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

Issue:
Renewals not processed correctly on uniqueness constraint for membership id
In GitLab by @JobDoesburg on Nov 20, 2019, 20:08

### One-sentence description

Renewals not processed correctly on uniqueness constraint for membership id

### Current behaviour / Reproducing the bug

1. Do a renewal for 1 year
2. Approve it, add a payment, finish it fully etc
3. Do a renewal for the rest of your study
4. Approve it
5. Process a payment
6. Breakage

(the payment gets processed, the membership is correctly added to the user, but the renewal does stick at 'approved' (with a processed payment attached))

### Expected behaviour

Do not crash


Discussion:
Could very well be that after the rewrite with `create_payment` this is not a problem anymore

Resolving patch:
diff --git a/website/registrations/migrations/0027_alter_entry_membership.py b/website/registrations/migrations/0027_alter_entry_membership.py
new file mode 100644
--- /dev/null
+++ b/website/registrations/migrations/0027_alter_entry_membership.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.2 on 2021-06-07 08:00
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('members', '0039_remove_profile_language'),
+        ('registrations', '0026_auto_20210315_2105'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='entry',
+            name='membership',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='members.membership'),
+        ),
+    ]
diff --git a/website/registrations/models.py b/website/registrations/models.py
--- a/website/registrations/models.py
+++ b/website/registrations/models.py
@@ -98,7 +98,7 @@ class Entry(models.Model):
         null=True,
     )
 
-    membership = models.OneToOneField(
+    membership = models.ForeignKey(
         "members.Membership", on_delete=models.SET_NULL, blank=True, null=True,
     )
 


Test patch:
Repository: svthalia/concrexit

Issue:
ValidationError when saving completed membership registration
In GitLab by _thaliatechnicie on Jun 5, 2019, 13:13


### One-sentence description

<!-- What breaks -->

### Current behaviour / Reproducing the bug

Click save while observing a completed registration.

Sentry Issue: [CONCREXIT-4](https://sentry.io/organizations/thalia/issues/1057927495/?referrer=gitlab_integration)

```
ValueError: 'RegistrationForm' has no field named 'email'.
(14 additional frame(s) were not displayed)
...
  File "django/forms/forms.py", line 180, in errors
    self.full_clean()
  File "django/forms/forms.py", line 383, in full_clean
    self._post_clean()
  File "django/forms/models.py", line 405, in _post_clean
    self._update_errors(e)
  File "django/forms/models.py", line 379, in _update_errors
    self.add_error(None, errors)
  File "django/forms/forms.py", line 353, in add_error
    "'%s' has no field named '%s'." % (self.__class__.__name__, field))

ValidationError: {'email': ['A user with that email address already exists. Login using the existing account and renew the membership by visiting the account settings.'], 'student_number': ['A user with that student number already exists. Login using the existing account and renew the membership by visiting the account settings.'], 'username': ['A user with that username already exists.']}
  File "django/forms/models.py", line 403, in _post_clean
    self.instance.full_clean(exclude=exclude, validate_unique=False)
  File "django/db/models/base.py", line 1152, in full_clean
    raise ValidationError(errors)
```

### Expected behaviour

No crash, maybe even no save button available.



Discussion:
In GitLab by _thaliatechnicie on Aug 17, 2019, 19:45

Possibly related. Sentry issue: [CONCREXIT-F](https://sentry.io/organizations/thalia/issues/1166060552/?referrer=gitlab_integration)
In GitLab by @mtsatsev on Oct 9, 2019, 20:55

assigned to @mtsatsev
In GitLab by @mtsatsev on Mar 4, 2020, 17:07

unassigned @mtsatsev

Resolving patch:
diff --git a/website/registrations/admin.py b/website/registrations/admin.py
--- a/website/registrations/admin.py
+++ b/website/registrations/admin.py
@@ -221,6 +221,14 @@ def has_review_permission(self, request):
         """Check if the user has the review permission."""
         return request.user.has_perm("registrations.review_entries")
 
+    def has_change_permission(self, request, obj=None):
+        """Completed registrations are read-only."""
+        return (
+            False
+            if obj and obj.status == Entry.STATUS_COMPLETED
+            else super().has_change_permission(request, obj)
+        )
+
     def save_model(self, request, obj, form, change):
         if not (
             obj.status == Entry.STATUS_REJECTED


Test patch:
Repository: svthalia/concrexit

Issue:
Groups miss description in API v2
### Describe the bug
The `description` field is missing in the `activemembers/groups` serializers. 

### How to reproduce
Look at swagger.

### Expected behaviour
An extra field for the description, at least in the detail endpoints.

### Additional context
Also something to double-check: groups have a field `display_members`. This is not included in the serializers, so are the members not shown if that field is true?



Discussion:
display_members should not be a problem since the API is not for public usage.

Resolving patch:
diff --git a/website/activemembers/api/v2/serializers/member_group.py b/website/activemembers/api/v2/serializers/member_group.py
--- a/website/activemembers/api/v2/serializers/member_group.py
+++ b/website/activemembers/api/v2/serializers/member_group.py
@@ -24,6 +24,7 @@ class Meta:
             "pk",
             "name",
             "type",
+            "description",
             "since",
             "until",
             "contact_address",
@@ -58,4 +59,13 @@ class Meta:
         """Meta class for the serializer."""
 
         model = MemberGroup
-        fields = ("pk", "name", "type", "since", "until", "contact_address", "photo")
+        fields = (
+            "pk",
+            "name",
+            "type",
+            "description",
+            "since",
+            "until",
+            "contact_address",
+            "photo",
+        )


Test patch:
Repository: svthalia/concrexit

Issue:
AttributeError: 'Settings' object has no attribute 'THALIA_PAY_FOR_NEW_MEMBERS'
Sentry Issue: [CONCREXIT-6B](https://sentry.io/organizations/thalia/issues/2464600322/?referrer=github_integration)

```
AttributeError: 'Settings' object has no attribute 'THALIA_PAY_FOR_NEW_MEMBERS'
(3 additional frame(s) were not displayed)
...
  File "django/views/generic/base.py", line 98, in dispatch
    return handler(request, *args, **kwargs)
  File "registrations/views.py", line 150, in get
    return super().get(request, args, kwargs)
  File "django/views/generic/edit.py", line 133, in get
    return self.render_to_response(self.get_context_data())
  File "registrations/views.py", line 168, in get_context_data
    and settings.THALIA_PAY_FOR_NEW_MEMBERS
  File "django/conf/__init__.py", line 83, in __getattr__
    val = getattr(self._wrapped, name)
```


Discussion:

Resolving patch:
diff --git a/website/thaliawebsite/settings.py b/website/thaliawebsite/settings.py
--- a/website/thaliawebsite/settings.py
+++ b/website/thaliawebsite/settings.py
@@ -174,6 +174,7 @@ def from_env(
 THALIA_PAY_ENABLED_PAYMENT_METHOD = (
     from_env("THALIA_PAY_ENABLED", development="1", staging="1", production="0") == "1"
 )
+THALIA_PAY_FOR_NEW_MEMBERS = os.environ.get("THALIA_PAY_FOR_NEW_MEMBERS", "1") == "1"
 
 ###############################################################################
 # Django settings


Test patch:
Repository: svthalia/concrexit

Issue:
AttributeError: 'Event' object has no attribute 'title_en'
Sentry Issue: [CONCREXIT-6D](https://sentry.io/organizations/thalia/issues/2465590057/?referrer=github_integration)

```
AttributeError: 'Event' object has no attribute 'title_en'
(9 additional frame(s) were not displayed)
...
  File "rest_framework/mixins.py", line 68, in update
    self.perform_update(serializer)
  File "pizzas/api/v1/viewsets.py", line 105, in perform_update
    self._update_payment(
  File "pizzas/api/v1/viewsets.py", line 114, in _update_payment
    order.payment = create_payment(order, processed_by, payment_type)
  File "payments/services.py", line 67, in create_payment
    notes=payable.payment_notes,
  File "pizzas/payables.py", line 21, in payment_notes
    f"Food order by {self.model.member_name} "
```


Discussion:

Resolving patch:
diff --git a/website/pizzas/payables.py b/website/pizzas/payables.py
--- a/website/pizzas/payables.py
+++ b/website/pizzas/payables.py
@@ -13,13 +13,13 @@ def payment_amount(self):
     @property
     def payment_topic(self):
         start_date = date(self.model.food_event.start, "Y-m-d")
-        return f"Food {self.model.food_event.event.title_en} [{start_date}]"
+        return f"Food {self.model.food_event.event.title} [{start_date}]"
 
     @property
     def payment_notes(self):
         return (
             f"Food order by {self.model.member_name} "
-            f"for {self.model.food_event.event.title_en}"
+            f"for {self.model.food_event.event.title}"
         )
 
     @property


Test patch:
Repository: svthalia/concrexit

Issue:
Renewal of membership send email about references without reason
### Describe the bug
A renewal of a membership to the 'until study end' triggered the email for references.


### How to reproduce
Steps to reproduce the behaviour:
1. Create a registration for a completely new user
2. Create an upgrade for the membership
3. Get the email

### Expected behaviour

No email should be received for references.

### Screenshots
<img width="929" alt="Screenshot 2021-06-20 at 15 20 10" src="https://user-images.githubusercontent.com/1799914/122675750-2a245800-d1db-11eb-93eb-d02abc0f63d1.png">
<img width="656" alt="Screenshot 2021-06-20 at 15 20 20" src="https://user-images.githubusercontent.com/1799914/122675752-2b558500-d1db-11eb-9763-3c1f622826e7.png">




Discussion:

Resolving patch:
diff --git a/website/registrations/forms.py b/website/registrations/forms.py
--- a/website/registrations/forms.py
+++ b/website/registrations/forms.py
@@ -151,7 +151,14 @@ def __init__(self, *args, **kwargs):
 
     class Meta:
         model = Renewal
-        fields = ("member", "length", "contribution", "membership_type")
+        fields = (
+            "member",
+            "length",
+            "contribution",
+            "membership_type",
+            "no_references",
+            "remarks",
+        )
 
 
 class ReferenceForm(forms.ModelForm):


Test patch:
Repository: svthalia/concrexit

Issue:
Cannot renew membership as benefactor, expects length field
### Describe the bug
Right now, when trying to renew a membership as benefactor from http://localhost:8000/user/membership/ I can't send the form. I get a javascript error: `An invalid form control with name='length' is not focusable.` 
So the problem is that the length field is expected to have a value while this isn't the case for benefactors.

### How to reproduce
Steps to reproduce the behaviour:
1. Go to http://localhost:8000/user/membership/
2. Add a benefactor membership renewal 
3. The form will not respond when trying to send
4. You will get a javascript error, indicating that the form can't focus on the length field (as it is hidden for benefactors), 

### Expected behaviour
It should ignore the length field for benefactorship renewals, as for benefactors it is always 1 year



Discussion:
I found the problem. website/registrations/views.py:241 hides the `year` choice in certain cases. The reason is that throughout the year, people can only upgrade their membership to a study membership.

However, the `year` choice needs to remain to allow people to renew their membership for benefactorship.  

I think it is best to just remove that filtering altogether. What do you think, @se-bastiaan 

Resolving patch:
diff --git a/website/registrations/views.py b/website/registrations/views.py
--- a/website/registrations/views.py
+++ b/website/registrations/views.py
@@ -237,7 +237,7 @@ def get_form(self, form_class=None):
         if member is not None and member.latest_membership is not None:
             latest_membership = member.latest_membership
             # If latest membership has not ended or does not ends
-            # within 1 month: do not show 'year' length
+            # within 1 month: do not show 'year' length and disable benefactor option
             hide_year_choice = not (
                 latest_membership is not None
                 and latest_membership.until is not None
@@ -250,6 +250,11 @@ def get_form(self, form_class=None):
                     for c in form.fields["length"].choices
                     if c[0] != Entry.MEMBERSHIP_YEAR
                 ]
+                form.fields["membership_type"].choices = [
+                    c
+                    for c in form.fields["membership_type"].choices
+                    if c[0] != Membership.BENEFACTOR
+                ]
 
         return form
 


Test patch:
Repository: svthalia/concrexit

Issue:
Cannot enter float number as contribution during benefactor renewal
### Describe the bug
Cannot enter float number as contribution during benefactor renewal

### How to reproduce
Steps to reproduce the behaviour:
1. Go to http://localhost:8000/user/membership/
2. Add a benefactor membership renewal 
3. The form will not error when trying to send

### Expected behaviour
Can enter float numbers as contribution. Like 7.69.

### Screenshots
<img width="691" alt="Screenshot 2021-06-20 at 18 48 35" src="https://user-images.githubusercontent.com/1799914/122682192-4edaf880-d1f8-11eb-99e2-26eaf5379ae8.png">




Discussion:

Resolving patch:
diff --git a/website/registrations/forms.py b/website/registrations/forms.py
--- a/website/registrations/forms.py
+++ b/website/registrations/forms.py
@@ -139,7 +139,7 @@ class RenewalForm(forms.ModelForm):
         required=False, label=_("I am an employee of iCIS")
     )
 
-    contribution = forms.IntegerField(required=False,)
+    contribution = forms.DecimalField(required=False, max_digits=5, decimal_places=2,)
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)


Test patch:
Repository: svthalia/concrexit

Issue:
FieldError: Cannot resolve keyword 'pizza_event' into field. Choices are: food_event, food_event_id, id, memb...
Sentry Issue: [CONCREXIT-6G](https://sentry.io/organizations/thalia/issues/2468308255/?referrer=github_integration)

```
FieldError: Cannot resolve keyword 'pizza_event' into field. Choices are: food_event, food_event_id, id, member, member_id, name, payment, payment_id, product, product_id
(9 additional frame(s) were not displayed)
...
  File "django/db/models/sql/query.py", line 1391, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "django/db/models/sql/query.py", line 1410, in _add_q
    child_clause, needed_inner = self.build_filter(
  File "django/db/models/sql/query.py", line 1284, in build_filter
    lookups, parts, reffed_expression = self.solve_lookup_type(arg)
  File "django/db/models/sql/query.py", line 1110, in solve_lookup_type
    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
  File "django/db/models/sql/query.py", line 1537, in names_to_path
    raise FieldError("Cannot resolve keyword '%s' into field. "
```


Discussion:

Resolving patch:
diff --git a/website/pizzas/services.py b/website/pizzas/services.py
--- a/website/pizzas/services.py
+++ b/website/pizzas/services.py
@@ -36,7 +36,7 @@ def gen_stats_current_pizza_orders():
         total.update(
             {
                 product.name: FoodOrder.objects.filter(
-                    product=product, pizza_event=current_pizza_event,
+                    product=product, food_event=current_pizza_event,
                 ).count(),
             }
         )
diff --git a/website/pizzas/views.py b/website/pizzas/views.py
--- a/website/pizzas/views.py
+++ b/website/pizzas/views.py
@@ -17,7 +17,7 @@ def index(request):
         products = products.exclude(restricted=True)
     event = FoodEvent.current()
     try:
-        obj = FoodOrder.objects.get(pizza_event=event, member=request.member)
+        obj = FoodOrder.objects.get(food_event=event, member=request.member)
     except FoodOrder.DoesNotExist:
         obj = None
     context = {"event": event, "products": products, "order": obj}
@@ -48,7 +48,7 @@ def place_order(request):
         return redirect("pizzas:index")
 
     try:
-        obj = FoodOrder.objects.get(pizza_event=event, member=request.member)
+        obj = FoodOrder.objects.get(food_event=event, member=request.member)
         current_order_locked = not obj.can_be_changed
     except FoodOrder.DoesNotExist:
         obj = None
@@ -63,7 +63,7 @@ def place_order(request):
         except Product.DoesNotExist as e:
             raise Http404("Pizza does not exist") from e
         if not obj:
-            obj = FoodOrder(pizza_event=event, member=request.member)
+            obj = FoodOrder(food_event=event, member=request.member)
         obj.product = product
         obj.save()
     return redirect("pizzas:index")


Test patch:
Repository: svthalia/concrexit

Issue:
Event registration member serializer should be read only
### Describe the bug
https://github.com/svthalia/concrexit/blob/4ab37961f50e398cc52422cdc1df66f6ab8ff2ee/website/events/api/v2/serializers/event_registration.py#L34 This serializer should be read-only

### How to reproduce
https://staging.thalia.nu/api/v2/events/150/registrations/ shows that you can POST to update the member profile, that should not be the case

### Expected behaviour
Be read only



Discussion:

Resolving patch:
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
@@ -31,4 +31,4 @@ class Meta:
             "name",
         )
 
-    member = MemberSerializer(detailed=False)
+    member = MemberSerializer(detailed=False, read_only=True)


Test patch:
Repository: svthalia/concrexit

Issue:
PaymentDetailView in admin API allows deleting payments unauthorized
https://github.com/svthalia/concrexit/blob/4ab37961f50e398cc52422cdc1df66f6ab8ff2ee/website/payments/api/v2/admin/views.py#L69

### Describe the bug
Payments sometimes should be undeletable. For example, TPay payments that are in a batch. The PaymentAdmin prevents such deletions. However, the rest framework DestroyAPIView does not respect that.

### How to reproduce
Steps to reproduce the behaviour:
1. Have a payment 
2. Add it to a batch
3. Process the batch
4. Do the API `DELETE` request at `/api/v2/admin/payments/<id>`

### Expected behaviour
Either disable payment deletion at all from the API, or manually implement a check that the payment is not in a processed batch.



Discussion:

Resolving patch:
diff --git a/website/payments/api/v2/admin/views.py b/website/payments/api/v2/admin/views.py
--- a/website/payments/api/v2/admin/views.py
+++ b/website/payments/api/v2/admin/views.py
@@ -74,6 +74,11 @@ class PaymentDetailView(AdminRetrieveAPIView, AdminDestroyAPIView):
     permission_classes = [IsAuthenticatedOrTokenHasScope]
     required_scopes = ["payments:admin"]
 
+    def delete(self, request, *args, **kwargs):
+        if self.get_object().batch and self.get_object().batch.processed:
+            raise PermissionDenied("This payment cannot be deleted.")
+        return super().delete(request, *args, **kwargs)
+
 
 class PayableDetailView(APIView):
     """View that allows you to manipulate the payment for the payable.


Test patch:
Repository: svthalia/concrexit

Issue:
Event registrations cannot be deleted from admin API
### Describe the bug
Event registrations cannot be deleted from admin API. Users are able to delete event registrations from the admin, so they should also be allowed to do it via the API

### How to reproduce
1. Try to delete an event registration with the API (as admin)
2. You can't

### Expected behaviour
You should be able to do it




Discussion:

Resolving patch:
diff --git a/website/events/api/v2/admin/views.py b/website/events/api/v2/admin/views.py
--- a/website/events/api/v2/admin/views.py
+++ b/website/events/api/v2/admin/views.py
@@ -84,7 +84,9 @@ def get_queryset(self):
         return EventRegistration.objects.none()
 
 
-class EventRegistrationAdminDetailView(AdminRetrieveAPIView, AdminUpdateAPIView):
+class EventRegistrationAdminDetailView(
+    AdminRetrieveAPIView, AdminUpdateAPIView, AdminDestroyAPIView
+):
     """Returns details of an event registration."""
 
     serializer_class = EventRegistrationAdminSerializer
diff --git a/website/events/api/v2/views.py b/website/events/api/v2/views.py
--- a/website/events/api/v2/views.py
+++ b/website/events/api/v2/views.py
@@ -3,7 +3,12 @@
 from rest_framework import filters as framework_filters
 from rest_framework import status
 from rest_framework.exceptions import PermissionDenied
-from rest_framework.generics import ListAPIView, RetrieveAPIView, get_object_or_404
+from rest_framework.generics import (
+    ListAPIView,
+    RetrieveAPIView,
+    get_object_or_404,
+    DestroyAPIView,
+)
 from rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly
 from rest_framework.response import Response
 from rest_framework.utils import json
@@ -46,7 +51,7 @@ class EventDetailView(RetrieveAPIView):
     required_scopes = ["events:read"]
 
 
-class EventRegistrationsView(ListAPIView):
+class EventRegistrationsView(ListAPIView, DestroyAPIView):
     """Returns a list of registrations."""
 
     serializer_class = EventRegistrationSerializer
@@ -108,8 +113,15 @@ def post(self, request, *args, **kwargs):
         except RegistrationError as e:
             raise PermissionDenied(detail=e) from e
 
+    def delete(self, request, *args, **kwargs):
+        try:
+            services.cancel_registration(request.member, self.event)
+            return Response(status=status.HTTP_204_NO_CONTENT)
+        except RegistrationError as e:
+            raise PermissionDenied(detail=e) from e
+
 
-class EventRegistrationDetailView(RetrieveAPIView):
+class EventRegistrationDetailView(RetrieveAPIView, DestroyAPIView):
     """Returns details of an event registration."""
 
     serializer_class = EventRegistrationSerializer


Test patch: