Repository: e-valuation/EvaP

Issue:
Aggregate reward points redemptions in export per user
When exporting the redemptions of an event, all of them are listed in the Excel export. The redemptions of one user should be aggregated into one line.
Also the number of redemptions on the staff page should be replaced by the number of users who redeemed points for an event.

So when a user redeems 1 point and then 2 points for the same event, the export should only state that 3 points have been redeemed in total.



Discussion:

Resolving patch:
diff --git a/evap/rewards/exporters.py b/evap/rewards/exporters.py
--- a/evap/rewards/exporters.py
+++ b/evap/rewards/exporters.py
@@ -2,8 +2,6 @@
 
 from django.utils.translation import ugettext as _
 
-from operator import attrgetter
-
 from collections import OrderedDict
 from collections import defaultdict
 import datetime
@@ -16,8 +14,8 @@
 
 class ExcelExporter(object):
 
-    def __init__(self, reward_point_redemptions):
-        self.reward_point_redemptions = reward_point_redemptions
+    def __init__(self, redemptions_by_user):
+        self.redemptions_by_user = redemptions_by_user
 
     styles = {
         'default':       xlwt.Style.default_style,
@@ -25,9 +23,8 @@ def __init__(self, reward_point_redemptions):
     }
 
     def export(self, response):
-        redemptions = self.reward_point_redemptions
-        redemptions = sorted(redemptions, key=attrgetter('user_profile.user.last_name', 'user_profile.user.first_name'))
-
+        redemptions_dict = self.redemptions_by_user
+        
         self.workbook = xlwt.Workbook()
         self.sheet = self.workbook.add_sheet(_(u"Redemptions"))
         self.row = 0
@@ -38,11 +35,10 @@ def export(self, response):
         writec(self, _("Email address"), "bold")
         writec(self, _("Number of points"), "bold")
 
-        for redemption in redemptions:
-            user = redemption.user_profile.user
-            writen(self, user.last_name, "default")
-            writec(self, user.first_name, "default")
-            writec(self, user.email, "default")
-            writec(self, redemption.value, "default")
+        for user_profile, value in redemptions_dict.items():
+            writen(self, user_profile.user.last_name, "default")
+            writec(self, user_profile.user.first_name, "default")
+            writec(self, user_profile.user.email, "default")
+            writec(self, value, "default")
 
         self.workbook.save(response)
diff --git a/evap/rewards/models.py b/evap/rewards/models.py
--- a/evap/rewards/models.py
+++ b/evap/rewards/models.py
@@ -1,6 +1,10 @@
 from django.utils.translation import ugettext_lazy as _
 from django.db import models
 
+from collections import OrderedDict
+
+from operator import attrgetter
+
 class RewardPointRedemptionEvent(models.Model):
     name = models.CharField(max_length=1024, verbose_name=_(u"event name"))
     date = models.DateField(verbose_name=_(u"event date"))
@@ -11,6 +15,15 @@ def can_delete(self):
         if RewardPointRedemption.objects.filter(event=self).exists():
             return False
         return True
+    
+    def redemptions_by_user(self):
+        redemptions = self.reward_point_redemptions.order_by('user_profile__user__last_name', 'user_profile__user__first_name')
+        redemptions_dict = OrderedDict()
+        for redemption in redemptions:
+            if not redemption.user_profile in redemptions_dict:
+                redemptions_dict[redemption.user_profile] = 0
+            redemptions_dict[redemption.user_profile] += redemption.value
+        return redemptions_dict
 
 class RewardPointGranting(models.Model):
     user_profile = models.ForeignKey('evaluation.UserProfile', related_name="reward_point_grantings")
diff --git a/evap/rewards/views.py b/evap/rewards/views.py
--- a/evap/rewards/views.py
+++ b/evap/rewards/views.py
@@ -136,7 +136,7 @@ def reward_point_redemption_event_export(request, event_id):
     response = HttpResponse(content_type="application/vnd.ms-excel")
     response["Content-Disposition"] = "attachment; filename=\"%s\"" % filename
 
-    ExcelExporter(event.reward_point_redemptions.all()).export(response)
+    ExcelExporter(event.redemptions_by_user()).export(response)
 
     return response
 


Test patch: