Repository: learningequality/kolibri

Issue:
The coach report shows incorrect data on version 0.5.0beta8
## Summary
The class progress shows 6/24 completed, but on navigating to check the students who have completed , I notice that fewer kids have only completed under the recent tab.

Note:
This is the same server that was updated from 0.4.5 to 0.5.x. This is across all the channels and not specific to any channel.

## System information
 - Version: 0.5.0beta8
 - Operating system: Ubuntu 14.04LTS
 - Browser: Chrome

## How to reproduce
1. As few users master an exercise.
2. Look for the class progress from recent tabs.

## Screenshots
![coach reprot_1](https://user-images.githubusercontent.com/13453618/29614177-dc706cfe-8826-11e7-9e40-adb89a4cf587.png)
![caoch report 2](https://user-images.githubusercontent.com/13453618/29614202-f501dece-8826-11e7-9c84-e8dff816d364.png)
![coach report_3](https://user-images.githubusercontent.com/13453618/29614211-fd03eedc-8826-11e7-8d0a-64a314eefda4.png)
![coach report_4](https://user-images.githubusercontent.com/13453618/29614216-feab0ac2-8826-11e7-804b-7b491e5d1106.png)



Discussion:
Thanks for doing these checks, @harishbalachandran! Seems like perhaps our recency filter is not filtering properly on the aggregate page, but is doing so when generating reports for individuals?

How does the report for pieces of content (6/24 watch) compare to looking at the same piece of content under 'Topics'? If it is the same, then I think it confirms my supposition.
Woops, did not mean to close!
Replicated locally. Investigating.

Resolving patch:
diff --git a/kolibri/plugins/coach/api.py b/kolibri/plugins/coach/api.py
--- a/kolibri/plugins/coach/api.py
+++ b/kolibri/plugins/coach/api.py
@@ -5,6 +5,7 @@
 from django.utils import timezone
 from kolibri.auth.constants import role_kinds
 from kolibri.auth.models import Collection, FacilityUser
+from kolibri.content.content_db_router import default_database_is_attached, get_active_content_database
 from kolibri.content.models import ContentNode
 from kolibri.logger.models import ContentSummaryLog, MasteryLog
 from rest_framework import pagination, permissions, viewsets
@@ -93,10 +94,17 @@ def get_queryset(self):
             datetime_cutoff = timezone.now() - datetime.timedelta(7)
         # Set on the kwargs to pass into the serializer
         self.kwargs['last_active_time'] = datetime_cutoff.isoformat()
-        recent_content_items = ContentSummaryLog.objects.filter_by_topic(query_node).filter(
+        if default_database_is_attached():  # if possible, do a direct join between the content and default databases
+            channel_alias = get_active_content_database()
+            SummaryLogManager = ContentSummaryLog.objects.using(channel_alias)
+        else:
+            SummaryLogManager = ContentSummaryLog.objects
+        recent_content_items = SummaryLogManager.filter_by_topic(query_node).filter(
             Q(progress__gt=0) | Q(masterylogs__in=attempted_mastery_logs),
             user__in=list(get_members_or_user(self.kwargs['collection_kind'], self.kwargs['collection_id'])),
-            end_timestamp__gte=datetime_cutoff).values_list('content_id')
+            end_timestamp__gte=datetime_cutoff).values_list('content_id', flat=True)
+        if not default_database_is_attached():
+            recent_content_items = list(recent_content_items)
         # note from rtibbles:
         # As good as either I or jamalex could come up with to ensure that we only return
         # unique content_id'ed ContentNodes from the coach recent report endpoint.
diff --git a/kolibri/plugins/coach/serializers.py b/kolibri/plugins/coach/serializers.py
--- a/kolibri/plugins/coach/serializers.py
+++ b/kolibri/plugins/coach/serializers.py
@@ -90,7 +90,7 @@ def get_progress_and_last_active(target_nodes, **kwargs):
         .filter(user__in=users, content_id__in=content_ids)
     # Conditionally filter by last active time
     if kwargs.get('last_active_time'):
-        progress_query.filter(end_timestamp__gte=parse(kwargs.get('last_active_time')))
+        progress_query = progress_query.filter(end_timestamp__gte=parse(kwargs.get('last_active_time')))
     # Get an annotated list of dicts of type:
     # {
     #   'content_id': <content_id>,


Test patch:
diff --git a/kolibri/plugins/coach/test/test_coach_api.py b/kolibri/plugins/coach/test/test_coach_api.py
--- a/kolibri/plugins/coach/test/test_coach_api.py
+++ b/kolibri/plugins/coach/test/test_coach_api.py
@@ -6,6 +6,7 @@
 from django.core.urlresolvers import reverse
 from django.db import connections
 from django.test.utils import override_settings
+from django.utils import timezone
 from kolibri.auth.constants import collection_kinds, role_kinds
 from kolibri.content import models as content
 from kolibri.content.content_db_router import set_active_content_database
@@ -98,6 +99,50 @@ def assert_progress(node, progress):
             [{'log_count_complete': 0, 'log_count_total': 1, 'total_progress': 0.5}]
         ])
 
+    def test_contentreport_time_filtering(self):
+
+        # set up data for testing time filtering on content node endpoint
+        facility = Facility.objects.create(name="MyFac")
+        user = FacilityUser.objects.create(username="learner", facility=facility)
+        user.set_password("pass")
+        user.save()
+
+        admin = FacilityUser.objects.create(username="admin", facility=facility)
+        admin.set_password("pass")
+        admin.save()
+
+        Role.objects.create(user=admin, collection=facility, kind=role_kinds.ADMIN)
+        root = content.ContentNode.objects.get(title="root")
+        c2c1 = content.ContentNode.objects.get(title="c2c1")
+        c2c3 = content.ContentNode.objects.get(title="c2c3")
+
+        start_date = datetime.datetime(2000, 1, 1)
+
+        date_1 = timezone.now() - datetime.timedelta(8)
+
+        date_2 = timezone.now() - datetime.timedelta(6)
+
+        for date, node in ((date_1, c2c1), (date_2, c2c3)):
+            ContentSummaryLog.objects.create(
+                user=user,
+                content_id=node.content_id,
+                progress=1.0,
+                kind=node.kind,
+                channel_id=self.the_channel_id,
+                start_timestamp=start_date,
+                end_timestamp=date,
+            )
+
+        # check that only the log less than 7 days ago returns from recent report
+        self.client.login(username="admin", password="pass", facility=facility)
+        response = self.client.get(self._reverse_channel_url("kolibri:coach:recentreport-list", {
+            'content_node_id': root.id,
+            'collection_kind': collection_kinds.FACILITY,
+            'collection_id': facility.id,
+        }))
+        self.assertEqual(len(response.data), 1)
+        self.assertEqual(response.data[0]['pk'], c2c3.pk)
+
     def tearDown(self):
         """
         clean up files/folders created during the test