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

Issue:
create fixtures crashes on "django.db.utils.IntegrityError: UNIQUE constraint failed: activemembers_membergroup.name"
### Describe the bug
When running `./manage.py createfixtures`, it crashes on the following error: `django.db.utils.IntegrityError: UNIQUE constraint failed: activemembers_membergroup.name`

### How to reproduce
Run `./manage.py createfixtures`

### Expected behaviour
Not crash

### Additional context
The reason this bug occurs, seems to be that after removing localization, we are using `member_group.name` instead of `name_en` in the database. However, this is not fixed in the `createfixtures` code.


Discussion:
This should be a result of https://github.com/svthalia/concrexit/pull/1216

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
@@ -145,14 +145,18 @@ def create_board(self, lecture_year):
 
         board = Board()
 
-        board.name_en = "Board {}-{}".format(lecture_year, lecture_year + 1)
-        board.description_en = _faker.paragraph()
+        board.name = "Board {}-{}".format(lecture_year, lecture_year + 1)
+        while Board.objects.filter(name=board.name).exists():
+            lecture_year = lecture_year - 1
+            board.name = "Board {}-{}".format(lecture_year, lecture_year + 1)
+
+        board.description = _faker.paragraph()
 
         igen = IconGenerator(5, 5)  # 5x5 blocks
         icon = igen.generate(
-            board.name_en, 480, 480, padding=(10, 10, 10, 10), output_format="jpeg"
+            board.name, 480, 480, padding=(10, 10, 10, 10), output_format="jpeg"
         )  # 620x620 pixels, with 10 pixels padding on each side
-        board.photo.save(board.name_en + ".jpeg", ContentFile(icon))
+        board.photo.save(f"{board.name}.jpeg", ContentFile(icon))
 
         board.since = date(year=lecture_year, month=9, day=1)
         board.until = date(year=lecture_year + 1, month=8, day=31)
@@ -186,18 +190,14 @@ def create_member_group(self, group_model):
 
         member_group = group_model()
 
-        member_group.name_en = _generate_title()
-        member_group.description_en = _faker.paragraph()
+        member_group.name = _generate_title()
+        member_group.description = _faker.paragraph()
 
         igen = IconGenerator(5, 5)  # 5x5 blocks
         icon = igen.generate(
-            member_group.name_en,
-            480,
-            480,
-            padding=(10, 10, 10, 10),
-            output_format="jpeg",
+            member_group.name, 480, 480, padding=(10, 10, 10, 10), output_format="jpeg",
         )  # 620x620 pixels, with 10 pixels padding on each side
-        member_group.photo.save(member_group.name_en + ".jpeg", ContentFile(icon))
+        member_group.photo.save(member_group.name + ".jpeg", ContentFile(icon))
 
         member_group.since = _faker.date_time_between("-10y", "+30d")
 


Test patch:
Repository: svthalia/concrexit

Issue:
Remove pay_with_tpay service from events
### Describe the change
Events app currently has a service `pay_with_tpay` that is not used.

### Motivation
Unused code should be removed

### Current implementation
Unused code

### Suggested implementation
Remove the unused code

### Additional context



Discussion:

Resolving patch:
diff --git a/website/events/services.py b/website/events/services.py
--- a/website/events/services.py
+++ b/website/events/services.py
@@ -8,7 +8,6 @@
 from events.exceptions import RegistrationError
 from events.models import EventRegistration, RegistrationInformationField, Event
 from payments.api.fields import PaymentTypeField
-from payments.models import Payment
 from payments.services import create_payment, delete_payment
 from utils.snippets import datetime_to_lectureyear
 
@@ -155,27 +154,6 @@ def cancel_registration(member, event):
         raise RegistrationError(_("You are not registered for this event."))
 
 
-def pay_with_tpay(member, event):
-    """
-    Add a Thalia Pay payment to an event registration
-
-    :param member: the user
-    :param event: the event
-    """
-    try:
-        registration = EventRegistration.objects.get(event=event, member=member)
-    except EventRegistration.DoesNotExist:
-        raise RegistrationError(_("You are not registered for this event."))
-
-    if registration.payment is None:
-        registration.payment = create_payment(
-            payable=registration, processed_by=member, pay_type=Payment.TPAY
-        )
-        registration.save()
-    else:
-        raise RegistrationError(_("You have already paid for this event."))
-
-
 def update_registration(
     member=None, event=None, name=None, registration=None, field_values=None
 ):


Test patch:
Repository: svthalia/concrexit

Issue:
Prevent event registrations cancelling when registration is paid (or where you were present)
### Is your feature request related to a problem? Please describe.
Currently it is technically possible to pay for an event and afterwards cancel your registration. That should not be possible (at least not by users themselves). This never was a real problem in practice but now with Thalia Pay the problem appears.

### Describe the solution you'd like
When a payment exists for an event registration, don't allow cancelling. Also when paying with Thalia Pay we might want to make explicit that after paying you can't cancel anymore (without maybe contacting the board). 

### Motivation

### Describe alternatives you've considered
- Only really creating the payment at the date of the event → too complex (code)
- As proposed here, but do allow cancellation when the payment is a TPay payment that is not processed yet → too complex (for users)
- Keeping things as it is (allow cancelling and accept people may pay without joining - it could be considered a feature) → felt undesirable, also without TPay

### Additional context



Discussion:

Resolving patch:
diff --git a/website/events/services.py b/website/events/services.py
--- a/website/events/services.py
+++ b/website/events/services.py
@@ -62,6 +62,7 @@ def event_permissions(member, event, name=None):
         registration is not None
         and registration.date_cancelled is None
         and (event.cancellation_allowed or name)
+        and registration.payment is None
     )
     perms["update_registration"] = (
         registration is not None
@@ -136,8 +137,6 @@ def cancel_registration(member, event):
         pass
 
     if event_permissions(member, event)["cancel_registration"] and registration:
-        if registration.payment is not None:
-            delete_payment(registration)
         if registration.queue_position == 0:
             emails.notify_first_waiting(event)
 
@@ -151,7 +150,7 @@ def cancel_registration(member, event):
         registration.date_cancelled = timezone.now()
         registration.save()
     else:
-        raise RegistrationError(_("You are not registered for this event."))
+        raise RegistrationError(_("You are not allowed to deregister for this event."))
 
 
 def update_registration(


Test patch:
Repository: svthalia/concrexit

Issue:
Change registration contribution from FloatField to DecimalField
### Describe the change
We currently user FloatFields for contribution amounts. We should use DecimalField's.

### Motivation
Events also use DecimalFields for the price of an event. Also, consider [https://docs.python.org/3/library/decimal.html#module-decimal](https://docs.python.org/3/library/decimal.html#module-decimal)

### Current implementation
FloatFields

### Suggested implementation
Just change it 



Discussion:
This is also a good read: https://stackoverflow.com/questions/2569015/django-floatfield-or-decimalfield-for-currency

Resolving patch:
diff --git a/website/registrations/migrations/0025_auto_20201005_2018.py b/website/registrations/migrations/0025_auto_20201005_2018.py
new file mode 100644
--- /dev/null
+++ b/website/registrations/migrations/0025_auto_20201005_2018.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.1.2 on 2020-10-05 18:18
+
+import django.core.validators
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('registrations', '0024_auto_20200325_2045'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='entry',
+            name='contribution',
+            field=models.DecimalField(decimal_places=2, default=7.5, max_digits=5, validators=[django.core.validators.MinValueValidator(7.5)], verbose_name='contribution'),
+        ),
+    ]
diff --git a/website/registrations/models.py b/website/registrations/models.py
--- a/website/registrations/models.py
+++ b/website/registrations/models.py
@@ -66,8 +66,10 @@ class Entry(models.Model, Payable):
         m for m in Membership.MEMBERSHIP_TYPES if m[0] != Membership.HONORARY
     ]
 
-    contribution = models.FloatField(
+    contribution = models.DecimalField(
         verbose_name=_("contribution"),
+        max_digits=5,
+        decimal_places=2,
         validators=[MinValueValidator(settings.MEMBERSHIP_PRICES["year"])],
         default=settings.MEMBERSHIP_PRICES["year"],
         blank=False,


Test patch:
Repository: svthalia/concrexit

Issue:
TypeError: '<' not supported between instances of 'datetime.date' and 'NoneType'
Sentry Issue: [CONCREXIT-3T](https://sentry.io/organizations/thalia/issues/1937285207/?referrer=github_integration)

```
TypeError: '<' not supported between instances of 'datetime.date' and 'NoneType'
(5 additional frame(s) were not displayed)
...
  File "django/views/generic/base.py", line 98, in dispatch
    return handler(request, *args, **kwargs)
  File "django/views/generic/detail.py", line 107, in get
    context = self.get_context_data(object=self.object)
  File "members/views.py", line 181, in get_context_data
    societies = member_societies(member)
  File "members/services.py", line 91, in member_societies
    societies = _member_group_memberships(
  File "members/services.py", line 45, in _member_group_memberships
    if data[name]["latest"] < membership.until:
```


Discussion:

Resolving patch:
diff --git a/website/members/services.py b/website/members/services.py
--- a/website/members/services.py
+++ b/website/members/services.py
@@ -40,10 +40,13 @@ def _member_group_memberships(
         name = membership.group.name
         if data.get(name):
             data[name]["periods"].append(period)
-            if data[name]["earliest"] > membership.since:
-                data[name]["earliest"] = membership.since
-            if data[name]["latest"] < membership.until:
-                data[name]["latest"] = membership.until
+            if data[name]["earliest"] > period["since"]:
+                data[name]["earliest"] = period["since"]
+            if period["until"] is None or (
+                data[name]["latest"] is not None
+                and data[name]["latest"] < period["until"]
+            ):
+                data[name]["latest"] = period["until"]
             data[name]["periods"].sort(key=lambda x: x["since"])
         else:
             data[name] = {
@@ -52,8 +55,8 @@ def _member_group_memberships(
                 "name": name,
                 "periods": [period],
                 "url": settings.BASE_URL + membership.group.get_absolute_url(),
-                "earliest": membership.since,
-                "latest": membership.until,
+                "earliest": period["since"],
+                "latest": period["until"],
             }
     return data
 


Test patch:
Repository: svthalia/concrexit

Issue:
Admin PaymentWidget can crash if payable.payment_payer returns None
### Describe the bug
After #1320, the PaymentWidget (`payments/widgets.py`) can crash if the `payment_payer` is `None`, for example for `registrations`. 

### How to reproduce
Steps to reproduce the behaviour:
1. Make a registration
2. Accept it (so the payment widget will appear)
3. Crash

### Expected behaviour
Not crash (we can just feed `None` to the html template)

Admin PaymentWidget can crash if payable.payment_payer returns None
### Describe the bug
After #1320, the PaymentWidget (`payments/widgets.py`) can crash if the `payment_payer` is `None`, for example for `registrations`. 

### How to reproduce
Steps to reproduce the behaviour:
1. Make a registration
2. Accept it (so the payment widget will appear)
3. Crash

### Expected behaviour
Not crash (we can just feed `None` to the html template)



Discussion:

Resolving patch:
diff --git a/website/payments/admin_views.py b/website/payments/admin_views.py
--- a/website/payments/admin_views.py
+++ b/website/payments/admin_views.py
@@ -43,9 +43,7 @@ def post(self, request, *args, app_label, model_name, payable, **kwargs):
         payable_obj = payable_model.objects.get(pk=payable)
 
         result = services.create_payment(
-            payable_obj,
-            PaymentUser.objects.get(pk=self.request.member.pk),
-            request.POST["type"],
+            payable_obj, self.request.member, request.POST["type"],
         )
         payable_obj.save()
 
diff --git a/website/payments/widgets.py b/website/payments/widgets.py
--- a/website/payments/widgets.py
+++ b/website/payments/widgets.py
@@ -22,8 +22,8 @@ def get_context(self, name, value, attrs) -> dict:
             context["obj"] = self.obj
             context["payable_payer"] = (
                 PaymentUser.objects.get(pk=self.obj.payment_payer.pk)
-                if hasattr(self.obj, "payment_payer")
-                else self.obj.paid_by
+                if getattr(self.obj, "payment_payer", None) is not None
+                else None
             )
             context["content_type"] = ContentType.objects.get_for_model(self.obj)
         elif value:


Test patch:
Repository: svthalia/concrexit

Issue:
Internet required to run tests
In GitLab by @joren485 on Jan 26, 2020, 20:07

### Description
Internet required to run tests, because [`activemembers/signals.py` always initializes the G Suite API](https://gitlab.science.ru.nl/thalia/concrexit/blob/master/website/activemembers/signals.py#L15). This is not (and should not be) always necessary (e.g. when running tests).


Discussion:
In GitLab by @se-bastiaan on Jan 26, 2020, 21:31

mmm it's better to initialise it globally because of the caching, but we should be able to disable it in test environments
In GitLab by @joren485 on Jan 26, 2020, 22:07

This problem does not only occur with the tests, but also when running a development environment (i.e. `python website/manage.py runserver` does not work without internet).
We can borrow code to do this from https://github.com/GipHouse/website as soon as @lukovdm is done there :p

Resolving patch:
diff --git a/website/activemembers/gsuite.py b/website/activemembers/gsuite.py
--- a/website/activemembers/gsuite.py
+++ b/website/activemembers/gsuite.py
@@ -5,17 +5,22 @@
 from django.utils.translation import gettext_lazy as _, override as lang_override
 
 from googleapiclient.errors import HttpError
-from utils.google_api import get_directory_api
 
 from members.models import Member
+from utils.google_api import get_directory_api
 
 logger = logging.getLogger(__name__)
 
 
 class GSuiteUserService:
-    def __init__(self, directory_api=get_directory_api()):
-        super().__init__()
-        self.directory_api = directory_api
+    def __init__(self, directory_api=None):
+        self._directory_api = directory_api
+
+    @property
+    def directory_api(self):
+        if self._directory_api is not None:
+            return self._directory_api
+        return get_directory_api()
 
     def create_user(self, member: Member):
         """
diff --git a/website/mailinglists/gsuite.py b/website/mailinglists/gsuite.py
--- a/website/mailinglists/gsuite.py
+++ b/website/mailinglists/gsuite.py
@@ -37,13 +37,22 @@ def __eq__(self, other: object) -> bool:
             return False
 
     def __init__(
-        self,
-        groups_settings_api=get_groups_settings_api(),
-        directory_api=get_directory_api(),
+        self, groups_settings_api=None, directory_api=None,
     ):
-        super().__init__()
-        self.groups_settings_api = groups_settings_api
-        self.directory_api = directory_api
+        self._groups_settings_api = groups_settings_api
+        self._directory_api = directory_api
+
+    @property
+    def directory_api(self):
+        if self._directory_api is not None:
+            return self._directory_api
+        return get_directory_api()
+
+    @property
+    def groups_settings_api(self):
+        if self._groups_settings_api is not None:
+            return self._groups_settings_api
+        return get_groups_settings_api()
 
     @staticmethod
     def _group_settings(moderated):


Test patch:
Repository: svthalia/concrexit

Issue:
Profile page crashes when not logged in
Sentry Issue: [CONCREXIT-40](https://sentry.io/organizations/thalia/issues/1976140555/?referrer=github_integration)

```
AttributeError: 'NoneType' object has no attribute 'pk'
  File "django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "django/core/handlers/base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "django/views/generic/base.py", line 64, in view
    self.setup(request, *args, **kwargs)
  File "members/views.py", line 173, in setup
    kwargs["pk"] = request.member.pk
  File "django/utils/functional.py", line 241, in inner
    return func(self._wrapped, *args)
```

Steps to reproduce:
1. Open https://thalia.nu/members/profile/ in Incognito mode


Discussion:

Resolving patch:
diff --git a/website/members/views.py b/website/members/views.py
--- a/website/members/views.py
+++ b/website/members/views.py
@@ -170,7 +170,7 @@ class ProfileDetailView(DetailView):
     template_name = "members/user/profile.html"
 
     def setup(self, request, *args, **kwargs) -> None:
-        if "pk" not in kwargs:
+        if "pk" not in kwargs and request.member:
             kwargs["pk"] = request.member.pk
         super().setup(request, *args, **kwargs)
 


Test patch:
Repository: svthalia/concrexit

Issue:
Searching in photos api is broken
### Describe the bug
Searching in photos api is broken

### How to reproduce
Steps to reproduce the behaviour:
1. Go to https://thalia.nu/api/v1/photos/albums/?search=Test

### Expected behaviour
This should not crash.




Discussion:

Resolving patch:
diff --git a/website/photos/api/viewsets.py b/website/photos/api/viewsets.py
--- a/website/photos/api/viewsets.py
+++ b/website/photos/api/viewsets.py
@@ -14,7 +14,7 @@ class AlbumsViewSet(ModelViewSet):
     permission_classes = (permissions.IsAuthenticated,)
     queryset = Album.objects.all()
     filter_backends = (filters.SearchFilter,)
-    search_fields = ("title_en", "title_nl", "date", "slug")
+    search_fields = ("title_en", "date", "slug")
 
     def get_queryset(self):
         """Return albums that are annotated to be accessible by the request user."""


Test patch:
Repository: svthalia/concrexit

Issue:
Documents page broken
Steps to reproduce:
1. Go to https://thalia.nu/association/documents/


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

```
FieldError: Cannot resolve keyword 'name_en' into field. Choices are: annualdocument, category, created, event, eventdocument, file, generalmeeting, id, last_updated, members_only, minutes, name
(5 additional frame(s) were not displayed)
...
  File "documents/views.py", line 54, in get_context_data
    "association_documents": AssociationDocument.objects.order_by(
  File "django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "django/db/models/query.py", line 1134, in order_by
    obj.query.add_ordering(*field_names)
  File "django/db/models/sql/query.py", line 1919, in add_ordering
    self.names_to_path(item.split(LOOKUP_SEP), self.model._meta)
  File "django/db/models/sql/query.py", line 1481, in names_to_path
    raise FieldError("Cannot resolve keyword '%s' into field. "
```


Discussion:

Resolving patch:
diff --git a/website/documents/views.py b/website/documents/views.py
--- a/website/documents/views.py
+++ b/website/documents/views.py
@@ -7,7 +7,6 @@
 from django.shortcuts import redirect
 from django.utils import timezone
 from django.utils.text import slugify
-from django.utils.translation import get_language
 from django.views.generic import TemplateView, DetailView
 from django_sendfile import sendfile
 
@@ -52,7 +51,7 @@ def get_context_data(self, **kwargs) -> dict:
         context.update(
             {
                 "association_documents": AssociationDocument.objects.order_by(
-                    f"name_{get_language()}"
+                    "name"
                 ).all(),
                 "years": list(years.items()),
             }
@@ -81,12 +80,8 @@ def get(self, request, *args, **kwargs) -> HttpResponse:
         if document.members_only and not request.member.has_active_membership():
             raise PermissionDenied
 
-        lang = request.GET.get("language")
         try:
-            if lang == "en":
-                file = document.file_en
-            else:  # Fall back on language detection
-                file = document.file
+            file = document.file
         except ValueError as e:
             raise Http404("This document does not exist.") from e
 


Test patch:
Repository: svthalia/concrexit

Issue:
Event (registration) status message in the API
### Is your feature request related to a problem? Please describe.
Currently, the event status messages (like 'you cannot cancel your registration without having to pay a fine') are hardcoded and whenever we update them, we must also update the app

### Describe the solution you'd like
Put the message in the API

### Additional context
Also checkout #1381 


Discussion:

Resolving patch:
diff --git a/website/events/api/v1/serializers/events/retrieve.py b/website/events/api/v1/serializers/events/retrieve.py
--- a/website/events/api/v1/serializers/events/retrieve.py
+++ b/website/events/api/v1/serializers/events/retrieve.py
@@ -41,6 +41,7 @@ class Meta:
             "google_maps_url",
             "is_admin",
             "slide",
+            "cancel_too_late_message",
         )
 
     description = serializers.SerializerMethodField("_description")
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
@@ -181,6 +181,17 @@ class Event(models.Model, metaclass=ModelTranslateMeta):
 
     tpay_allowed = models.BooleanField(_("Allow Thalia Pay"), default=True)
 
+    @property
+    def cancel_too_late_message(self):
+        return _(
+            "Cancellation isn't possible anymore without having to pay "
+            "the full costs of €" + str(self.fine) + ". Also note that "
+            "you will be unable to re-register. Note: If you have any "
+            "COVID-19 symptoms you will not have to pay these fees. "
+            "Let us know via info@thalia.nu that this is this reason "
+            "for your cancellation."
+        )
+
     @property
     def after_cancel_deadline(self):
         return self.cancel_deadline and self.cancel_deadline <= timezone.now()


Test patch:
diff --git a/website/events/tests/test_views.py b/website/events/tests/test_views.py
--- a/website/events/tests/test_views.py
+++ b/website/events/tests/test_views.py
@@ -435,7 +435,7 @@ def test_registration_cancel_after_deadline_warning(self):
         response = self.client.get("/events/1/")
         self.assertContains(
             response,
-            "Cancellation isn't possible anymore without having to pay the full costs of",
+            "Cancellation isn&#x27;t possible anymore without having to pay the full costs of",
         )
 
     def test_registration_cancel_after_deadline_waitinglist_no_warning(self):