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

Issue:
Akvo Pages with hostnames in uppercase does not work properly
## Test plan
1. Go to 'old' RSR admin: `/en/admin/rsr/partnersite/add/`
2. Add an Akvo Page with capitals in the hostname
3. Save
4. The hostname should be all lowercase
## Issue description

If changed to lower case it does. Since hostnames are case insensitive we should make sure that works properly.



Discussion:
Middleware tests should be extended to include this https://github.com/akvo/akvo-rsr/blob/develop/akvo/rsr/tests/test_middleware.py


Resolving patch:
diff --git a/akvo/rsr/models/partner_site.py b/akvo/rsr/models/partner_site.py
--- a/akvo/rsr/models/partner_site.py
+++ b/akvo/rsr/models/partner_site.py
@@ -161,6 +161,12 @@ def __unicode__(self):
         """Unicode representation."""
         return _(u'Akvo page for {}').format(self.organisation.name)
 
+    def save(self, *args, **kwargs):
+        if self.hostname:
+            self.hostname = self.hostname.lower()
+
+        super(PartnerSite, self).save(*args, **kwargs)
+
     @property
     def logo(self):
         """Return logo."""


Test patch:
Repository: akvo/akvo-rsr

Issue:
Small results framework bugs
## Test plan

No test plan needed. Part of #1772 and #1773.
## Issue description

File "akvo/rsr/views/project.py", line 341, in main
    'project_admin': request.user.is_superuser or request.user.is_admin or True in ...

In addition: project page crashes when no accordion.



Discussion:

Resolving patch:
diff --git a/akvo/rsr/views/project.py b/akvo/rsr/views/project.py
--- a/akvo/rsr/views/project.py
+++ b/akvo/rsr/views/project.py
@@ -304,9 +304,18 @@ def main(request, project_id):
     project = get_object_or_404(Project, pk=project_id)
 
     # Non-editors are not allowed to view unpublished projects
-    if not project.is_published() and not request.user.has_perm('rsr.change_project', project):
+    if not project.is_published() and not request.user.is_anonymous() and \
+            not request.user.has_perm('rsr.change_project', project):
         raise PermissionDenied
 
+    # Permissions: project admin
+    if not request.user.is_anonymous() and (
+            request.user.is_superuser or request.user.is_admin or
+            True in [request.user.admin_of(partner) for partner in project.partners.all()]):
+        project_admin = True
+    else:
+        project_admin = False
+
     # Updates
     updates = project.project_updates.select_related('user').order_by('-created_at')
     narrative_updates = updates.exclude(indicator_period__isnull=False)
@@ -338,9 +347,7 @@ def main(request, project_id):
         'partners': partner_types,
         'pledged': project.get_pledged(),
         'project': project,
-        'project_admin': request.user.is_superuser or request.user.is_admin or True in [
-            request.user.admin_of(partner) for partner in project.partners.all()
-        ],
+        'project_admin': project_admin,
         'reporting_org': rep_org_info,
         'updates': narrative_updates,
         'update_timeout': settings.PROJECT_UPDATE_TIMEOUT,


Test patch:
Repository: akvo/akvo-rsr

Issue:
IATI Identifier shows 'None' when empty
## Test plan
1. Go to the project editor
2. Remove the value for "IATI Identifier" (section 1 of the project editor)
3. Save section 1
4. No error should be shown
5. Reload page
6. The "IATI Identifier" field should be empty, and not state `None`
## Issue description

Two bugs in the project editor concerning the IATI Identifier:
1. 'None' is displayed when the value is actually empty.
2. Storing an empty IATI Identifier states that the IATI Identifier already exists.



Discussion:

Resolving patch:
diff --git a/akvo/rest/views/project_editor.py b/akvo/rest/views/project_editor.py
--- a/akvo/rest/views/project_editor.py
+++ b/akvo/rest/views/project_editor.py
@@ -31,7 +31,7 @@
 SECTION_ONE_FIELDS = (
     ('title', 'projectTitle', 'text'),
     ('subtitle', 'projectSubTitle', 'text'),
-    ('iati_activity_id', 'iatiId', 'text'),
+    ('iati_activity_id', 'iatiId', 'none'),
     ('status', 'projectStatus', 'text'),
     ('date_start_planned', 'eventFromPlanned', 'date'),
     ('date_end_planned', 'eventEndPlanned', 'date'),


Test patch:
Repository: akvo/akvo-rsr

Issue:
Small bug in IATI checks
## Test plan
1. Add a project with transactions, budgets and planned disbursements, but without any values or value dates
2. Go to the IATI checks (MyRSR > My IATI > Select reporting organisation of project)
3. Perform IATI checks
4. All objects should give a warning that they don't have a value and value date
## Issue description

An error is shown when a transaction has a value (as opposed to not having a value).
In addition: we need to check for value dates more thoroughly.



Discussion:

Resolving patch:
diff --git a/akvo/iati/checks/versions/v201.py b/akvo/iati/checks/versions/v201.py
--- a/akvo/iati/checks/versions/v201.py
+++ b/akvo/iati/checks/versions/v201.py
@@ -418,6 +418,8 @@ def budgets(self):
             if not budget.currency and not self.project.currency:
                 checks.append((u'error', u'budget (id: %s) has no currency and no default '
                                          u'currency specified' % str(budget.pk)))
+            if not budget.value_date:
+                checks.append((u'error', u'budget (id: %s) has no value date' % str(budget.pk)))
 
         if self.project.budget_items.all() and not checks:
             checks.append((u'success', u'has valid budget items'))
@@ -438,6 +440,9 @@ def planned_disbursements(self):
             if not pd.value:
                 checks.append((u'error', u'planned disbursement (id: %s) has '
                                          u'no amount' % str(pd.pk)))
+            if not pd.value_date:
+                checks.append((u'error', u'planned disbursement (id: %s) has '
+                                         u'no value date' % str(pd.pk)))
             if not pd.period_start:
                 checks.append((u'error', u'planned disbursement (id: %s) has no start '
                                          u'date' % str(pd.pk)))
@@ -473,9 +478,12 @@ def transactions(self):
                 checks.append((u'error', u'transaction (id: %s) has a date in '
                                          u'the future' % str(t.pk)))
 
-            if t.value:
+            if not t.value:
                 checks.append((u'error', u'transaction (id: %s) has no value' % str(t.pk)))
 
+            if not t.value_date:
+                checks.append((u'error', u'transaction (id: %s) has no value date' % str(t.pk)))
+
             if not (t.currency or self.project.currency):
                 checks.append((u'error', u'transaction (id: %s) has no currency and no default '
                                          u'currency specified' % str(t.pk)))


Test patch:
Repository: akvo/akvo-rsr

Issue:
Special characters not shown correctly for updates
## Test plan
1. Add an update with a special character (e.g. "á") and a location
2. View the map on the project main page (under '+ Show map' in the project header)
3. The info window of the update should display the special character correctly
## Issue description

An update with special characters in the title will not show correctly in the maps.



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
@@ -321,6 +321,12 @@ class Meta:
 
     def save(self, last_updated=False, *args, **kwargs):
         # Check if the project is converted to an RSR Impact project
+        if self.title:
+            self.title = self.title.strip()
+
+        if self.subtitle:
+            self.subtitle = self.subtitle.strip()
+
         if not last_updated:
             if self.pk:
                 orig = get_model('rsr', 'project').objects.get(pk=self.pk)
@@ -350,16 +356,6 @@ def clean(self):
                                               u'time than end date (actual).')}
             )
 
-    def save(self, *args, **kwargs):
-        """Strip the title and subtitle from any leading or trailing spaces."""
-        if self.title:
-            self.title = self.title.strip()
-
-        if self.subtitle:
-            self.subtitle = self.subtitle.strip()
-
-        super(Project, self).save(*args, **kwargs)
-
     @models.permalink
     def get_absolute_url(self):
         return ('project-main', (), {'project_id': self.pk})
diff --git a/akvo/rsr/templatetags/maps.py b/akvo/rsr/templatetags/maps.py
--- a/akvo/rsr/templatetags/maps.py
+++ b/akvo/rsr/templatetags/maps.py
@@ -7,6 +7,7 @@
 < http://www.gnu.org/licenses/agpl.html >.
 """
 
+import json
 import logging
 import os
 from django import template
@@ -230,10 +231,10 @@ def project_map(id, width, height, dynamic='dynamic'):
         # Small map, so don't show thumbnail of updates
         thumbnail = ""
 
-        update_locations.append([update_location.latitude,
-                                 update_location.longitude,
-                                 [str(project_update.pk),project_update.title.encode('utf8'), thumbnail, 'project',
-                                  str(id)]])
+        update_locations.append([
+            update_location.latitude, update_location.longitude,
+            [str(project_update.pk), project_update.title, thumbnail, 'project', str(id)]
+        ])
 
     template_context = {
         'map_id': map_id,
@@ -241,8 +242,8 @@ def project_map(id, width, height, dynamic='dynamic'):
         'height': height,
         'marker_icon': PROJECT_MARKER_ICON,
         'update_marker_icon': PROJECT_UPDATE_MARKER_ICON,
-        'locations': locations,
-        'update_locations': update_locations,
+        'locations': json.dumps(locations),
+        'update_locations': json.dumps(update_locations),
         'dynamic': dynamic,
         'infowindows': False,
         'partnersite_widget': False


Test patch:
Repository: akvo/akvo-rsr

Issue:
Unless the correct auth groups exists in the DB myrsr dies.
## Test plan

We could test this by removing one of the groups in the auth.group model. However, this would delete a lot of user's employments on Test or UAT as well.

Might be better to just login as an organisation admin (and not a superuser) with an activated employment to the 'old' RSR admin, e.g. `/en/admin/rsr/project/`, to see if logging in still works.
## Issue description

This part of the code depends on certain data to be in the database. We should probably try to add the data if it's missing - or have a try/catch thing around that code.

https://github.com/akvo/akvo-rsr/blob/feature/rsr_v3/akvo/rsr/models/employment.py#L66

This ties into that RSR is dependent on certain data being present in the db for it to function. This makes things like testing, creating new datasets a bit tricky. We should consider if we can either make sure that data is present or add it. Or alternatively try to program a bit more defensibly.



Discussion:

Resolving patch:
diff --git a/akvo/rsr/models/employment.py b/akvo/rsr/models/employment.py
--- a/akvo/rsr/models/employment.py
+++ b/akvo/rsr/models/employment.py
@@ -8,6 +8,7 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth.models import Group
 from django.contrib.contenttypes.models import ContentType
+from django.core.exceptions import ObjectDoesNotExist
 from django.db import models
 from django.db.models.query import QuerySet as DjangoQuerySet
 from django.forms.models import model_to_dict
@@ -84,14 +85,15 @@ def approve(self, approved_by):
 
     def to_dict(self, org_list):
         country = '' if not self.country else model_to_dict(self.country)
-        # Set groups in right order
 
-        all_groups = [
-            Group.objects.get(name='Users'),
-            Group.objects.get(name='User Managers'),
-            Group.objects.get(name='Project Editors'),
-            Group.objects.get(name='Admins')
-        ]
+        # Set groups in right order
+        all_groups = []
+        auth_group_names = ['Users', 'User Managers', 'Project Editors', 'Admins']
+        for auth_group_name in auth_group_names:
+            try:
+                all_groups.append(Group.objects.get(name=auth_group_name))
+            except ObjectDoesNotExist:
+                continue
 
         user_group = model_to_dict(self.group, fields=['id', 'name']) if self.group else None
         other_groups = [model_to_dict(group, fields=['id', 'name']) for group in all_groups]


Test patch:
Repository: akvo/akvo-rsr

Issue:
Project can only have one reporting organisation
## Test plan
1. Go to project editor and select 2 reporting organisations in section 3
2. _RESULT:_ a validation error should be shown
3. Remove one of the reporting organisations
4. _RESULT:_ the save should be successful
## Issue description

Validation error appears even if there's only one reporting organisation.



Discussion:

Resolving patch:
diff --git a/akvo/rsr/models/partnership.py b/akvo/rsr/models/partnership.py
--- a/akvo/rsr/models/partnership.py
+++ b/akvo/rsr/models/partnership.py
@@ -168,12 +168,13 @@ def __unicode__(self):
 
     def clean(self):
         # Don't allow multiple reporting organisations
-        reporting_orgs = self.project.partnerships.filter(
-            iati_organisation_role=self.IATI_REPORTING_ORGANISATION
-        )
-
-        if reporting_orgs:
-            raise ValidationError(
-                {'iati_organisation_role': u'%s' % _(u'Project can only have one reporting '
-                                                     u'organisation')}
+        if self.iati_organisation_role == self.IATI_REPORTING_ORGANISATION:
+            reporting_orgs = self.project.partnerships.filter(
+                iati_organisation_role=self.IATI_REPORTING_ORGANISATION
             )
+
+            if reporting_orgs.count() > 1:
+                raise ValidationError(
+                    {'iati_organisation_role': u'%s' % _(u'Project can only have one reporting '
+                                                         u'organisation')}
+                )


Test patch:
Repository: akvo/akvo-rsr

Issue:
Calculate updates from baseline, not from actual
## Test plan

There shouldn't be a difference from the original results framework. No specific testing needed.
## Issue description

Currently, the place of the updates on the slider is calculated by going back from the actual. However, this sometimes results in strange behaviour (e.g. the slider being before the baseline). We should calculate starting from the baseline and add up all the previous updates.



Discussion:

Resolving patch:
diff --git a/akvo/rsr/models/project_update.py b/akvo/rsr/models/project_update.py
--- a/akvo/rsr/models/project_update.py
+++ b/akvo/rsr/models/project_update.py
@@ -112,12 +112,19 @@ def save(self, *args, **kwargs):
 
     def delete(self, *args, **kwargs):
         if self.indicator_period and self.period_update:
-            try:
-                self.indicator_period.update_actual_value(
-                    Decimal(self.period_update) * -1
-                )
-            except (InvalidOperation, TypeError):
-                pass
+            # Subsctract the value of the update from the actual value of the indicator period
+            if ProjectUpdate.objects.filter(indicator_period=self.indicator_period).\
+                    exclude(pk=self.pk).exists():
+                try:
+                    self.indicator_period.update_actual_value(
+                        Decimal(self.period_update) * -1
+                    )
+                except (InvalidOperation, TypeError):
+                    pass
+            else:
+                # There's no other updates for this indicator period, remove actual value
+                self.indicator_period.actual_value = ''
+                self.indicator_period.save()
         super(ProjectUpdate, self).delete(*args, **kwargs)
 
     def clean(self):


Test patch:
Repository: akvo/akvo-rsr

Issue:
Aggregation status and Ascending can't be "No"
## Test plan

GIVEN the Aggregation status (Result) and Ascending (Indicator) in section 5 of the project editor (click 'Advanced IATI fields' to see those)
1. Setting the value to "No" should not give an error
2. Setting the value to either nothing, "Yes" or "No" should save correctly (refresh the page to check if the values actually have been stored correctly).
## Issue description

Setting the aggregation status or ascending to "No" in the project editor results in an error.



Discussion:

Resolving patch:
diff --git a/akvo/rest/views/project_editor.py b/akvo/rest/views/project_editor.py
--- a/akvo/rest/views/project_editor.py
+++ b/akvo/rest/views/project_editor.py
@@ -369,7 +369,7 @@ def process_field(obj, form_data, field, errors, changes, form_obj_id='', rel_ob
         orig_data = field_data
 
     elif field[2] == 'none-boolean':
-        field_data = None if orig_data == 'none' else orig_data
+        field_data = True if orig_data == '1' else False if orig_data == '2' else None
 
     elif field[2] == 'none':
         field_data = orig_data if orig_data else None


Test patch:
Repository: akvo/akvo-rsr

Issue:
Only display the first 5 narrative updates on the project summary page
## Test plan

GIVEN the summary page of the project
WHEN a project has more than 5 narrative updates
THEN only the first 5 should be shown on the summary page



Discussion:

Resolving patch:
diff --git a/akvo/rsr/views/project.py b/akvo/rsr/views/project.py
--- a/akvo/rsr/views/project.py
+++ b/akvo/rsr/views/project.py
@@ -344,7 +344,7 @@ def main(request, project_id):
         'pledged': project.get_pledged(),
         'project': project,
         'project_admin': project_admin,
-        'updates': narrative_updates,
+        'updates': narrative_updates[:5] if narrative_updates else None,
         'update_timeout': settings.PROJECT_UPDATE_TIMEOUT,
     }
 


Test patch:
Repository: akvo/akvo-rsr

Issue:
Project does not always have a primary partner
## Test plan

GIVEN the project listing page and project main page
WHEN a project has no partners
THEN no internal server error should be shown, but just no partners

GIVEN the project main page
THEN no 'Financial info' should be shown, since we now have a 'Finance' tab

GIVEN the finance tab on the project main page
WHEN an organisation without a logo is a partner
THEN the 'No logo specified' image should not be bigger than 80x60 pixels
## Description

There are situations in which the project does not have a primary partner. Even though this should be a scenario that doesn't occur very often, we do get errors from it now in Sentry: http://sentry.support.akvo-ops.org/rsr/live/group/711/, http://sentry.support.akvo-ops.org/rsr/live/group/713/.



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
@@ -512,6 +512,14 @@ def reporting_org(self):
         """
         return self.reporting_partner.organisation if self.reporting_partner else None
 
+    @property
+    def publishing_orgs(self):
+        """
+        Returns the organisations that have the right to publish the project. In other words, that
+        have Organisation.can_create_project set to True.
+        """
+        return self.partners.filter(can_create_projects=True)
+
     def set_reporting_org(self, organisation):
         """ Set the reporting-org for the project.
             Currently protests if you try to set another organisation when one is already set.
@@ -860,15 +868,19 @@ def _partners(self, role=None):
 
     @property
     def primary_organisation(self):
-        """ This method tries to return the "managing" partner organisation.
         """
-        # If we have a reporting-org then we choose that
+        This method tries to return the "managing" partner organisation.
+        """
+        # Pick the partner that can publish the project first
+        if self.publishing_orgs:
+            return self.publishing_orgs[0]
+        # Otherwise, if we have a reporting-org then we choose that
         if self.reporting_org:
             return self.reporting_org
-        # otherwise grab the first accountable partner we find
+        # Otherwise, grab the first accountable partner we find
         elif self.support_partners():
             return self.support_partners()[0]
-        # panic mode: grab the first partner we find
+        # Panic mode: grab the first partner we find
         elif self.all_partners():
             return self.all_partners()[0]
         # Uh-oh...
diff --git a/akvo/rsr/templatetags/rsr_utils.py b/akvo/rsr/templatetags/rsr_utils.py
--- a/akvo/rsr/templatetags/rsr_utils.py
+++ b/akvo/rsr/templatetags/rsr_utils.py
@@ -42,6 +42,8 @@ def img(context, obj, width, height, alt):
 
     return {"default_img": default_img,
             "geometry": geometry,
+            "height": height,
+            "width": width,
             "img": img,
             "alt": alt}
 


Test patch:
Repository: akvo/akvo-rsr

Issue:
Error in validation when saving an Organisation
When you add or change an IATI organisation ID in the RSR admin, an AttributeError occurs. The reason for this is a bug in the check for duplicate IATI IDs.



Discussion:

Resolving patch:
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
@@ -191,12 +191,12 @@ def clean(self):
 
         names = Organisation.objects.filter(name__iexact=name)
         long_names = Organisation.objects.filter(long_name__iexact=long_name)
-        ids = Organisation.objects.filter(iati_org_id__iexact=iati_org_id) if iati_org_id else None
+        ids = Organisation.objects.filter(iati_org_id__iexact=iati_org_id)
 
         if self.pk:
             names = names.exclude(pk=self.pk)
             long_names = long_names.exclude(pk=self.pk)
-            ids = ids.exclude(pk=self.pk) if ids else None
+            ids = ids.exclude(pk=self.pk)
 
         if name and names.exists():
             validation_errors['name'] = u'{}: {}'.format(
@@ -208,7 +208,6 @@ def clean(self):
         if long_name and long_names.exists():
             validation_errors['long_name'] = u'{}: {}'.format(
                 _('An Organisation with this long name already exists'), long_name)
-
         elif not long_name:
             # This prevents organisation long names with only spaces
             validation_errors['long_name'] = _(u'Organisation long name may not be blank')


Test patch:
Repository: akvo/akvo-rsr

Issue:
Partnership doesn't always have a role
## Test plan

GIVEN the project main page
WHEN the project has a partnership without a role
THEN no error should be shown, but the **ROLE** of the partnership should be empty
## Description

When a partnership has no role, the report tab of the project main page makes the page crash.

Although this scenario doesn't occur often, it does occur: http://sentry.support.akvo-ops.org/rsr/live/group/709/, http://sentry.support.akvo-ops.org/rsr/live/group/679/.



Discussion:

Resolving patch:
diff --git a/akvo/rsr/models/partnership.py b/akvo/rsr/models/partnership.py
--- a/akvo/rsr/models/partnership.py
+++ b/akvo/rsr/models/partnership.py
@@ -135,7 +135,10 @@ class Partnership(models.Model):
     )
 
     def iati_organisation_role_label(self):
-        return dict(self.IATI_ROLES)[self.iati_organisation_role]
+        if self.iati_organisation_role:
+            return dict(self.IATI_ROLES)[self.iati_organisation_role]
+        else:
+            return None
 
     def iati_role_to_partner_type(self):
         if self.iati_organisation_role:


Test patch: