We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Fix "complex_logic" issue in website/events/services.py
Consider simplifying this complex logical expression.

https://codeclimate.com/github/svthalia/concrexit/website/events/services.py#issue_5ece61c6b391e1000100034b

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `website/events/services.py`
Content:
```
1 from collections import OrderedDict
2 
3 from django.utils import timezone
4 from django.utils.datetime_safe import date
5 from django.utils.translation import gettext_lazy as _, get_language
6 
7 from events import emails
8 from events.exceptions import RegistrationError
9 from events.models import EventRegistration, RegistrationInformationField, Event
10 from payments.models import Payment
11 from payments.services import create_payment, delete_payment
12 from utils.snippets import datetime_to_lectureyear
13 
14 
15 def is_user_registered(member, event):
16     """
17     Returns if the user is registered for the specified event
18 
19     :param member: the user
20     :param event: the event
21     :return: None if registration is not required or no member else True/False
22     """
23     if not event.registration_required or not member.is_authenticated:
24         return None
25 
26     return event.registrations.filter(member=member, date_cancelled=None).count() > 0
27 
28 
29 def event_permissions(member, event, name=None):
30     """
31     Returns a dictionary with the available event permissions of the user
32 
33     :param member: the user
34     :param event: the event
35     :param name: the name of a non member registration
36     :return: the permission dictionary
37     """
38     perms = {
39         "create_registration": False,
40         "cancel_registration": False,
41         "update_registration": False,
42     }
43     if member and member.is_authenticated or name:
44         registration = None
45         try:
46             registration = EventRegistration.objects.get(
47                 event=event, member=member, name=name
48             )
49         except EventRegistration.DoesNotExist:
50             pass
51 
52         perms["create_registration"] = (
53             (registration is None or registration.date_cancelled is not None)
54             and event.registration_allowed
55             and (name or member.can_attend_events)
56         )
57         perms["cancel_registration"] = (
58             registration is not None
59             and registration.date_cancelled is None
60             and (event.cancellation_allowed or name)
61         )
62         perms["update_registration"] = (
63             registration is not None
64             and registration.date_cancelled is None
65             and event.has_fields()
66             and event.registration_allowed
67             and (name or member.can_attend_events)
68         )
69 
70     return perms
71 
72 
73 def is_organiser(member, event):
74     if member and member.is_authenticated:
75         if member.is_superuser or member.has_perm("events.override_organiser"):
76             return True
77 
78         if event:
79             return member.get_member_groups().filter(pk=event.organiser.pk).count() != 0
80 
81     return False
82 
83 
84 def create_registration(member, event):
85     """
86     Creates a new user registration for an event
87 
88     :param member: the user
89     :param event: the event
90     :return: returns the registration if successful
91     """
92     if event_permissions(member, event)["create_registration"]:
93         registration = None
94         try:
95             registration = EventRegistration.objects.get(event=event, member=member)
96         except EventRegistration.DoesNotExist:
97             pass
98 
99         if registration is None:
100             return EventRegistration.objects.create(event=event, member=member)
101         elif registration.date_cancelled is not None:
102             if registration.is_late_cancellation():
103                 raise RegistrationError(
104                     _(
105                         "You cannot re-register anymore "
106                         "since you've cancelled after the "
107                         "deadline."
108                     )
109                 )
110             else:
111                 registration.date = timezone.now()
112                 registration.date_cancelled = None
113                 registration.save()
114 
115         return registration
116     elif event_permissions(member, event)["cancel_registration"]:
117         raise RegistrationError(_("You were already registered."))
118     else:
119         raise RegistrationError(_("You may not register."))
120 
121 
122 def cancel_registration(member, event):
123     """
124     Cancel a user registration for an event
125 
126     :param member: the user
127     :param event: the event
128     """
129     registration = None
130     try:
131         registration = EventRegistration.objects.get(event=event, member=member)
132     except EventRegistration.DoesNotExist:
133         pass
134 
135     if event_permissions(member, event)["cancel_registration"] and registration:
136         if registration.payment is not None:
137             p = registration.payment
138             registration.payment = None
139             registration.save()
140             p.delete()
141         if registration.queue_position == 0:
142             emails.notify_first_waiting(event)
143 
144             if event.send_cancel_email and event.after_cancel_deadline:
145                 emails.notify_organiser(event, registration)
146 
147         # Note that this doesn"t remove the values for the
148         # information fields that the user entered upon registering.
149         # But this is regarded as a feature, not a bug. Especially
150         # since the values will still appear in the backend.
151         registration.date_cancelled = timezone.now()
152         registration.save()
153     else:
154         raise RegistrationError(_("You are not registered for this event."))
155 
156 
157 def pay_with_tpay(member, event):
158     """
159     Add a Thalia Pay payment to an event registration
160 
161     :param member: the user
162     :param event: the event
163     """
164     try:
165         registration = EventRegistration.objects.get(event=event, member=member)
166     except EventRegistration.DoesNotExist:
167         raise RegistrationError(_("You are not registered for this event."))
168 
169     if registration.payment is None:
170         registration.payment = create_payment(
171             payable=registration, processed_by=member, pay_type=Payment.TPAY
172         )
173         registration.save()
174     else:
175         raise RegistrationError(_("You have already paid for this event."))
176 
177 
178 def update_registration(
179     member=None, event=None, name=None, registration=None, field_values=None
180 ):
181     """
182     Updates a user registration of an event
183 
184     :param request: http request
185     :param member: the user
186     :param event: the event
187     :param name: the name of a registration not associated with a user
188     :param registration: the registration
189     :param field_values: values for the information fields
190     """
191     if not registration:
192         try:
193             registration = EventRegistration.objects.get(
194                 event=event, member=member, name=name
195             )
196         except EventRegistration.DoesNotExist as error:
197             raise RegistrationError(
198                 _("You are not registered for this event.")
199             ) from error
200     else:
201         member = registration.member
202         event = registration.event
203         name = registration.name
204 
205     if (
206         not event_permissions(member, event, name)["update_registration"]
207         or not field_values
208     ):
209         return
210 
211     for field_id, field_value in field_values:
212         field = RegistrationInformationField.objects.get(
213             id=field_id.replace("info_field_", "")
214         )
215 
216         if (
217             field.type == RegistrationInformationField.INTEGER_FIELD
218             and field_value is None
219         ):
220             field_value = 0
221         elif (
222             field.type == RegistrationInformationField.BOOLEAN_FIELD
223             and field_value is None
224         ):
225             field_value = False
226         elif (
227             field.type == RegistrationInformationField.TEXT_FIELD
228             and field_value is None
229         ):
230             field_value = ""
231 
232         field.set_value_for(registration, field_value)
233 
234 
235 def registration_fields(request, member=None, event=None, registration=None, name=None):
236     """
237     Returns information about the registration fields of a registration
238 
239     :param member: the user (optional if registration provided)
240     :param name: the name of a non member registration
241                  (optional if registration provided)
242     :param event: the event (optional if registration provided)
243     :param registration: the registration (optional if member & event provided)
244     :return: the fields
245     """
246 
247     if registration is None:
248         try:
249             registration = EventRegistration.objects.get(
250                 event=event, member=member, name=name
251             )
252         except EventRegistration.DoesNotExist as error:
253             raise RegistrationError(
254                 _("You are not registered for this event.")
255             ) from error
256         except EventRegistration.MultipleObjectsReturned as error:
257             raise RegistrationError(
258                 _("Unable to find the right registration.")
259             ) from error
260     else:
261         member = registration.member
262         event = registration.event
263         name = registration.name
264 
265     perms = event_permissions(member, event, name)[
266         "update_registration"
267     ] or is_organiser(request.member, event)
268     if perms and registration:
269         information_fields = registration.information_fields
270         fields = OrderedDict()
271 
272         for information_field in information_fields:
273             field = information_field["field"]
274 
275             fields["info_field_{}".format(field.id)] = {
276                 "type": field.type,
277                 "label": getattr(field, "{}_{}".format("name", get_language())),
278                 "description": getattr(
279                     field, "{}_{}".format("description", get_language())
280                 ),
281                 "value": information_field["value"],
282                 "required": field.required,
283             }
284 
285         return fields
286     else:
287         raise RegistrationError(_("You are not allowed to update this registration."))
288 
289 
290 def update_registration_by_organiser(registration, member, data):
291     if not is_organiser(member, registration.event):
292         raise RegistrationError(_("You are not allowed to update this registration."))
293 
294     if "payment" in data:
295         if data["payment"]["type"] == Payment.NONE and registration.payment is not None:
296             delete_payment(registration)
297         else:
298             registration.payment = create_payment(
299                 payable=registration,
300                 processed_by=member,
301                 pay_type=data["payment"]["type"],
302             )
303 
304     if "present" in data:
305         registration.present = data["present"]
306 
307     registration.save()
308 
309 
310 def generate_category_statistics():
311     """
312     Generate statistics about events, number of events per category
313     :return: Dict with key, value resp. being category, event count.
314     """
315     year = datetime_to_lectureyear(timezone.now())
316 
317     data = {}
318     for i in range(5):
319         year_start = date(year=year - i, month=9, day=1)
320         year_end = date(year=year - i + 1, month=9, day=1)
321         data[str(year - i)] = {
322             str(display): Event.objects.filter(
323                 category=key, start__gte=year_start, end__lte=year_end
324             ).count()
325             for key, display in Event.EVENT_CATEGORIES
326         }
327 
328     return data
329
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/website/events/services.py b/website/events/services.py
--- a/website/events/services.py
+++ b/website/events/services.py
@@ -40,33 +40,36 @@
         "cancel_registration": False,
         "update_registration": False,
     }
-    if member and member.is_authenticated or name:
-        registration = None
-        try:
-            registration = EventRegistration.objects.get(
-                event=event, member=member, name=name
-            )
-        except EventRegistration.DoesNotExist:
-            pass
+    if not member:
+        return perms
+    if not (member.is_authenticated or name):
+        return perms
 
-        perms["create_registration"] = (
-            (registration is None or registration.date_cancelled is not None)
-            and event.registration_allowed
-            and (name or member.can_attend_events)
-        )
-        perms["cancel_registration"] = (
-            registration is not None
-            and registration.date_cancelled is None
-            and (event.cancellation_allowed or name)
-        )
-        perms["update_registration"] = (
-            registration is not None
-            and registration.date_cancelled is None
-            and event.has_fields()
-            and event.registration_allowed
-            and (name or member.can_attend_events)
+    registration = None
+    try:
+        registration = EventRegistration.objects.get(
+            event=event, member=member, name=name
         )
+    except EventRegistration.DoesNotExist:
+        pass
 
+    perms["create_registration"] = (
+        (registration is None or registration.date_cancelled is not None)
+        and event.registration_allowed
+        and (name or member.can_attend_events)
+    )
+    perms["cancel_registration"] = (
+        registration is not None
+        and registration.date_cancelled is None
+        and (event.cancellation_allowed or name)
+    )
+    perms["update_registration"] = (
+        registration is not None
+        and registration.date_cancelled is None
+        and event.has_fields()
+        and event.registration_allowed
+        and (name or member.can_attend_events)
+    )
     return perms

{"golden_diff": "diff --git a/website/events/services.py b/website/events/services.py\n--- a/website/events/services.py\n+++ b/website/events/services.py\n@@ -40,33 +40,36 @@\n         \"cancel_registration\": False,\n         \"update_registration\": False,\n     }\n-    if member and member.is_authenticated or name:\n-        registration = None\n-        try:\n-            registration = EventRegistration.objects.get(\n-                event=event, member=member, name=name\n-            )\n-        except EventRegistration.DoesNotExist:\n-            pass\n+    if not member:\n+        return perms\n+    if not (member.is_authenticated or name):\n+        return perms\n \n-        perms[\"create_registration\"] = (\n-            (registration is None or registration.date_cancelled is not None)\n-            and event.registration_allowed\n-            and (name or member.can_attend_events)\n-        )\n-        perms[\"cancel_registration\"] = (\n-            registration is not None\n-            and registration.date_cancelled is None\n-            and (event.cancellation_allowed or name)\n-        )\n-        perms[\"update_registration\"] = (\n-            registration is not None\n-            and registration.date_cancelled is None\n-            and event.has_fields()\n-            and event.registration_allowed\n-            and (name or member.can_attend_events)\n+    registration = None\n+    try:\n+        registration = EventRegistration.objects.get(\n+            event=event, member=member, name=name\n         )\n+    except EventRegistration.DoesNotExist:\n+        pass\n \n+    perms[\"create_registration\"] = (\n+        (registration is None or registration.date_cancelled is not None)\n+        and event.registration_allowed\n+        and (name or member.can_attend_events)\n+    )\n+    perms[\"cancel_registration\"] = (\n+        registration is not None\n+        and registration.date_cancelled is None\n+        and (event.cancellation_allowed or name)\n+    )\n+    perms[\"update_registration\"] = (\n+        registration is not None\n+        and registration.date_cancelled is None\n+        and event.has_fields()\n+        and event.registration_allowed\n+        and (name or member.can_attend_events)\n+    )\n     return perms\n", "issue": "Fix \"complex_logic\" issue in website/events/services.py\nConsider simplifying this complex logical expression.\n\nhttps://codeclimate.com/github/svthalia/concrexit/website/events/services.py#issue_5ece61c6b391e1000100034b\n", "before_files": [{"content": "from collections import OrderedDict\n\nfrom django.utils import timezone\nfrom django.utils.datetime_safe import date\nfrom django.utils.translation import gettext_lazy as _, get_language\n\nfrom events import emails\nfrom events.exceptions import RegistrationError\nfrom events.models import EventRegistration, RegistrationInformationField, Event\nfrom payments.models import Payment\nfrom payments.services import create_payment, delete_payment\nfrom utils.snippets import datetime_to_lectureyear\n\n\ndef is_user_registered(member, event):\n    \"\"\"\n    Returns if the user is registered for the specified event\n\n    :param member: the user\n    :param event: the event\n    :return: None if registration is not required or no member else True/False\n    \"\"\"\n    if not event.registration_required or not member.is_authenticated:\n        return None\n\n    return event.registrations.filter(member=member, date_cancelled=None).count() > 0\n\n\ndef event_permissions(member, event, name=None):\n    \"\"\"\n    Returns a dictionary with the available event permissions of the user\n\n    :param member: the user\n    :param event: the event\n    :param name: the name of a non member registration\n    :return: the permission dictionary\n    \"\"\"\n    perms = {\n        \"create_registration\": False,\n        \"cancel_registration\": False,\n        \"update_registration\": False,\n    }\n    if member and member.is_authenticated or name:\n        registration = None\n        try:\n            registration = EventRegistration.objects.get(\n                event=event, member=member, name=name\n            )\n        except EventRegistration.DoesNotExist:\n            pass\n\n        perms[\"create_registration\"] = (\n            (registration is None or registration.date_cancelled is not None)\n            and event.registration_allowed\n            and (name or member.can_attend_events)\n        )\n        perms[\"cancel_registration\"] = (\n            registration is not None\n            and registration.date_cancelled is None\n            and (event.cancellation_allowed or name)\n        )\n        perms[\"update_registration\"] = (\n            registration is not None\n            and registration.date_cancelled is None\n            and event.has_fields()\n            and event.registration_allowed\n            and (name or member.can_attend_events)\n        )\n\n    return perms\n\n\ndef is_organiser(member, event):\n    if member and member.is_authenticated:\n        if member.is_superuser or member.has_perm(\"events.override_organiser\"):\n            return True\n\n        if event:\n            return member.get_member_groups().filter(pk=event.organiser.pk).count() != 0\n\n    return False\n\n\ndef create_registration(member, event):\n    \"\"\"\n    Creates a new user registration for an event\n\n    :param member: the user\n    :param event: the event\n    :return: returns the registration if successful\n    \"\"\"\n    if event_permissions(member, event)[\"create_registration\"]:\n        registration = None\n        try:\n            registration = EventRegistration.objects.get(event=event, member=member)\n        except EventRegistration.DoesNotExist:\n            pass\n\n        if registration is None:\n            return EventRegistration.objects.create(event=event, member=member)\n        elif registration.date_cancelled is not None:\n            if registration.is_late_cancellation():\n                raise RegistrationError(\n                    _(\n                        \"You cannot re-register anymore \"\n                        \"since you've cancelled after the \"\n                        \"deadline.\"\n                    )\n                )\n            else:\n                registration.date = timezone.now()\n                registration.date_cancelled = None\n                registration.save()\n\n        return registration\n    elif event_permissions(member, event)[\"cancel_registration\"]:\n        raise RegistrationError(_(\"You were already registered.\"))\n    else:\n        raise RegistrationError(_(\"You may not register.\"))\n\n\ndef cancel_registration(member, event):\n    \"\"\"\n    Cancel a user registration for an event\n\n    :param member: the user\n    :param event: the event\n    \"\"\"\n    registration = None\n    try:\n        registration = EventRegistration.objects.get(event=event, member=member)\n    except EventRegistration.DoesNotExist:\n        pass\n\n    if event_permissions(member, event)[\"cancel_registration\"] and registration:\n        if registration.payment is not None:\n            p = registration.payment\n            registration.payment = None\n            registration.save()\n            p.delete()\n        if registration.queue_position == 0:\n            emails.notify_first_waiting(event)\n\n            if event.send_cancel_email and event.after_cancel_deadline:\n                emails.notify_organiser(event, registration)\n\n        # Note that this doesn\"t remove the values for the\n        # information fields that the user entered upon registering.\n        # But this is regarded as a feature, not a bug. Especially\n        # since the values will still appear in the backend.\n        registration.date_cancelled = timezone.now()\n        registration.save()\n    else:\n        raise RegistrationError(_(\"You are not registered for this event.\"))\n\n\ndef pay_with_tpay(member, event):\n    \"\"\"\n    Add a Thalia Pay payment to an event registration\n\n    :param member: the user\n    :param event: the event\n    \"\"\"\n    try:\n        registration = EventRegistration.objects.get(event=event, member=member)\n    except EventRegistration.DoesNotExist:\n        raise RegistrationError(_(\"You are not registered for this event.\"))\n\n    if registration.payment is None:\n        registration.payment = create_payment(\n            payable=registration, processed_by=member, pay_type=Payment.TPAY\n        )\n        registration.save()\n    else:\n        raise RegistrationError(_(\"You have already paid for this event.\"))\n\n\ndef update_registration(\n    member=None, event=None, name=None, registration=None, field_values=None\n):\n    \"\"\"\n    Updates a user registration of an event\n\n    :param request: http request\n    :param member: the user\n    :param event: the event\n    :param name: the name of a registration not associated with a user\n    :param registration: the registration\n    :param field_values: values for the information fields\n    \"\"\"\n    if not registration:\n        try:\n            registration = EventRegistration.objects.get(\n                event=event, member=member, name=name\n            )\n        except EventRegistration.DoesNotExist as error:\n            raise RegistrationError(\n                _(\"You are not registered for this event.\")\n            ) from error\n    else:\n        member = registration.member\n        event = registration.event\n        name = registration.name\n\n    if (\n        not event_permissions(member, event, name)[\"update_registration\"]\n        or not field_values\n    ):\n        return\n\n    for field_id, field_value in field_values:\n        field = RegistrationInformationField.objects.get(\n            id=field_id.replace(\"info_field_\", \"\")\n        )\n\n        if (\n            field.type == RegistrationInformationField.INTEGER_FIELD\n            and field_value is None\n        ):\n            field_value = 0\n        elif (\n            field.type == RegistrationInformationField.BOOLEAN_FIELD\n            and field_value is None\n        ):\n            field_value = False\n        elif (\n            field.type == RegistrationInformationField.TEXT_FIELD\n            and field_value is None\n        ):\n            field_value = \"\"\n\n        field.set_value_for(registration, field_value)\n\n\ndef registration_fields(request, member=None, event=None, registration=None, name=None):\n    \"\"\"\n    Returns information about the registration fields of a registration\n\n    :param member: the user (optional if registration provided)\n    :param name: the name of a non member registration\n                 (optional if registration provided)\n    :param event: the event (optional if registration provided)\n    :param registration: the registration (optional if member & event provided)\n    :return: the fields\n    \"\"\"\n\n    if registration is None:\n        try:\n            registration = EventRegistration.objects.get(\n                event=event, member=member, name=name\n            )\n        except EventRegistration.DoesNotExist as error:\n            raise RegistrationError(\n                _(\"You are not registered for this event.\")\n            ) from error\n        except EventRegistration.MultipleObjectsReturned as error:\n            raise RegistrationError(\n                _(\"Unable to find the right registration.\")\n            ) from error\n    else:\n        member = registration.member\n        event = registration.event\n        name = registration.name\n\n    perms = event_permissions(member, event, name)[\n        \"update_registration\"\n    ] or is_organiser(request.member, event)\n    if perms and registration:\n        information_fields = registration.information_fields\n        fields = OrderedDict()\n\n        for information_field in information_fields:\n            field = information_field[\"field\"]\n\n            fields[\"info_field_{}\".format(field.id)] = {\n                \"type\": field.type,\n                \"label\": getattr(field, \"{}_{}\".format(\"name\", get_language())),\n                \"description\": getattr(\n                    field, \"{}_{}\".format(\"description\", get_language())\n                ),\n                \"value\": information_field[\"value\"],\n                \"required\": field.required,\n            }\n\n        return fields\n    else:\n        raise RegistrationError(_(\"You are not allowed to update this registration.\"))\n\n\ndef update_registration_by_organiser(registration, member, data):\n    if not is_organiser(member, registration.event):\n        raise RegistrationError(_(\"You are not allowed to update this registration.\"))\n\n    if \"payment\" in data:\n        if data[\"payment\"][\"type\"] == Payment.NONE and registration.payment is not None:\n            delete_payment(registration)\n        else:\n            registration.payment = create_payment(\n                payable=registration,\n                processed_by=member,\n                pay_type=data[\"payment\"][\"type\"],\n            )\n\n    if \"present\" in data:\n        registration.present = data[\"present\"]\n\n    registration.save()\n\n\ndef generate_category_statistics():\n    \"\"\"\n    Generate statistics about events, number of events per category\n    :return: Dict with key, value resp. being category, event count.\n    \"\"\"\n    year = datetime_to_lectureyear(timezone.now())\n\n    data = {}\n    for i in range(5):\n        year_start = date(year=year - i, month=9, day=1)\n        year_end = date(year=year - i + 1, month=9, day=1)\n        data[str(year - i)] = {\n            str(display): Event.objects.filter(\n                category=key, start__gte=year_start, end__lte=year_end\n            ).count()\n            for key, display in Event.EVENT_CATEGORIES\n        }\n\n    return data\n", "path": "website/events/services.py"}], "after_files": [{"content": "from collections import OrderedDict\n\nfrom django.utils import timezone\nfrom django.utils.datetime_safe import date\nfrom django.utils.translation import gettext_lazy as _, get_language\n\nfrom events import emails\nfrom events.exceptions import RegistrationError\nfrom events.models import EventRegistration, RegistrationInformationField, Event\nfrom payments.models import Payment\nfrom payments.services import create_payment, delete_payment\nfrom utils.snippets import datetime_to_lectureyear\n\n\ndef is_user_registered(member, event):\n    \"\"\"\n    Returns if the user is registered for the specified event\n\n    :param member: the user\n    :param event: the event\n    :return: None if registration is not required or no member else True/False\n    \"\"\"\n    if not event.registration_required or not member.is_authenticated:\n        return None\n\n    return event.registrations.filter(member=member, date_cancelled=None).count() > 0\n\n\ndef event_permissions(member, event, name=None):\n    \"\"\"\n    Returns a dictionary with the available event permissions of the user\n\n    :param member: the user\n    :param event: the event\n    :param name: the name of a non member registration\n    :return: the permission dictionary\n    \"\"\"\n    perms = {\n        \"create_registration\": False,\n        \"cancel_registration\": False,\n        \"update_registration\": False,\n    }\n    if not member:\n        return perms\n    if not (member.is_authenticated or name):\n        return perms\n\n    registration = None\n    try:\n        registration = EventRegistration.objects.get(\n            event=event, member=member, name=name\n        )\n    except EventRegistration.DoesNotExist:\n        pass\n\n    perms[\"create_registration\"] = (\n        (registration is None or registration.date_cancelled is not None)\n        and event.registration_allowed\n        and (name or member.can_attend_events)\n    )\n    perms[\"cancel_registration\"] = (\n        registration is not None\n        and registration.date_cancelled is None\n        and (event.cancellation_allowed or name)\n    )\n    perms[\"update_registration\"] = (\n        registration is not None\n        and registration.date_cancelled is None\n        and event.has_fields()\n        and event.registration_allowed\n        and (name or member.can_attend_events)\n    )\n    return perms\n\n\ndef is_organiser(member, event):\n    if member and member.is_authenticated:\n        if member.is_superuser or member.has_perm(\"events.override_organiser\"):\n            return True\n\n        if event:\n            return member.get_member_groups().filter(pk=event.organiser.pk).count() != 0\n\n    return False\n\n\ndef create_registration(member, event):\n    \"\"\"\n    Creates a new user registration for an event\n\n    :param member: the user\n    :param event: the event\n    :return: returns the registration if successful\n    \"\"\"\n    if event_permissions(member, event)[\"create_registration\"]:\n        registration = None\n        try:\n            registration = EventRegistration.objects.get(event=event, member=member)\n        except EventRegistration.DoesNotExist:\n            pass\n\n        if registration is None:\n            return EventRegistration.objects.create(event=event, member=member)\n        elif registration.date_cancelled is not None:\n            if registration.is_late_cancellation():\n                raise RegistrationError(\n                    _(\n                        \"You cannot re-register anymore \"\n                        \"since you've cancelled after the \"\n                        \"deadline.\"\n                    )\n                )\n            else:\n                registration.date = timezone.now()\n                registration.date_cancelled = None\n                registration.save()\n\n        return registration\n    elif event_permissions(member, event)[\"cancel_registration\"]:\n        raise RegistrationError(_(\"You were already registered.\"))\n    else:\n        raise RegistrationError(_(\"You may not register.\"))\n\n\ndef cancel_registration(member, event):\n    \"\"\"\n    Cancel a user registration for an event\n\n    :param member: the user\n    :param event: the event\n    \"\"\"\n    registration = None\n    try:\n        registration = EventRegistration.objects.get(event=event, member=member)\n    except EventRegistration.DoesNotExist:\n        pass\n\n    if event_permissions(member, event)[\"cancel_registration\"] and registration:\n        if registration.payment is not None:\n            p = registration.payment\n            registration.payment = None\n            registration.save()\n            p.delete()\n        if registration.queue_position == 0:\n            emails.notify_first_waiting(event)\n\n            if event.send_cancel_email and event.after_cancel_deadline:\n                emails.notify_organiser(event, registration)\n\n        # Note that this doesn\"t remove the values for the\n        # information fields that the user entered upon registering.\n        # But this is regarded as a feature, not a bug. Especially\n        # since the values will still appear in the backend.\n        registration.date_cancelled = timezone.now()\n        registration.save()\n    else:\n        raise RegistrationError(_(\"You are not registered for this event.\"))\n\n\ndef pay_with_tpay(member, event):\n    \"\"\"\n    Add a Thalia Pay payment to an event registration\n\n    :param member: the user\n    :param event: the event\n    \"\"\"\n    try:\n        registration = EventRegistration.objects.get(event=event, member=member)\n    except EventRegistration.DoesNotExist:\n        raise RegistrationError(_(\"You are not registered for this event.\"))\n\n    if registration.payment is None:\n        registration.payment = create_payment(\n            payable=registration, processed_by=member, pay_type=Payment.TPAY\n        )\n        registration.save()\n    else:\n        raise RegistrationError(_(\"You have already paid for this event.\"))\n\n\ndef update_registration(\n    member=None, event=None, name=None, registration=None, field_values=None\n):\n    \"\"\"\n    Updates a user registration of an event\n\n    :param request: http request\n    :param member: the user\n    :param event: the event\n    :param name: the name of a registration not associated with a user\n    :param registration: the registration\n    :param field_values: values for the information fields\n    \"\"\"\n    if not registration:\n        try:\n            registration = EventRegistration.objects.get(\n                event=event, member=member, name=name\n            )\n        except EventRegistration.DoesNotExist as error:\n            raise RegistrationError(\n                _(\"You are not registered for this event.\")\n            ) from error\n    else:\n        member = registration.member\n        event = registration.event\n        name = registration.name\n\n    if (\n        not event_permissions(member, event, name)[\"update_registration\"]\n        or not field_values\n    ):\n        return\n\n    for field_id, field_value in field_values:\n        field = RegistrationInformationField.objects.get(\n            id=field_id.replace(\"info_field_\", \"\")\n        )\n\n        if (\n            field.type == RegistrationInformationField.INTEGER_FIELD\n            and field_value is None\n        ):\n            field_value = 0\n        elif (\n            field.type == RegistrationInformationField.BOOLEAN_FIELD\n            and field_value is None\n        ):\n            field_value = False\n        elif (\n            field.type == RegistrationInformationField.TEXT_FIELD\n            and field_value is None\n        ):\n            field_value = \"\"\n\n        field.set_value_for(registration, field_value)\n\n\ndef registration_fields(request, member=None, event=None, registration=None, name=None):\n    \"\"\"\n    Returns information about the registration fields of a registration\n\n    :param member: the user (optional if registration provided)\n    :param name: the name of a non member registration\n                 (optional if registration provided)\n    :param event: the event (optional if registration provided)\n    :param registration: the registration (optional if member & event provided)\n    :return: the fields\n    \"\"\"\n\n    if registration is None:\n        try:\n            registration = EventRegistration.objects.get(\n                event=event, member=member, name=name\n            )\n        except EventRegistration.DoesNotExist as error:\n            raise RegistrationError(\n                _(\"You are not registered for this event.\")\n            ) from error\n        except EventRegistration.MultipleObjectsReturned as error:\n            raise RegistrationError(\n                _(\"Unable to find the right registration.\")\n            ) from error\n    else:\n        member = registration.member\n        event = registration.event\n        name = registration.name\n\n    perms = event_permissions(member, event, name)[\n        \"update_registration\"\n    ] or is_organiser(request.member, event)\n    if perms and registration:\n        information_fields = registration.information_fields\n        fields = OrderedDict()\n\n        for information_field in information_fields:\n            field = information_field[\"field\"]\n\n            fields[\"info_field_{}\".format(field.id)] = {\n                \"type\": field.type,\n                \"label\": getattr(field, \"{}_{}\".format(\"name\", get_language())),\n                \"description\": getattr(\n                    field, \"{}_{}\".format(\"description\", get_language())\n                ),\n                \"value\": information_field[\"value\"],\n                \"required\": field.required,\n            }\n\n        return fields\n    else:\n        raise RegistrationError(_(\"You are not allowed to update this registration.\"))\n\n\ndef update_registration_by_organiser(registration, member, data):\n    if not is_organiser(member, registration.event):\n        raise RegistrationError(_(\"You are not allowed to update this registration.\"))\n\n    if \"payment\" in data:\n        if data[\"payment\"][\"type\"] == Payment.NONE and registration.payment is not None:\n            delete_payment(registration)\n        else:\n            registration.payment = create_payment(\n                payable=registration,\n                processed_by=member,\n                pay_type=data[\"payment\"][\"type\"],\n            )\n\n    if \"present\" in data:\n        registration.present = data[\"present\"]\n\n    registration.save()\n\n\ndef generate_category_statistics():\n    \"\"\"\n    Generate statistics about events, number of events per category\n    :return: Dict with key, value resp. being category, event count.\n    \"\"\"\n    year = datetime_to_lectureyear(timezone.now())\n\n    data = {}\n    for i in range(5):\n        year_start = date(year=year - i, month=9, day=1)\n        year_end = date(year=year - i + 1, month=9, day=1)\n        data[str(year - i)] = {\n            str(display): Event.objects.filter(\n                category=key, start__gte=year_start, end__lte=year_end\n            ).count()\n            for key, display in Event.EVENT_CATEGORIES\n        }\n\n    return data\n", "path": "website/events/services.py"}]}