Repository: akvo/akvo-rsr

Issue:
IATI export error when result has no quantitative indicators
When running the IATI export, a result that has only qualitative indicators is reported as an error.

This seems to be a bug introduced when we started including qualitative indicators in the export, but didn't change the validation to allow for qualitative-only results.


Discussion:

Resolving patch:
diff --git a/akvo/iati/checks/fields/results.py b/akvo/iati/checks/fields/results.py
--- a/akvo/iati/checks/fields/results.py
+++ b/akvo/iati/checks/fields/results.py
@@ -4,7 +4,7 @@
 # See more details in the license.txt file located at the root folder of the Akvo RSR module.
 # For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.
 
-from akvo.rsr.models.result.utils import QUANTITATIVE
+from akvo.rsr.models.result.utils import QUANTITATIVE, QUALITATIVE
 
 DGIS_VALIDATION_SET_NAME = u"DGIS IATI"
 
@@ -28,14 +28,14 @@ def results(project):
             all_checks_passed = False
             checks.append((u'error', u'result (id: %s) has no title specified' % str(result.pk)))
 
-        if not result.indicators.filter(type=QUANTITATIVE):
+        if not result.indicators.exists():
             all_checks_passed = False
             checks.append(
-                (u'error', u'result (id: %s) has no quantitative indicator(s)' % str(result.pk))
+                (u'error', u'result (id: %s) has no indicator(s)' % str(result.pk))
             )
 
-        for indicator in result.indicators.filter(type=QUANTITATIVE):
-            if not indicator.measure:
+        for indicator in result.indicators.all():
+            if indicator.type == QUANTITATIVE and not indicator.measure:
                 all_checks_passed = False
                 checks.append((u'error', u'indicator (id: %s) has no measure specified' %
                                str(indicator.pk)))
@@ -101,7 +101,7 @@ def results(project):
                     checks.append((u'error', u'indicator period (id: %s) has a start date '
                                              u'later than the end date' % str(period.pk)))
 
-                if not period.target_value:
+                if indicator.type == QUANTITATIVE and not period.target_value:
                     if DGIS_PROJECT:
                         all_checks_passed = False
                         checks.append((u'warning', u'indicator period (id: %s) has no target value '
@@ -115,7 +115,7 @@ def results(project):
                                                  u'location(s) or target dimension(s)' %
                                        str(period.pk)))
 
-                if not period.actual_value:
+                if indicator.type == QUANTITATIVE and not period.actual_value:
                     if DGIS_PROJECT:
                         all_checks_passed = False
                         checks.append((u'warning', u'indicator period (id: %s) has no actual value '


Test patch:
diff --git a/akvo/rsr/tests/iati_checks/test_iati_checks_fields_results.py b/akvo/rsr/tests/iati_checks/test_iati_checks_fields_results.py
--- a/akvo/rsr/tests/iati_checks/test_iati_checks_fields_results.py
+++ b/akvo/rsr/tests/iati_checks/test_iati_checks_fields_results.py
@@ -15,7 +15,7 @@
 from akvo.rsr.models import (
     Project, Result, Indicator, IndicatorPeriod, ProjectEditorValidationSet, IndicatorReference
 )
-from akvo.rsr.models.result.utils import QUANTITATIVE
+from akvo.rsr.models.result.utils import QUANTITATIVE, QUALITATIVE
 
 
 class IatiChecksFieldsReultsTestCase(TestCase):
@@ -52,6 +52,25 @@ def test_iati_checks_fields_results_result_and_indicator_pass(self):
         self.assertEquals(len(checks), 1)
         self.assertIn(u'has valid result(s)', checks[0][1])
 
+    def test_iati_results_checks_pass_with_qualitative_indicator_only(self):
+        # Given
+        Indicator.objects.create(
+            result=self.result,
+            type=QUALITATIVE,
+            title="Title",
+            description="Description",
+            baseline_value="4711",
+            baseline_year=2017,
+        )
+
+        # When
+        all_checks_passed, checks = results_checks(self.project)
+
+        # Then
+        self.assertTrue(all_checks_passed)
+        self.assertEquals(len(checks), 1)
+        self.assertIn(u'has valid result(s)', checks[0][1])
+
     def test_iati_checks_fields_results_result_errors(self):
         # When
         self.result.title = ''
@@ -64,7 +83,7 @@ def test_iati_checks_fields_results_result_errors(self):
         self.assertEquals(len(checks), 3)
         self.assertIn(u'has no type specified', checks[0][1])
         self.assertIn(u'has no title specified', checks[1][1])
-        self.assertIn(u'has no quantitative indicator', checks[2][1])
+        self.assertIn(u'has no indicator', checks[2][1])
 
     def test_iati_checks_fields_results_indicator_error(self):
         # Given an indicator missing title, measure and baseline year and value