internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: svthalia/concrexit

Issue:
Add cancelled registrations to event in api v2
### Is your feature request related to a problem? Please describe.
API v2 doesn't return a cancelled registration when you've cancelled a registration (in the event serializer). So we cannot display stuff like 'Your registration is cancelled (after the deadline)'.

### Describe the solution you'd like
Also return a registration if it's cancelled, and include fields like is_cancelled, is_late_cancellation, etc.

### Motivation
This makes it possible to show nice status texts like in the old app and the website.

### Describe alternatives you've considered
Leaving out the messages for cancelled registrations. In that case, you can only see that there is no register button, but not why.



Discussion:

Resolving patch:
diff --git a/website/events/api/v2/serializers/event.py b/website/events/api/v2/serializers/event.py
--- a/website/events/api/v2/serializers/event.py
+++ b/website/events/api/v2/serializers/event.py
@@ -58,12 +58,20 @@ def _user_registration(self, instance):
         try:
             if self.context["request"].member:
                 reg = instance.eventregistration_set.get(
-                    member=self.context["request"].member, date_cancelled=None
+                    member=self.context["request"].member
                 )
                 return EventRegistrationSerializer(
                     reg,
                     context=self.context,
-                    fields=("pk", "present", "queue_position", "date", "payment"),
+                    fields=(
+                        "pk",
+                        "present",
+                        "queue_position",
+                        "is_cancelled",
+                        "is_late_cancellation",
+                        "date",
+                        "payment",
+                    ),
                 ).data
         except EventRegistration.DoesNotExist:
             pass
diff --git a/website/events/api/v2/serializers/event_registration.py b/website/events/api/v2/serializers/event_registration.py
--- a/website/events/api/v2/serializers/event_registration.py
+++ b/website/events/api/v2/serializers/event_registration.py
@@ -34,3 +34,16 @@ class Meta:
 
     payment = PaymentSerializer()
     member = MemberSerializer(detailed=False, read_only=True)
+    is_cancelled = serializers.SerializerMethodField("_is_cancelled")
+    is_late_cancellation = serializers.SerializerMethodField("_is_late_cancellation")
+    queue_position = serializers.SerializerMethodField("_queue_position")
+
+    def _is_late_cancellation(self, instance):
+        return instance.is_late_cancellation()
+
+    def _queue_position(self, instance):
+        pos = instance.queue_position
+        return pos if pos and pos > 0 else None
+
+    def _is_cancelled(self, instance):
+        return instance.date_cancelled is not None


Test patch:
Repository: svthalia/concrexit

Issue:
PaymentError: This payment has already been processed and hence cannot be deleted.
Sentry Issue: [CONCREXIT-8C](https://sentry.io/organizations/thalia/issues/2568657203/?referrer=github_integration)

```
PaymentError: This payment has already been processed and hence cannot be deleted.
(1 additional frame(s) were not displayed)
...
  File "django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "django/views/decorators/http.py", line 40, in inner
    return func(request, *args, **kwargs)
  File "pizzas/views.py", line 38, in cancel_order
    order.delete()
  File "pizzas/models.py", line 256, in delete
    delete_payment(self)
  File "payments/services.py", line 98, in delete_payment
    raise PaymentError(
```


Discussion:

Resolving patch:
diff --git a/website/pizzas/api/v2/views.py b/website/pizzas/api/v2/views.py
--- a/website/pizzas/api/v2/views.py
+++ b/website/pizzas/api/v2/views.py
@@ -102,22 +102,17 @@ def get_object(self):
 
     def dispatch(self, request, *args, **kwargs):
         self.food_event = get_object_or_404(FoodEvent, pk=self.kwargs.get("pk"))
-        return super().dispatch(request, *args, **kwargs)
+        try:
+            return super().dispatch(request, *args, **kwargs)
+        except PaymentError as e:
+            return Response(str(e), status=status.HTTP_403_FORBIDDEN,)
 
     def update(self, request, *args, **kwargs):
         super().update(request, *args, **kwargs)
         instance = self.get_object()
 
         if instance.payment:
-            try:
-                delete_payment(
-                    instance, member=request.member, ignore_change_window=True
-                )
-            except PaymentError:
-                return Response(
-                    "Your order could not be updated because it was already paid.",
-                    status=status.HTTP_403_FORBIDDEN,
-                )
+            delete_payment(instance, member=request.member, ignore_change_window=True)
 
         return Response(
             FoodOrderSerializer(instance, context=self.get_serializer_context()).data
diff --git a/website/pizzas/views.py b/website/pizzas/views.py
--- a/website/pizzas/views.py
+++ b/website/pizzas/views.py
@@ -35,8 +35,11 @@ def cancel_order(request):
             if not order.can_be_changed:
                 messages.error(request, _("You can no longer cancel."))
             elif order.member == request.member:
-                order.delete()
-                messages.success(request, _("Your order has been cancelled."))
+                try:
+                    order.delete()
+                    messages.success(request, _("Your order has been cancelled."))
+                except PaymentError as e:
+                    messages.error(request, str(e))
         except Http404:
             messages.error(request, _("Your order could not be found."))
     return redirect("pizzas:index")


Test patch:
Repository: svthalia/concrexit

Issue:
Use constants for accessing membership price settings
### Describe the change
Right now, the registrations app (models.py) accesses the price of certain memberships by string indexing. We should use constants for this.

### Motivation
Better code quality

### Current implementation
A mix of "year" and Entry.MEMBERSHIP_YEAR (idem study)

### Suggested implementation
Use the constant everywhere




Discussion:

Resolving patch:
diff --git a/website/registrations/models.py b/website/registrations/models.py
--- a/website/registrations/models.py
+++ b/website/registrations/models.py
@@ -71,8 +71,8 @@ class Entry(models.Model):
         verbose_name=_("contribution"),
         max_digits=5,
         decimal_places=2,
-        validators=[MinValueValidator(settings.MEMBERSHIP_PRICES["year"])],
-        default=settings.MEMBERSHIP_PRICES["year"],
+        validators=[MinValueValidator(settings.MEMBERSHIP_PRICES[MEMBERSHIP_YEAR])],
+        default=settings.MEMBERSHIP_PRICES[MEMBERSHIP_YEAR],
         blank=False,
         null=False,
     )
@@ -130,8 +130,8 @@ def save(
         else:
             if self.membership_upgrade_discount_applies:
                 self.contribution = (
-                    settings.MEMBERSHIP_PRICES["study"]
-                    - settings.MEMBERSHIP_PRICES["year"]
+                    settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_STUDY]
+                    - settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_YEAR]
                 )
             else:
                 self.contribution = settings.MEMBERSHIP_PRICES[self.length]


Test patch:
Repository: svthalia/concrexit

Issue:
Disabling optional registrations does not work
### Describe the bug
I tried to disable optional registrations for an event, but somehow it didn’t work out

### How to reproduce
Have an event. 
Do not check ‘optional registrations allowed’
Profit

### Expected behaviour
Speaks for itself 

### Screenshots

### Additional context



Discussion:
This bug report really needs some more context. What event was it? Were registrations for that event enabled? Were the registrations already open?

I tried to reproduce the steps in this issue using https://staging.thalia.nu/admin/events/event/49/change/ and the only thing I found is that the checkbox was enabled for the event that had registrations enabled. So after disabling I couldnt enable the option anymore.
Have tried this again and really cannot reproduce.
Okay I just found that gmail decided to spam all GitHub notifications so I have some discussions to catch up :)

I experienced this problem with the orientation barbecue event that was cancelled. I was able to reproduce it right now with https://staging.thalia.nu/events/153/ and https://staging.thalia.nu/events/154/. Note that https://staging.thalia.nu/admin/events/event/153/change/ and https://staging.thalia.nu/admin/events/event/154/change/ show that optional registration is **not** enabled though the front end allows registration...
Not sure if relevant, but the `registration_start` `registration_end` `registration_cancel` and `max_participants` fields are all unset
Looks like we forgot to check if `optional_registrations` is actually enabled

https://github.com/svthalia/concrexit/blob/48933f4517073e126c7e5aa5640e5f132629a899/website/events/models/event.py#L275-#L277

Resolving patch:
diff --git a/website/events/models/event.py b/website/events/models/event.py
--- a/website/events/models/event.py
+++ b/website/events/models/event.py
@@ -274,7 +274,11 @@ def cancellation_allowed(self):
 
     @property
     def optional_registration_allowed(self):
-        return not self.registration_required and self.end >= timezone.now()
+        return (
+            self.optional_registrations
+            and not self.registration_required
+            and self.end >= timezone.now()
+        )
 
     @property
     def has_food_event(self):


Test patch:
Repository: svthalia/concrexit

Issue:
ImproperlyConfigured: Field name `language` is not valid for model `Profile`.
Sentry Issue: [CONCREXIT-8J](https://sentry.io/organizations/thalia/issues/2580014551/?referrer=github_integration)

```
ImproperlyConfigured: Field name `language` is not valid for model `Profile`.
(14 additional frame(s) were not displayed)
...
  File "django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "rest_framework/serializers.py", line 349, in fields
    for key, value in self.get_fields().items():
  File "rest_framework/serializers.py", line 1053, in get_fields
    field_class, field_kwargs = self.build_field(
  File "rest_framework/serializers.py", line 1199, in build_field
    return self.build_unknown_field(field_name, model_class)
  File "rest_framework/serializers.py", line 1317, in build_unknown_field
    raise ImproperlyConfigured(
```


Discussion:

Resolving patch:
diff --git a/website/members/api/v1/serializers.py b/website/members/api/v1/serializers.py
--- a/website/members/api/v1/serializers.py
+++ b/website/members/api/v1/serializers.py
@@ -125,7 +125,6 @@ class Meta:
             "profile_description",
             "nickname",
             "display_name_preference",
-            "language",
             "receive_optin",
             "receive_newsletter",
             "receive_magazine",


Test patch:
Repository: svthalia/concrexit

Issue:
Catch ValueError when updating orders if order is paid
This error should be caught.

Sentry Issue: [CONCREXIT-6V](https://sentry.io/organizations/thalia/issues/2472850301/?referrer=github_integration)

```
ValueError: This order has already been paid for.
(12 additional frame(s) were not displayed)
...
  File "rest_framework/serializers.py", line 200, in save
    self.instance = self.update(self.instance, validated_data)
  File "sales/api/v2/admin/serializers/order.py", line 151, in update
    OrderItemSerializer(item, context={"order": instance}).update(
  File "sales/api/v2/admin/serializers/order.py", line 66, in update
    super().update(instance, validated_data)
  File "rest_framework/serializers.py", line 983, in update
    instance.save()
  File "sales/models/order.py", line 215, in save
    raise ValueError("This order has already been paid for.")
```


Discussion:

Resolving patch:
diff --git a/website/sales/api/v2/admin/serializers/order.py b/website/sales/api/v2/admin/serializers/order.py
--- a/website/sales/api/v2/admin/serializers/order.py
+++ b/website/sales/api/v2/admin/serializers/order.py
@@ -1,6 +1,7 @@
-from django.core.exceptions import ObjectDoesNotExist
+from django.core.exceptions import ObjectDoesNotExist, ValidationError
 from django.utils.encoding import smart_str
 from rest_framework import serializers
+from rest_framework.settings import api_settings
 
 from members.api.v2.serializers.member import MemberSerializer
 from payments.api.v2.serializers import PaymentSerializer
@@ -63,7 +64,10 @@ def update(self, instance, validated_data, **kwargs):
         order = self.context["order"]
         instance.order = order
         instance.total = None  # Always recalculate the total amount if updating using API (note the difference from the model that only recalculates if the total is None, to deal with historic data and allow for special discounts)
-        super().update(instance, validated_data)
+        try:
+            super().update(instance, validated_data)
+        except ValueError as e:
+            raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [e]})
         return instance
 
 


Test patch:
Repository: svthalia/concrexit

Issue:
make fixtures crashes on payment fixtures
### Describe the bug
Creating fixtures crashes on creating payment fixtures:

```bash
$ make fixtures
...
Creating a payment
Traceback (most recent call last):
  File "/home/joren/projects/concrexit/website/manage.py", line 19, in <module>
    execute_from_command_line(sys.argv)
  File "/home/joren/.cache/pypoetry/virtualenvs/concrexit-zE6WZ1Zu-py3.9/lib/python3.9/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
    utility.execute()
  File "/home/joren/.cache/pypoetry/virtualenvs/concrexit-zE6WZ1Zu-py3.9/lib/python3.9/site-packages/django/core/management/__init__.py", line 413, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/joren/.cache/pypoetry/virtualenvs/concrexit-zE6WZ1Zu-py3.9/lib/python3.9/site-packages/django/core/management/base.py", line 354, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/joren/.cache/pypoetry/virtualenvs/concrexit-zE6WZ1Zu-py3.9/lib/python3.9/site-packages/django/core/management/base.py", line 398, in execute
    output = self.handle(*args, **options)
  File "/home/joren/projects/concrexit/website/utils/management/commands/createfixtures.py", line 731, in handle
    self.create_payment()
  File "/home/joren/projects/concrexit/website/utils/management/commands/createfixtures.py", line 561, in create_payment
    create_payment(
  File "/home/joren/projects/concrexit/website/payments/services.py", line 45, in create_payment
    raise PaymentError(
payments.exceptions.PaymentError: User processing payment does not have the right permissions
make: *** [Makefile:55: fixtures] Error 1
```

### How to reproduce
Steps to reproduce the behaviour:
1. Remove your local database.
2. Run `make fixtures`




Discussion:

Resolving patch:
diff --git a/website/utils/management/commands/createfixtures.py b/website/utils/management/commands/createfixtures.py
--- a/website/utils/management/commands/createfixtures.py
+++ b/website/utils/management/commands/createfixtures.py
@@ -557,10 +557,17 @@ def create_payment(self):
 
         registration = event.registrations.order_by("?")[0]
 
-        processed_by = Member.objects.order_by("?")[0]
+        superusers = Member.objects.filter(is_superuser=True)
+        if not superusers:
+            print(
+                "There is no member which is also a superuser. Creating payments without this isn't possible!"
+            )
+            print("Please add an membership to the superuser.")
+            return
+
         create_payment(
             registration,
-            processed_by,
+            superusers[0],
             random.choice([Payment.CASH, Payment.CARD, Payment.WIRE]),
         )
 


Test patch:
Repository: svthalia/concrexit

Issue:
Annual documents does not show drop-down menu for year
### Describe the bug

When I try to add an annual document to the site, I am not able to select a year, the dropdown menu does not contain any entries. 

### Steps to reproduce

1. 


Discussion:
@SnevelRetlaw for the next time, please use the issue templates :)

Resolving patch:
diff --git a/website/documents/forms.py b/website/documents/forms.py
--- a/website/documents/forms.py
+++ b/website/documents/forms.py
@@ -64,6 +64,10 @@ def _year_choices():
             for year in range(current + 1, 1989, -1)
         ]
 
+    year = forms.TypedChoiceField(
+        coerce=int, choices=_year_choices.__func__, initial=_current_year.__func__
+    )
+
 
 class AssociationDocumentForm(forms.ModelForm):
     """Form that overrides the widgets for the files."""


Test patch:
Repository: svthalia/concrexit

Issue:
Inactive partner page is still visible
When a partner is not set to be active, the page can still be loaded, while it should give a 404. See for example: https://thalia.nu/career/partners/exellys/, can be viewed, but it cannot be found on the https://thalia.nu/career/ page.

### How to reproduce
Steps to reproduce the behaviour:
1. Go to specific partner settings and disable "Is active" checkbox
2. Go to partner page: the partner is not visible
3. Go to the specific partner page: the partner is visible

### Expected behaviour
The specific partner page should give a 404.



Discussion:
https://github.com/svthalia/concrexit/blob/master/website/partners/views.py#L26 needs filtering on is_active

Resolving patch:
diff --git a/website/partners/migrations/0020_auto_20211002_0002.py b/website/partners/migrations/0020_auto_20211002_0002.py
new file mode 100644
--- /dev/null
+++ b/website/partners/migrations/0020_auto_20211002_0002.py
@@ -0,0 +1,23 @@
+# Generated by Django 3.2.7 on 2021-10-01 22:02
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('partners', '0019_remove_multilang_field'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='partner',
+            name='slug',
+            field=models.SlugField(unique=True),
+        ),
+        migrations.AlterField(
+            model_name='vacancycategory',
+            name='slug',
+            field=models.SlugField(unique=True),
+        ),
+    ]
diff --git a/website/partners/models.py b/website/partners/models.py
--- a/website/partners/models.py
+++ b/website/partners/models.py
@@ -15,7 +15,7 @@ class Partner(models.Model):
     is_main_partner = models.BooleanField(default=False)
     is_local_partner = models.BooleanField(default=False)
     name = models.CharField(max_length=255)
-    slug = models.SlugField()
+    slug = models.SlugField(unique=True)
     link = models.CharField(max_length=255, blank=True, validators=[URLValidator()])
     company_profile = HTMLField(blank=True)
     logo = models.ImageField(upload_to="public/partners/logos/")
@@ -118,7 +118,7 @@ class VacancyCategory(models.Model):
     """Model describing vacancy categories."""
 
     name = models.CharField(max_length=30)
-    slug = models.SlugField()
+    slug = models.SlugField(unique=True)
 
     def __str__(self):
         """Return the category name."""
diff --git a/website/partners/views.py b/website/partners/views.py
--- a/website/partners/views.py
+++ b/website/partners/views.py
@@ -23,7 +23,7 @@ def index(request):
 
 def partner(request, slug):
     """View to show partner page."""
-    obj = get_object_or_404(Partner, slug=slug)
+    obj = get_object_or_404(Partner, slug=slug, is_active=True)
     context = {
         "partner": obj,
         "vacancies": Vacancy.objects.filter(partner=obj),


Test patch:
Repository: svthalia/concrexit

Issue:
Saving food event with non-member registrations crashes trying to send push notification

Sentry Issue: [CONCREXIT-8P](https://sentry.io/organizations/thalia/issues/2613494929/?referrer=github_integration)

```
NotNullViolation: null value in column "user_id" of relation "pushnotifications_message_users" violates not-null constraint
DETAIL:  Failing row contains (549181, 1156, null).

  File "django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)

IntegrityError: null value in column "user_id" of relation "pushnotifications_message_users" violates not-null constraint
DETAIL:  Failing row contains (549181, 1156, null).

(26 additional frame(s) were not displayed)
...
  File "django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
```


Discussion:
@JobDoesburg you created this issue?

I think it crashes when you save an event with a food event attached, not when you save the food event.

Anyways, this is easy and fun because the only thing it requires is a filter on the event registrations in the `save` of the FoodEvent where we do `end_reminder.users.set` to make sure non-member registrations are not included.
Marie sent me a message that the site crashed while she was doing this, and then I checked out sentry. 

You're right btw, it is on saving the pizza event 

Resolving patch:
diff --git a/website/pizzas/models.py b/website/pizzas/models.py
--- a/website/pizzas/models.py
+++ b/website/pizzas/models.py
@@ -116,9 +116,9 @@ def save(self, **kwargs):
 
             if self.event.registration_required:
                 end_reminder.users.set(
-                    self.event.registrations.select_related("member").values_list(
-                        "member", flat=True
-                    )
+                    self.event.registrations.filter(member__isnull=False)
+                    .select_related("member")
+                    .values_list("member", flat=True)
                 )
             else:
                 end_reminder.users.set(Member.current_members.all())


Test patch: