internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: akvo/akvo-rsr

Issue:
REST API: project_extra with organisation filter gives duplicates
The `project_extra` REST API endpoint shows duplicate projects when it is filtered on organisation.



Discussion:

Resolving patch:
diff --git a/akvo/rest/views/project.py b/akvo/rest/views/project.py
--- a/akvo/rest/views/project.py
+++ b/akvo/rest/views/project.py
@@ -93,7 +93,7 @@ def get_queryset(self):
         if sync_owner:
             queryset = queryset.filter(partnerships__iati_organisation_role=101,
                                        partnerships__organisation__pk=sync_owner)
-        return queryset
+        return queryset.distinct()
 
 
 class ProjectExtraViewSet(ProjectViewSet):


Test patch:
Repository: akvo/akvo-rsr

Issue:
Saving a project with only a title does not work in 'old' admin
## Test plan
1. Go to the old admin and add a new project: /en/admin/rsr/project/add/
2. Fill in a title and select a partner type
3. Save
4. **RESULT:** the project should be saved and not give a validation error for the IATI activity ID



Discussion:

Resolving patch:
diff --git a/akvo/rsr/models/project.py b/akvo/rsr/models/project.py
--- a/akvo/rsr/models/project.py
+++ b/akvo/rsr/models/project.py
@@ -325,19 +325,27 @@ class Meta:
         )
 
     def save(self, last_updated=False, *args, **kwargs):
-        # Check if the project is converted to an RSR Impact project
+        # Strip title of any trailing or leading spaces
         if self.title:
             self.title = self.title.strip()
 
+        # Strip subtitle of any trailing or leading spaces
         if self.subtitle:
             self.subtitle = self.subtitle.strip()
 
+        # Strip IATI ID of any trailing or leading spaces
+        if self.iati_activity_id:
+            self.iati_activity_id = self.iati_activity_id.strip()
+
+        # Check if project should be converted to an Impact project
         if not last_updated:
             if self.pk:
+                # Existing project, only convert if original project was not an Impact project
                 orig = get_model('rsr', 'project').objects.get(pk=self.pk)
                 if self.is_impact_project and not orig.is_impact_project:
                     self.convert_to_impact_project()
             elif self.is_impact_project:
+                # New project, so convert to Impact project
                 self.convert_to_impact_project()
 
         super(Project, self).save(*args, **kwargs)
@@ -361,6 +369,10 @@ def clean(self):
                                               u'time than end date (actual).')}
             )
 
+        # In order for the IATI activity IDs not be unique, we set them to None when they're empty
+        if not self.iati_activity_id:
+            self.iati_activity_id = None
+
     @models.permalink
     def get_absolute_url(self):
         return ('project-main', (), {'project_id': self.pk})


Test patch:
Repository: akvo/akvo-rsr

Issue:
Project editor crash for conditions without a text
## Test plan
1. Open the project editor, and click the 'Show advanced IATI fields' button
2. In the results and indicators section, add a project condition with only a type (no condition text)
3. Save
4. Refresh the page
5. **RESULT:** No error should be shown and the condition should state "No condition specified"
## Issue description

Hasn't happened on Live yet, but it did on Test. See http://sentry.support.akvo-ops.org/rsr/test/group/690/.



Discussion:

Resolving patch:
diff --git a/akvo/rsr/models/project_condition.py b/akvo/rsr/models/project_condition.py
--- a/akvo/rsr/models/project_condition.py
+++ b/akvo/rsr/models/project_condition.py
@@ -23,7 +23,7 @@ class ProjectCondition(models.Model):
                              choices=codelist_choices(CONDITION_TYPE))
 
     def __unicode__(self):
-        return self.text if self.text else _(u'No condition specified')
+        return self.text if self.text else u'%s' % _(u'No condition specified')
 
     def iati_type(self):
         return codelist_value(ConditionType, self, 'type')


Test patch:
Repository: akvo/akvo-rsr

Issue:
User admin queryset filtering shows an error
## Test plan

GIVEN the User admin list (`/en/admin/rsr/user/`)
AND the user is marked as User.is_staff to access the admin site

WHEN logged in as a superuser or RSR admin
THEN all users should be shown in the list

WHEN logged in as an organisation admin or user manager
THEN all users of all organisations that the user manages should be shown in the list

WHEN logged in as a project editor or normal user
THEN only the user that is logged in should be shown in the list
## Issue description

See http://sentry.support.akvo-ops.org/rsr/live/group/724/



Discussion:

Resolving patch:
diff --git a/akvo/rsr/admin.py b/akvo/rsr/admin.py
--- a/akvo/rsr/admin.py
+++ b/akvo/rsr/admin.py
@@ -906,14 +906,24 @@ def get_readonly_fields(self, request, obj=None):
             return ['is_admin', 'is_support', 'is_superuser', 'last_login', 'date_joined']
 
     def get_queryset(self, request):
+        # Superusers or RSR Admins can see all users
         if request.user.is_superuser or request.user.is_admin:
             return super(UserAdmin, self).get_queryset(request)
 
-        qs = get_user_model().objects.filter(pk__in=[request.user.pk, ])
-        for employment in request.user.employers.approved():
-            if employment.group in Group.objects.filter(name__in=['Admins', 'User Managers']):
-                qs = qs.distinct() | employment.organisation.all_users().distinct()
-        return qs.distinct()
+        else:
+            # Retrieve the organisations of which the user is an approved Admin or User manager
+            user_manager_groups = Group.objects.filter(name__in=['Admins', 'User Managers'])
+            managing_orgs = request.user.organisations.filter(
+                employees__user__pk=request.user.pk,
+                employees__is_approved=True,
+                employees__group__in=user_manager_groups
+            )
+            if managing_orgs:
+                # Return all users of the organisations that the user manages
+                return managing_orgs.users()
+            else:
+                # User doesn't manage any organisation, only return the user itself
+                return get_user_model().objects.filter(pk=request.user.pk)
 
 admin.site.register(get_user_model(), UserAdmin)
 
diff --git a/akvo/rsr/models/organisation.py b/akvo/rsr/models/organisation.py
--- a/akvo/rsr/models/organisation.py
+++ b/akvo/rsr/models/organisation.py
@@ -324,9 +324,7 @@ def website(self):
 
     def all_users(self):
         "returns a queryset of all users belonging to the organisation"
-        from .user import User
-        #return User.objects.filter(employers__organisation=self).distinct()
-        return self.employees.all()
+        return self.users.all()
 
     def published_projects(self):
         "returns a queryset with published projects that has self as any kind of partner"


Test patch:
Repository: akvo/akvo-rsr

Issue:
Project list widget throws an internal server error
## Test plan

GIVEN the 'Grab a widget' page

WHEN a project has no partners
THEN the project list and project map options should not be available

WHEN a project has partners
THEN all widgets should be available and not display an error
## Issue description

The project list widget gives an internal server error. And the map widget as well: http://sentry.support.akvo-ops.org/rsr/live/group/727/. This is due to the fact that they don't have a reporting organisation and the map and project listing widgets expect an organisation as an input.

The reporting organisation here should be changed to the project's primary organisation, and we should create a 404 exception when the project has no partners at all, just in case.



Discussion:

Resolving patch:
diff --git a/akvo/rsr/views/widgets.py b/akvo/rsr/views/widgets.py
--- a/akvo/rsr/views/widgets.py
+++ b/akvo/rsr/views/widgets.py
@@ -86,7 +86,7 @@ class ProjectListView(BaseWidgetView):
     def get_context_data(self, **kwargs):
         context = super(ProjectListView, self).get_context_data(**kwargs)
         order_by = self.request.GET.get('order_by', 'title')
-        org_id = self.request.GET.get('organisation_id', '0')
+        org_id = self.request.GET.get('organisation_id')
         organisation = get_object_or_404(Organisation, pk=org_id)
         projects = Project.objects.select_related(
             'publishingstatus__status',
@@ -125,7 +125,7 @@ def get_context_data(self, **kwargs):
         context['widthpx'] = str(context['width']) + 'px'
         context['style'] = self.request.GET.get('style', 'dark')
         context['state'] = self.request.GET.get('state', 'dynamic')
-        org_id = self.request.GET.get('organisation_id', '0')
+        org_id = self.request.GET.get('organisation_id')
         org = get_object_or_404(Organisation, pk=org_id)
         context['projects'] = org.published_projects()
         return context


Test patch:
Repository: akvo/akvo-rsr

Issue:
Tests fail because of migration error
## Test plan

No testing needed. Unit tests should run again on Test env.
## Issue description

The DB tests fail because migration 0040 uses the Project model instead of apps.get_model(). This results in a field being referred to that doesn't currently exist in the actual DB.

Fix by reverting to old code that didn't use any model methods. Live and learn :wink: 



Discussion:

Resolving patch:
diff --git a/akvo/rsr/migrations/0040_auto_20151111_1300.py b/akvo/rsr/migrations/0040_auto_20151111_1300.py
--- a/akvo/rsr/migrations/0040_auto_20151111_1300.py
+++ b/akvo/rsr/migrations/0040_auto_20151111_1300.py
@@ -7,9 +7,30 @@
 from ..models.project import Project
 
 def add_primary_organisations(apps, schema_editor):
+    Project = apps.get_model("rsr", "Project")
 
     for project in Project.objects.all():
-        project.primary_organisation = project.find_primary_organisation()
+        primary_organisation = None
+
+        # Pick the partner that can publish the project first
+        if project.partners.filter(can_create_projects=True):
+            primary_organisation = project.partners.filter(can_create_projects=True)[0]
+
+        # Otherwise, if we have a reporting-org then we choose that
+        elif project.partnerships.filter(iati_organisation_role=101):
+            primary_organisation = project.partnerships.filter(
+                iati_organisation_role=101)[0].organisation
+
+        # Otherwise, grab the first accountable partner we find
+        elif project.partnerships.filter(iati_organisation_role=2):
+            primary_organisation = project.partnerships.filter(
+                iati_organisation_role=2)[0].organisation
+
+        # Panic mode: grab the first partner we find
+        elif project.partners.all():
+            primary_organisation = project.partners.all()[0]
+
+        project.primary_organisation = primary_organisation
         project.save(update_fields=['primary_organisation'])
 
 


Test patch:
Repository: akvo/akvo-rsr

Issue:
Project up REST resource broken
## Test plan

The `/rest/v1/project_up/` resource should not give an error.
## Sentry

See http://sentry.support.akvo-ops.org/rsr/live/group/743/



Discussion:

Resolving patch:
diff --git a/akvo/rest/views/project.py b/akvo/rest/views/project.py
--- a/akvo/rest/views/project.py
+++ b/akvo/rest/views/project.py
@@ -136,7 +136,7 @@ class ProjectUpViewSet(ProjectViewSet):
         'partners',
     ).prefetch_related(
         'publishingstatus',
-        'updates',
+        'project_updates',
     )
     serializer_class = ProjectUpSerializer
     paginate_by_param = 'limit'


Test patch:
Repository: akvo/akvo-rsr

Issue:
Organisations list gives timeout
## Test plan

The organisations list should not give a timeout. Since this only happened on Live, it is hard to debug.
## Sentry

See http://sentry.support.akvo-ops.org/rsr/live/group/742/



Discussion:

Resolving patch:
diff --git a/akvo/rsr/views/organisation.py b/akvo/rsr/views/organisation.py
--- a/akvo/rsr/views/organisation.py
+++ b/akvo/rsr/views/organisation.py
@@ -77,10 +77,6 @@ def directory(request):
     # Get related objects of page at once
     page.object_list = page.object_list.select_related(
         'primary_location__country',
-    ).annotate(
-        num_employees=Count('employees', distinct=True),
-        num_projects=Count('projects', distinct=True),
-        num_updates=Count('projects__project_updates', distinct=True),
     )
 
     return render(request, 'organisation_directory.html', {


Test patch:
Repository: akvo/akvo-rsr

Issue:
Public projects filter in REST API not working correctly
## Test plan

All projects (and other objects) should be displayed in the REST API.
## Issue description

As a quick fix, just display all projects (public and private) in the API.



Discussion:

Resolving patch:
diff --git a/akvo/rest/viewsets.py b/akvo/rest/viewsets.py
--- a/akvo/rest/viewsets.py
+++ b/akvo/rest/viewsets.py
@@ -23,11 +23,3 @@ class BaseRSRViewSet(viewsets.ModelViewSet):
     permission_classes = (DjangoObjectPermissions, )
     filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter, )
     ordering_fields = '__all__'
-
-    def get_queryset(self):
-        """Filter out any private projects."""
-        for related_obj in self.queryset.model._meta.get_all_related_objects():
-            if related_obj.model == Project:
-                self.queryset = self.queryset.filter(project__is_public=True)
-                break
-        return super(BaseRSRViewSet, self).get_queryset()


Test patch:
Repository: akvo/akvo-rsr

Issue:
Reporting org added as participating org in IATI export
## Test plan

The reporting partner and sponsor partners should not be added to an IATI file as a _<participating_org>_ during the IATI export.
1. Go to a project page of a project with a reporting organisation
2. Click the IATI link in the 'Export data' section in the project footer
3. In the resulting IATI file, the reporting partner should be named in the _<reporting_org>_ tag, but not as one of the _<participating_org>_.
## Issue description

The reporting org is also added as a participating org without a role in the IATI export. All participating organisations should have a role according to IATI, so this makes the generated IATI file invalid.



Discussion:

Resolving patch:
diff --git a/akvo/iati/exports/elements/participating_org.py b/akvo/iati/exports/elements/participating_org.py
--- a/akvo/iati/exports/elements/participating_org.py
+++ b/akvo/iati/exports/elements/participating_org.py
@@ -6,13 +6,6 @@
 
 from lxml import etree
 
-TYPE_TO_CODE = {
-    'funding': '1',
-    'support': '2',
-    'sponsor': '3',
-    'field': '4',
-}
-
 
 def participating_org(project):
     """
@@ -26,25 +19,27 @@ def participating_org(project):
     from akvo.rsr.models import Partnership
 
     for partnership in project.partnerships.all():
-        org = partnership.organisation
-        element = etree.Element("participating-org")
+        # Don't include reporting orgs or sponsor partners
+        if partnership.iati_organisation_role in Partnership.IATI_ROLE_LIST[:4]:
+            org = partnership.organisation
+            element = etree.Element("participating-org")
+
+            if org.iati_org_id:
+                element.attrib['ref'] = org.iati_org_id
 
-        if org.iati_org_id:
-            element.attrib['ref'] = org.iati_org_id
+            if org.new_organisation_type:
+                element.attrib['type'] = str(org.new_organisation_type)
 
-        if org.new_organisation_type:
-            element.attrib['type'] = str(org.new_organisation_type)
-        # don't include old akvo sponsor partner value when checking
-        if partnership.iati_organisation_role in Partnership.IATI_ROLE_LIST[:-1]:
-            element.attrib['role'] = str(partnership.iati_organisation_role)
+            if partnership.iati_organisation_role:
+                element.attrib['role'] = str(partnership.iati_organisation_role)
 
-        narrative_element = etree.SubElement(element, "narrative")
+            narrative_element = etree.SubElement(element, "narrative")
 
-        if org.long_name:
-            narrative_element.text = org.long_name
-        elif org.name:
-            narrative_element.text = org.name
+            if org.long_name:
+                narrative_element.text = org.long_name
+            elif org.name:
+                narrative_element.text = org.name
 
-        partnership_elements.append(element)
+            partnership_elements.append(element)
 
     return partnership_elements


Test patch:
Repository: akvo/akvo-rsr

Issue:
MyRSR - search short and longname 
## Test plan

GIVEN the My Details page of MyRSR

WHEN trying to connect to an employer
THEN the organisation field should be red IF no organisation is not filled in
AND the organisation field should be red IF the user is already connect to the selected organisation
AND the form / button should be disabled IF the user selected a correct organisation

WHEN the request to join an employer is successful
THEN the organisation should be added to the organisations list above, with (Not approved) added

WHEN the user clicks on the red cross behind an organisation
THEN the loading icon should replace the red cross
AND the organisation should disappear IF the employment is deleted successfully
## Issue description

In MyRSR > My details > My organisations box:
When linking to employer: the search field only searches on short name. I would expect it also searches on an organisation's long name. E.g if a user wants to connect to an organisation and searches for 'Health Alive Foundation', nothing pops up. Instead I need to know upfront that I need to search for HAF, otherwise I can't find the organsation.



Discussion:

Resolving patch:
diff --git a/akvo/rest/views/user.py b/akvo/rest/views/user.py
--- a/akvo/rest/views/user.py
+++ b/akvo/rest/views/user.py
@@ -101,6 +101,7 @@ def request_organisation(request, pk=None):
 
         serializer.data['country_full'] = CountrySerializer(country).data
         serializer.data['organisation_full'] = OrganisationSerializer(organisation).data
+        serializer.data['id'] = employment.pk
 
         return Response(serializer.data)
     else:
diff --git a/akvo/rsr/models/__init__.py b/akvo/rsr/models/__init__.py
--- a/akvo/rsr/models/__init__.py
+++ b/akvo/rsr/models/__init__.py
@@ -291,7 +291,7 @@
 
 rules.add_perm('rsr.add_employment', is_rsr_admin)
 rules.add_perm('rsr.change_employment', is_rsr_admin | is_org_admin | is_org_user_manager)
-rules.add_perm('rsr.delete_employment', is_rsr_admin | is_org_admin | is_org_user_manager)
+rules.add_perm('rsr.delete_employment', is_rsr_admin | is_org_admin | is_org_user_manager | is_self)
 
 rules.add_perm('rsr.iati_management', is_rsr_admin | is_org_admin | is_org_project_editor)
 
diff --git a/akvo/rsr/permissions.py b/akvo/rsr/permissions.py
--- a/akvo/rsr/permissions.py
+++ b/akvo/rsr/permissions.py
@@ -181,4 +181,6 @@ def is_self(user, obj):
         return True
     if isinstance(obj, get_user_model()) and obj == user:
         return True
+    if isinstance(obj, Employment) and obj.user == user:
+        return True
     return False


Test patch:
Repository: akvo/akvo-rsr

Issue:
Multiple reporting partners
## Test plan

GIVEN a project with multiple reporting partners
WHEN accessing the project page
THEN the project page should be shown instead of an error

_Note; This is hard to test, unless you have direct access to the database_
## Issue description

It shouldn't happen, but it still does: multiple reporting partners for a project. Currently RSR crashed in these cases, see http://sentry.support.akvo-ops.org/rsr/live/group/752/. We should catch this, just to be sure.



Discussion:

Resolving patch:
diff --git a/akvo/rsr/models/project.py b/akvo/rsr/models/project.py
--- a/akvo/rsr/models/project.py
+++ b/akvo/rsr/models/project.py
@@ -9,7 +9,7 @@
 from decimal import Decimal, InvalidOperation
 
 from django.conf import settings
-from django.core.exceptions import ValidationError, ObjectDoesNotExist
+from django.core.exceptions import ValidationError, ObjectDoesNotExist, MultipleObjectsReturned
 from django.core.mail import send_mail
 from django.core.validators import MaxValueValidator, MinValueValidator
 from django.db import models
@@ -554,6 +554,18 @@ def reporting_partner(self):
                 iati_organisation_role=Partnership.IATI_REPORTING_ORGANISATION)
         except ObjectDoesNotExist:
             return None
+        except MultipleObjectsReturned:
+            # A project with multiple reporting organisations should not happen, but in practice
+            # it sometimes does unfortunately. In these cases we check if there's one "primary
+            # reporter" and return that. If not, we return the first reporting organisation.
+            primary_reporters = self.partnerships.filter(
+                iati_organisation_role=Partnership.IATI_REPORTING_ORGANISATION).exclude(
+                    is_secondary_reporter=True)
+            if primary_reporters.count() == 1:
+                return primary_reporters[0]
+            else:
+                return self.partnerships.filter(
+                    iati_organisation_role=Partnership.IATI_REPORTING_ORGANISATION)[0]
 
     @property
     def reporting_org(self):


Test patch:
Repository: akvo/akvo-rsr

Issue:
Project update endpoint gives internal server error
See `http://rsr.akvo.org/rest/v1/project_update/`



Discussion:

Resolving patch:
diff --git a/akvo/rest/views/project_update.py b/akvo/rest/views/project_update.py
--- a/akvo/rest/views/project_update.py
+++ b/akvo/rest/views/project_update.py
@@ -23,10 +23,8 @@ class ProjectUpdateViewSet(PublicProjectViewSet):
     serializer_class = ProjectUpdateSerializer
     filter_fields = {
         'project': ['exact', ],
-        'indicator_period': ['exact', ],
         'user': ['exact', ],
         'uuid': ['exact', 'icontains', ],
-        'period_update': ['exact', 'gt', 'gte', 'lt', 'lte', ],
     }
 
     paginate_by_param = 'limit'
@@ -90,10 +88,8 @@ class ProjectUpdateExtraViewSet(PublicProjectViewSet):
     serializer_class = ProjectUpdateExtraSerializer
     filter_fields = {
         'project': ['exact', ],
-        'indicator_period': ['exact', ],
         'user': ['exact', ],
         'uuid': ['exact', 'icontains', ],
-        'period_update': ['exact', 'gt', 'gte', 'lt', 'lte', ],
         # These filters only accept a date, not a datetime
         # 'created_at': ['exact', 'gt', 'gte', 'lt', 'lte', ],
         # 'last_modified_at': ['exact', 'gt', 'gte', 'lt', 'lte', ],


Test patch:
Repository: akvo/akvo-rsr

Issue:
Project update admin gives internal server error
See http://sentry.support.akvo-ops.org/rsr/live/group/784/



Discussion:

Resolving patch:
diff --git a/akvo/rsr/admin.py b/akvo/rsr/admin.py
--- a/akvo/rsr/admin.py
+++ b/akvo/rsr/admin.py
@@ -955,9 +955,6 @@ class ProjectUpdateAdmin(TimestampsAdminDisplayMixin, AdminVideoMixin, admin.Mod
             'fields': ('photo', 'photo_caption', 'photo_credit', 'video', 'video_caption',
                        'video_credit',),
         }),
-        (_(u'Results'), {
-            'fields': ('indicator_period', 'period_update',),
-        }),
     )
     # Methods overridden from ModelAdmin (django/contrib/admin/options.py)
 


Test patch: