Repository: akvo/akvo-rsr

Issue:
Copy update text to actual value comment field
When placing an update in the results framework, the text of the (latest) update should be copied to the `actual_comment` field of the indicator period.



Discussion:
A bit of context:

Currently, the IATI field 'Actual Value comment' (actual_comment) is not available for input through My RSR - My results. Instead, there is a field 'Value Description' there. If a user inputs comment for a chosen indicator value in 'Value Description', it does not update actual_comment. Since these two fields have similar purpose, user input in 'Value Description' should be defaulted in 'Actual Value comment' (actual_comment). This way, it can be further used in IATI reporting.

Hi @punchagan , I'll try to answer your questions:

**Question:** The requirement states that the text of the latest update should be copied to the actual_comment field of the indicator period. Not sure if copy here means, an overwrite of the older text or an append to the existing text.

**Answer:** There will be no text in the actual_comment before copying as it was not made available for user input through My RSR - My results. So actual_comment should be defaulted from 'Value Description' field in My Results

**Question:** Results can have child results, and Indicators for these results therefore have corresponding children.  Parent Indicator values can get aggregated from child Indicator values.  But, this doesn't happen with comments.  So, I presume this behavior shouldn't change and the actual_comment of only the Indicator Period should get updated without any changes to any of its parents.

**Answer:** Yes, you're right. Only the actual_comment of the corresponding Indicator Period should get updated. 

> Question: The requirement states that the text of the latest update should be copied to the actual_comment field of the indicator period. Not sure if copy here means, an overwrite of the older text or an append to the existing text.
> 
> Answer: There will be no text in the actual_comment before copying as it was not made available for user input through My RSR - My results. So actual_comment should be defaulted from 'Value Description' field in My Results

Once the functionality of copying the text from an update to the Indicator Period is added, there will be text in the `actual_comment` field of the Indicator Period.  (Even before, text could be added when the Indicator Period was created from the Project Editor). 
![mon sep 12 16 43 26 ist 2016](https://cloud.githubusercontent.com/assets/315678/18433984/2764ecf0-7908-11e6-9ecb-1fd9c896db38.jpg)

Once the update (with the text `More Amazing things happened`) is approved, should the original text `Something amazing happened` be appended to or overwritten? 


Resolving patch:
diff --git a/akvo/rsr/models/indicator.py b/akvo/rsr/models/indicator.py
--- a/akvo/rsr/models/indicator.py
+++ b/akvo/rsr/models/indicator.py
@@ -511,6 +511,29 @@ def recalculate_children(self, save=True):
 
         return new_value
 
+    def update_actual_comment(self, save=True):
+        """
+        Set the actual comment to the text of the latest approved update.
+
+        :param save; Boolean, save period if True
+        :return Actual comment of period
+        """
+
+        approved_updates = self.data.filter(status=IndicatorPeriodData.STATUS_APPROVED_CODE)
+        update_texts = [
+            '{}: {}'.format(update.last_modified_at.strftime('%d-%m-%Y'), update.text)
+            for update in approved_updates.order_by('-created_at')
+        ]
+        actual_comment = ' | '.join(update_texts)
+        if len(actual_comment) >= 2000:  # max_size
+            actual_comment = '{} ...'.format(actual_comment[:1995])
+
+        self.actual_comment = actual_comment
+        if save:
+            self.save()
+
+        return self.actual_comment
+
     def is_calculated(self):
         """
         When a period has got indicator updates, we consider the actual value to be a
@@ -778,6 +801,7 @@ def save(self, recalculate=True, *args, **kwargs):
         # In case the status is approved, recalculate the period
         if recalculate and self.status == self.STATUS_APPROVED_CODE:
             self.period.recalculate_period()
+            self.period.update_actual_comment()
 
     def delete(self, *args, **kwargs):
         old_status = self.status


Test patch: