edx-enterprise-data 10.11.1__py3-none-any.whl → 10.13.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. {edx_enterprise_data-10.11.1.dist-info → edx_enterprise_data-10.13.0.dist-info}/METADATA +1 -1
  2. {edx_enterprise_data-10.11.1.dist-info → edx_enterprise_data-10.13.0.dist-info}/RECORD +22 -19
  3. enterprise_data/__init__.py +1 -1
  4. enterprise_data/admin_analytics/database/filters/__init__.py +2 -0
  5. enterprise_data/admin_analytics/database/filters/fact_completion_admin_dash.py +22 -0
  6. enterprise_data/admin_analytics/database/filters/fact_engagement_admin_dash.py +11 -0
  7. enterprise_data/admin_analytics/database/filters/fact_enrollment_admin_dash.py +2 -42
  8. enterprise_data/admin_analytics/database/filters/mixins.py +84 -0
  9. enterprise_data/admin_analytics/database/queries/fact_engagement_admin_dash.py +13 -18
  10. enterprise_data/admin_analytics/database/queries/fact_enrollment_admin_dash.py +20 -24
  11. enterprise_data/admin_analytics/database/tables/fact_engagement_admin_dash.py +103 -33
  12. enterprise_data/admin_analytics/database/tables/fact_enrollment_admin_dash.py +96 -74
  13. enterprise_data/api/v1/serializers.py +1 -0
  14. enterprise_data/api/v1/views/analytics_completions.py +11 -5
  15. enterprise_data/api/v1/views/analytics_engagements.py +10 -5
  16. enterprise_data/api/v1/views/enterprise_admin.py +2 -1
  17. enterprise_data/management/commands/pre_warm_analytics_cache.py +11 -0
  18. enterprise_data/tests/api/v1/views/test_enterprise_admin.py +5 -4
  19. enterprise_reporting/tests/test_delivery_method.py +1 -1
  20. {edx_enterprise_data-10.11.1.dist-info → edx_enterprise_data-10.13.0.dist-info}/WHEEL +0 -0
  21. {edx_enterprise_data-10.11.1.dist-info → edx_enterprise_data-10.13.0.dist-info}/licenses/LICENSE +0 -0
  22. {edx_enterprise_data-10.11.1.dist-info → edx_enterprise_data-10.13.0.dist-info}/top_level.txt +0 -0
@@ -2,12 +2,15 @@
2
2
  Module for interacting with the fact_enrollment_engagement_day_admin_dash table.
3
3
  """
4
4
  from datetime import date
5
+ from typing import Optional, Tuple
5
6
  from uuid import UUID
6
7
 
7
8
  from enterprise_data.cache.decorators import cache_it
8
9
  from enterprise_data.utils import find_first
9
10
 
11
+ from ..filters import FactEngagementAdminDashFilters
10
12
  from ..queries import FactEngagementAdminDashQueries
13
+ from ..query_filters import QueryFilters
11
14
  from ..utils import run_query
12
15
  from .base import BaseTable
13
16
 
@@ -19,6 +22,43 @@ class FactEngagementAdminDashTable(BaseTable):
19
22
  Class for communicating with the fact_enrollment_engagement_day_admin_dash table.
20
23
  """
21
24
  queries = FactEngagementAdminDashQueries()
25
+ engagement_filters = FactEngagementAdminDashFilters()
26
+
27
+ def __get_common_query_filters_for_engagement(
28
+ self, enterprise_customer_uuid: UUID,
29
+ group_uuid: Optional[UUID],
30
+ start_date: date,
31
+ end_date: date,
32
+ ) -> Tuple[QueryFilters, dict]:
33
+ """
34
+ Utility method to get query filters common in most usages below.
35
+ This will return a tuple containing the query filters list and the dictionary of query parameters that
36
+ will be used in the query.
37
+ It will contain the following query filters.
38
+ 1. enterprise_customer_uuid filter to filter records for an enterprise customer.
39
+ 2. enrollment_date range filter to filter records by enrollment date.
40
+ 3. group_uuid filter to filter records for learners who belong to the given group.
41
+ """
42
+ query_filters = QueryFilters([
43
+ self.engagement_filters.enterprise_customer_uuid_filter('enterprise_customer_uuid'),
44
+ self.engagement_filters.date_range_filter('activity_date', 'start_date', 'end_date'),
45
+ ])
46
+ params = {
47
+ 'enterprise_customer_uuid': enterprise_customer_uuid,
48
+ 'start_date': start_date,
49
+ 'end_date': end_date,
50
+ }
51
+
52
+ response = self.engagement_filters.enterprise_user_query_filter(
53
+ group_uuid,
54
+ enterprise_customer_uuid
55
+ )
56
+ if response is not None:
57
+ enterprise_user_id_in_filter, enterprise_user_id_params = response
58
+ query_filters.append(enterprise_user_id_in_filter)
59
+ params.update(enterprise_user_id_params)
60
+
61
+ return query_filters, params
22
62
 
23
63
  @cache_it()
24
64
  def get_learning_hours_and_daily_sessions(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
@@ -47,7 +87,13 @@ class FactEngagementAdminDashTable(BaseTable):
47
87
  return tuple(results[0])
48
88
 
49
89
  @cache_it()
50
- def get_engagement_count(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
90
+ def get_engagement_count(
91
+ self,
92
+ enterprise_customer_uuid: UUID,
93
+ group_uuid: Optional[UUID],
94
+ start_date: date,
95
+ end_date: date
96
+ ):
51
97
  """
52
98
  Get the total number of engagements for the given enterprise customer.
53
99
 
@@ -59,13 +105,13 @@ class FactEngagementAdminDashTable(BaseTable):
59
105
  Returns:
60
106
  int: The total number of engagements.
61
107
  """
108
+ query_filters, query_filter_params = self.__get_common_query_filters_for_engagement(
109
+ enterprise_customer_uuid, group_uuid, start_date, end_date
110
+ )
111
+
62
112
  results = run_query(
63
- query=self.queries.get_engagement_count_query(),
64
- params={
65
- 'enterprise_customer_uuid': enterprise_customer_uuid,
66
- 'start_date': start_date,
67
- 'end_date': end_date,
68
- }
113
+ query=self.queries.get_engagement_count_query(query_filters),
114
+ params=query_filter_params,
69
115
  )
70
116
  if not results:
71
117
  return 0
@@ -73,13 +119,20 @@ class FactEngagementAdminDashTable(BaseTable):
73
119
 
74
120
  @cache_it()
75
121
  def get_all_engagements(
76
- self, enterprise_customer_uuid: UUID, start_date: date, end_date: date, limit: int, offset: int
122
+ self,
123
+ enterprise_customer_uuid: UUID,
124
+ group_uuid: Optional[UUID],
125
+ start_date: date,
126
+ end_date: date,
127
+ limit: int,
128
+ offset: int
77
129
  ):
78
130
  """
79
131
  Get all engagement data for the given enterprise customer.
80
132
 
81
133
  Arguments:
82
134
  enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
135
+ group_uuid (UUID): The UUID of a group.
83
136
  start_date (date): The start date.
84
137
  end_date (date): The end date.
85
138
  limit (int): The maximum number of records to return.
@@ -88,12 +141,14 @@ class FactEngagementAdminDashTable(BaseTable):
88
141
  Returns:
89
142
  list<dict>: A list of dictionaries containing the engagement data.
90
143
  """
144
+ query_filters, query_filter_params = self.__get_common_query_filters_for_engagement(
145
+ enterprise_customer_uuid, group_uuid, start_date, end_date
146
+ )
147
+
91
148
  return run_query(
92
- query=self.queries.get_all_engagement_query(),
149
+ query=self.queries.get_all_engagement_query(query_filters),
93
150
  params={
94
- 'enterprise_customer_uuid': enterprise_customer_uuid,
95
- 'start_date': start_date,
96
- 'end_date': end_date,
151
+ **query_filter_params,
97
152
  'limit': limit,
98
153
  'offset': offset,
99
154
  },
@@ -101,7 +156,13 @@ class FactEngagementAdminDashTable(BaseTable):
101
156
  )
102
157
 
103
158
  @cache_it()
104
- def get_top_courses_by_engagement(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
159
+ def get_top_courses_by_engagement(
160
+ self,
161
+ enterprise_customer_uuid: UUID,
162
+ group_uuid: Optional[UUID],
163
+ start_date: date,
164
+ end_date: date
165
+ ):
105
166
  """
106
167
  Get the top courses by user engagement for the given enterprise customer.
107
168
 
@@ -113,18 +174,23 @@ class FactEngagementAdminDashTable(BaseTable):
113
174
  Returns:
114
175
  list<dict>: A list of dictionaries containing the course data.
115
176
  """
177
+ query_filters, query_filter_params = self.__get_common_query_filters_for_engagement(
178
+ enterprise_customer_uuid, group_uuid, start_date, end_date
179
+ )
116
180
  return run_query(
117
- query=self.queries.get_top_courses_by_engagement_query(),
118
- params={
119
- 'enterprise_customer_uuid': enterprise_customer_uuid,
120
- 'start_date': start_date,
121
- 'end_date': end_date,
122
- },
181
+ query=self.queries.get_top_courses_by_engagement_query(query_filters),
182
+ params=query_filter_params,
123
183
  as_dict=True,
124
184
  )
125
185
 
126
186
  @cache_it()
127
- def get_top_subjects_by_engagement(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
187
+ def get_top_subjects_by_engagement(
188
+ self,
189
+ enterprise_customer_uuid: UUID,
190
+ group_uuid: Optional[UUID],
191
+ start_date: date,
192
+ end_date: date
193
+ ):
128
194
  """
129
195
  Get the top subjects by user engagement for the given enterprise customer.
130
196
 
@@ -136,18 +202,23 @@ class FactEngagementAdminDashTable(BaseTable):
136
202
  Returns:
137
203
  list<dict>: A list of dictionaries containing the subject data.
138
204
  """
205
+ query_filters, query_filter_params = self.__get_common_query_filters_for_engagement(
206
+ enterprise_customer_uuid, group_uuid, start_date, end_date
207
+ )
139
208
  return run_query(
140
- query=self.queries.get_top_subjects_by_engagement_query(),
141
- params={
142
- 'enterprise_customer_uuid': enterprise_customer_uuid,
143
- 'start_date': start_date,
144
- 'end_date': end_date,
145
- },
209
+ query=self.queries.get_top_subjects_by_engagement_query(query_filters),
210
+ params=query_filter_params,
146
211
  as_dict=True,
147
212
  )
148
213
 
149
214
  @cache_it()
150
- def get_engagement_time_series_data(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
215
+ def get_engagement_time_series_data(
216
+ self,
217
+ enterprise_customer_uuid: UUID,
218
+ group_uuid: Optional[UUID],
219
+ start_date: date,
220
+ end_date: date
221
+ ):
151
222
  """
152
223
  Get the engagement time series data.
153
224
 
@@ -159,13 +230,12 @@ class FactEngagementAdminDashTable(BaseTable):
159
230
  Returns:
160
231
  list<dict>: A list of dictionaries containing the engagement time series data.
161
232
  """
233
+ query_filters, query_filter_params = self.__get_common_query_filters_for_engagement(
234
+ enterprise_customer_uuid, group_uuid, start_date, end_date
235
+ )
162
236
  return run_query(
163
- query=self.queries.get_engagement_time_series_data_query(),
164
- params={
165
- 'enterprise_customer_uuid': enterprise_customer_uuid,
166
- 'start_date': start_date,
167
- 'end_date': end_date,
168
- },
237
+ query=self.queries.get_engagement_time_series_data_query(query_filters),
238
+ params=query_filter_params,
169
239
  as_dict=True,
170
240
  )
171
241
 
@@ -2,58 +2,25 @@
2
2
  Module for interacting with the fact_enrollment_admin_dash table.
3
3
  """
4
4
  from datetime import date, datetime
5
- from logging import getLogger
6
5
  from typing import Optional, Tuple
7
6
  from uuid import UUID
8
7
 
9
8
  from enterprise_data.cache.decorators import cache_it
10
- from enterprise_data.clients import EnterpriseApiClient
11
- from enterprise_data.exceptions import EnterpriseApiClientException
12
9
 
13
- from ..filters import FactEnrollmentAdminDashFilters
10
+ from ..filters import FactCompletionAdminDashFilters, FactEnrollmentAdminDashFilters
14
11
  from ..queries import FactEnrollmentAdminDashQueries
15
- from ..query_filters import INQueryFilter, QueryFilters
12
+ from ..query_filters import QueryFilters
16
13
  from ..utils import run_query
17
14
  from .base import BaseTable
18
15
 
19
- LOGGER = getLogger(__name__)
20
-
21
16
 
22
17
  class FactEnrollmentAdminDashTable(BaseTable):
23
18
  """
24
19
  Class for communicating with the fact_enrollment_admin_dash table.
25
20
  """
26
21
  queries = FactEnrollmentAdminDashQueries()
27
- filters = FactEnrollmentAdminDashFilters()
28
-
29
- def __get_enterprise_user_query_filter( # pylint: disable=inconsistent-return-statements
30
- self, group_uuid: Optional[UUID],
31
- enterprise_customer_uuid: UUID
32
- ) -> Optional[Tuple[INQueryFilter, dict]]:
33
- """
34
- Get the query filter to filter enrollments for enterprise users in the given group.
35
-
36
- Arguments:
37
- group_uuid (UUID): The UUID of the group.
38
- enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
39
-
40
- Returns:
41
- (INQueryFilter | None): The query filter to filter enrollments for enterprise users in the given group.
42
- """
43
- if not group_uuid:
44
- return None
45
-
46
- try:
47
- learners_in_group = EnterpriseApiClient.get_enterprise_user_ids_in_group(group_uuid)
48
- except EnterpriseApiClientException:
49
- LOGGER.exception(
50
- "Failed to get learners in group [%s] for enterprise [%s]",
51
- group_uuid,
52
- enterprise_customer_uuid,
53
- )
54
- else:
55
- params = {f'eu_{i}': enterprise_user_id for i, enterprise_user_id in enumerate(learners_in_group)}
56
- return self.filters.enterprise_user_id_in_filter(list(params.keys())), params
22
+ enrollment_filters = FactEnrollmentAdminDashFilters()
23
+ completion_filters = FactCompletionAdminDashFilters()
57
24
 
58
25
  def __get_common_query_filters(
59
26
  self, enterprise_customer_uuid: UUID,
@@ -73,8 +40,8 @@ class FactEnrollmentAdminDashTable(BaseTable):
73
40
  3. group_uuid filter to filter records for learners who belong to the given group.
74
41
  """
75
42
  query_filters = QueryFilters([
76
- self.filters.enterprise_customer_uuid_filter('enterprise_customer_uuid'),
77
- self.filters.enterprise_enrollment_date_range_filter('start_date', 'end_date'),
43
+ self.enrollment_filters.enterprise_customer_uuid_filter('enterprise_customer_uuid'),
44
+ self.enrollment_filters.date_range_filter('enterprise_enrollment_date', 'start_date', 'end_date'),
78
45
  ])
79
46
  params = {
80
47
  'enterprise_customer_uuid': enterprise_customer_uuid,
@@ -82,7 +49,46 @@ class FactEnrollmentAdminDashTable(BaseTable):
82
49
  'end_date': end_date,
83
50
  }
84
51
 
85
- response = self.__get_enterprise_user_query_filter(
52
+ response = self.enrollment_filters.enterprise_user_query_filter(
53
+ group_uuid, enterprise_customer_uuid
54
+ )
55
+ if response is not None:
56
+ enterprise_user_id_in_filter, enterprise_user_id_params = response
57
+ query_filters.append(enterprise_user_id_in_filter)
58
+ params.update(enterprise_user_id_params)
59
+
60
+ return query_filters, params
61
+
62
+ def __get_common_query_filters_for_completion(
63
+ self, enterprise_customer_uuid: UUID,
64
+ group_uuid: Optional[UUID],
65
+ start_date: date,
66
+ end_date: date,
67
+ ) -> Tuple[QueryFilters, dict]:
68
+ """
69
+ Utility method to get query filters common in most usages below.
70
+
71
+ This will return a tuple containing the query filters list and the dictionary of query parameters that
72
+ will be used in the query.
73
+
74
+ It will contain the following query filters.
75
+ 1. enterprise_customer_uuid filter to filter records for an enterprise customer.
76
+ 2. enrollment_date range filter to filter records by enrollment date.
77
+ 3. group_uuid filter to filter records for learners who belong to the given group.
78
+ 4. has_passed filter to filter records for successful completions.
79
+ """
80
+ query_filters = QueryFilters([
81
+ self.completion_filters.enterprise_customer_uuid_filter('enterprise_customer_uuid'),
82
+ self.completion_filters.date_range_filter('passed_date', 'start_date', 'end_date'),
83
+ self.completion_filters.has_passed_filter(),
84
+ ])
85
+ params = {
86
+ 'enterprise_customer_uuid': enterprise_customer_uuid,
87
+ 'start_date': start_date,
88
+ 'end_date': end_date,
89
+ }
90
+
91
+ response = self.completion_filters.enterprise_user_query_filter(
86
92
  group_uuid, enterprise_customer_uuid
87
93
  )
88
94
  if response is not None:
@@ -232,27 +238,31 @@ class FactEnrollmentAdminDashTable(BaseTable):
232
238
  return tuple(results[0])
233
239
 
234
240
  @cache_it()
235
- def get_completion_count(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
241
+ def get_completion_count(
242
+ self, enterprise_customer_uuid: UUID, group_uuid: Optional[UUID], start_date: date, end_date: date
243
+ ):
236
244
  """
237
245
  Get the completion count for the given enterprise customer.
238
246
 
239
247
  Arguments:
240
248
  enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
249
+ group_uuid (UUID): The UUID of the group.
241
250
  start_date (date): The start date.
242
251
  end_date (date): The end date.
243
252
 
244
253
  Returns:
245
254
  int: The completion count.
246
255
  """
256
+ query_filters, query_filter_params = self.__get_common_query_filters_for_completion(
257
+ enterprise_customer_uuid, group_uuid, start_date, end_date
258
+ )
247
259
  results = run_query(
248
- query=self.queries.get_completion_count_query(),
249
- params={
250
- 'enterprise_customer_uuid': enterprise_customer_uuid,
251
- 'start_date': start_date,
252
- 'end_date': end_date,
253
- }
260
+ query=self.queries.get_completion_count_query(query_filters),
261
+ params=query_filter_params,
262
+ as_dict=False,
254
263
  )
255
- if not results:
264
+ # Handle empty results defensively
265
+ if not results or not results[0] or len(results[0]) == 0:
256
266
  return 0
257
267
 
258
268
  return int(results[0][0] or 0)
@@ -347,7 +357,13 @@ class FactEnrollmentAdminDashTable(BaseTable):
347
357
 
348
358
  @cache_it()
349
359
  def get_all_completions(
350
- self, enterprise_customer_uuid: UUID, start_date: date, end_date: date, limit: int, offset: int
360
+ self,
361
+ enterprise_customer_uuid: UUID,
362
+ group_uuid: Optional[UUID],
363
+ start_date: date,
364
+ end_date: date,
365
+ limit: int,
366
+ offset: int,
351
367
  ):
352
368
  """
353
369
  Get all completions for the given enterprise customer.
@@ -355,6 +371,7 @@ class FactEnrollmentAdminDashTable(BaseTable):
355
371
  Arguments:
356
372
  enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
357
373
  start_date (date): The start date.
374
+ group_uuid (UUID): The UUID of the group.
358
375
  end_date (date): The end date.
359
376
  limit (int): The maximum number of records to return.
360
377
  offset (int): The number of records to skip.
@@ -362,12 +379,13 @@ class FactEnrollmentAdminDashTable(BaseTable):
362
379
  Returns:
363
380
  list<dict>: A list of dictionaries containing the completions data.
364
381
  """
382
+ query_filters, query_filter_params = self.__get_common_query_filters_for_completion(
383
+ enterprise_customer_uuid, group_uuid, start_date, end_date
384
+ )
365
385
  return run_query(
366
- query=self.queries.get_all_completions_query(),
386
+ query=self.queries.get_all_completions_query(query_filters),
367
387
  params={
368
- 'enterprise_customer_uuid': enterprise_customer_uuid,
369
- 'start_date': start_date,
370
- 'end_date': end_date,
388
+ **query_filter_params,
371
389
  'limit': limit,
372
390
  'offset': offset,
373
391
  },
@@ -375,7 +393,9 @@ class FactEnrollmentAdminDashTable(BaseTable):
375
393
  )
376
394
 
377
395
  @cache_it()
378
- def get_top_courses_by_completions(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
396
+ def get_top_courses_by_completions(
397
+ self, enterprise_customer_uuid: UUID, group_uuid: Optional[UUID], start_date: date, end_date: date
398
+ ):
379
399
  """
380
400
  Get the top courses by completion for the given enterprise customer.
381
401
 
@@ -387,18 +407,19 @@ class FactEnrollmentAdminDashTable(BaseTable):
387
407
  Returns:
388
408
  list<dict>: A list of dictionaries containing the course key, course_title and completion count.
389
409
  """
410
+ query_filters, query_filter_params = self.__get_common_query_filters_for_completion(
411
+ enterprise_customer_uuid, group_uuid, start_date, end_date
412
+ )
390
413
  return run_query(
391
- query=self.queries.get_top_courses_by_completions_query(),
392
- params={
393
- 'enterprise_customer_uuid': enterprise_customer_uuid,
394
- 'start_date': start_date,
395
- 'end_date': end_date,
396
- },
414
+ query=self.queries.get_top_courses_by_completions_query(query_filters),
415
+ params=query_filter_params,
397
416
  as_dict=True,
398
417
  )
399
418
 
400
419
  @cache_it()
401
- def get_top_subjects_by_completions(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
420
+ def get_top_subjects_by_completions(
421
+ self, enterprise_customer_uuid: UUID, group_uuid: Optional[UUID], start_date: date, end_date: date
422
+ ):
402
423
  """
403
424
  Get the top subjects by completions for the given enterprise customer.
404
425
 
@@ -410,35 +431,36 @@ class FactEnrollmentAdminDashTable(BaseTable):
410
431
  Returns:
411
432
  list<dict>: A list of dictionaries containing the subject and completion count.
412
433
  """
434
+ query_filters, query_filter_params = self.__get_common_query_filters_for_completion(
435
+ enterprise_customer_uuid, group_uuid, start_date, end_date
436
+ )
413
437
  return run_query(
414
- query=self.queries.get_top_subjects_by_completions_query(),
415
- params={
416
- 'enterprise_customer_uuid': enterprise_customer_uuid,
417
- 'start_date': start_date,
418
- 'end_date': end_date,
419
- },
438
+ query=self.queries.get_top_subjects_by_completions_query(query_filters),
439
+ params=query_filter_params,
420
440
  as_dict=True,
421
441
  )
422
442
 
423
443
  @cache_it()
424
- def get_completions_time_series_data(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
444
+ def get_completions_time_series_data(
445
+ self, enterprise_customer_uuid: UUID, group_uuid: Optional[UUID], start_date: date, end_date: date
446
+ ):
425
447
  """
426
448
  Get the completions time series data for the given enterprise customer.
427
449
 
428
450
  Arguments:
429
451
  enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
452
+ group_uuid (UUID): The UUID of the group.
430
453
  start_date (date): The start date.
431
454
  end_date (date): The end date.
432
455
 
433
456
  Returns:
434
457
  list<dict>: A list of dictionaries containing the date and completion count.
435
458
  """
459
+ query_filters, query_filter_params = self.__get_common_query_filters_for_completion(
460
+ enterprise_customer_uuid, group_uuid, start_date, end_date
461
+ )
436
462
  return run_query(
437
- query=self.queries.get_completions_time_series_data_query(),
438
- params={
439
- 'enterprise_customer_uuid': enterprise_customer_uuid,
440
- 'start_date': start_date,
441
- 'end_date': end_date,
442
- },
463
+ query=self.queries.get_completions_time_series_data_query(query_filters),
464
+ params=query_filter_params,
443
465
  as_dict=True,
444
466
  )
@@ -262,6 +262,7 @@ class AdminAnalyticsAggregatesQueryParamsSerializer(serializers.Serializer): #
262
262
  response_type = serializers.CharField(required=False)
263
263
  page = serializers.IntegerField(required=False)
264
264
  chart_type = serializers.CharField(required=False)
265
+ group_uuid = serializers.UUIDField(required=False)
265
266
 
266
267
  def validate(self, attrs):
267
268
  """
@@ -51,10 +51,12 @@ class AdvanceAnalyticsCompletionsView(AnalyticsPaginationMixin, ViewSet):
51
51
  # get values from query params or use default values
52
52
  start_date = serializer.data.get('start_date', min_enrollment_date)
53
53
  end_date = serializer.data.get('end_date', date.today())
54
+ group_uuid = serializer.data.get('group_uuid')
54
55
  page = serializer.data.get('page', 1)
55
56
  page_size = serializer.data.get('page_size', 100)
56
57
  completions = FactEnrollmentAdminDashTable().get_all_completions(
57
58
  enterprise_customer_uuid=enterprise_uuid,
59
+ group_uuid=group_uuid,
58
60
  start_date=start_date,
59
61
  end_date=end_date,
60
62
  limit=page_size,
@@ -62,6 +64,7 @@ class AdvanceAnalyticsCompletionsView(AnalyticsPaginationMixin, ViewSet):
62
64
  )
63
65
  total_count = FactEnrollmentAdminDashTable().get_completion_count(
64
66
  enterprise_customer_uuid=enterprise_uuid,
67
+ group_uuid=group_uuid,
65
68
  start_date=start_date,
66
69
  end_date=end_date,
67
70
  )
@@ -79,7 +82,7 @@ class AdvanceAnalyticsCompletionsView(AnalyticsPaginationMixin, ViewSet):
79
82
 
80
83
  return StreamingHttpResponse(
81
84
  IndividualCompletionsCSVRenderer().render(self._stream_serialized_data(
82
- enterprise_uuid, start_date, end_date, total_count
85
+ enterprise_uuid, group_uuid, start_date, end_date, total_count
83
86
  )),
84
87
  content_type="text/csv",
85
88
  headers={"Content-Disposition": f'attachment; filename="{filename}"'},
@@ -94,7 +97,7 @@ class AdvanceAnalyticsCompletionsView(AnalyticsPaginationMixin, ViewSet):
94
97
  )
95
98
 
96
99
  @staticmethod
97
- def _stream_serialized_data(enterprise_uuid, start_date, end_date, total_count, page_size=50000):
100
+ def _stream_serialized_data(enterprise_uuid, group_uuid, start_date, end_date, total_count, page_size=50000):
98
101
  """
99
102
  Stream the serialized data.
100
103
  """
@@ -102,6 +105,7 @@ class AdvanceAnalyticsCompletionsView(AnalyticsPaginationMixin, ViewSet):
102
105
  while offset < total_count:
103
106
  completions = FactEnrollmentAdminDashTable().get_all_completions(
104
107
  enterprise_customer_uuid=enterprise_uuid,
108
+ group_uuid=group_uuid,
105
109
  start_date=start_date,
106
110
  end_date=end_date,
107
111
  limit=page_size,
@@ -133,16 +137,18 @@ class AdvanceAnalyticsCompletionsView(AnalyticsPaginationMixin, ViewSet):
133
137
  # get values from query params or use default
134
138
  start_date = serializer.data.get('start_date', min_enrollment_date)
135
139
  end_date = serializer.data.get('end_date', date.today())
140
+ group_uuid = serializer.data.get('group_uuid')
141
+
136
142
  with timer('construct_completion_all_stats'):
137
143
  data = {
138
144
  'completions_over_time': FactEnrollmentAdminDashTable().get_completions_time_series_data(
139
- enterprise_uuid, start_date, end_date
145
+ enterprise_uuid, group_uuid, start_date, end_date
140
146
  ),
141
147
  'top_courses_by_completions': FactEnrollmentAdminDashTable().get_top_courses_by_completions(
142
- enterprise_uuid, start_date, end_date,
148
+ enterprise_uuid, group_uuid, start_date, end_date,
143
149
  ),
144
150
  'top_subjects_by_completions': FactEnrollmentAdminDashTable().get_top_subjects_by_completions(
145
- enterprise_uuid, start_date, end_date,
151
+ enterprise_uuid, group_uuid, start_date, end_date,
146
152
  ),
147
153
  }
148
154
  return Response(data)
@@ -51,10 +51,12 @@ class AdvanceAnalyticsEngagementView(AnalyticsPaginationMixin, ViewSet):
51
51
  # get values from query params or use default values
52
52
  start_date = serializer.data.get('start_date', min_enrollment_date)
53
53
  end_date = serializer.data.get('end_date', date.today())
54
+ group_uuid = serializer.data.get('group_uuid')
54
55
  page = serializer.data.get('page', 1)
55
56
  page_size = serializer.data.get('page_size', 100)
56
57
  engagements = FactEngagementAdminDashTable().get_all_engagements(
57
58
  enterprise_customer_uuid=enterprise_uuid,
59
+ group_uuid=group_uuid,
58
60
  start_date=start_date,
59
61
  end_date=end_date,
60
62
  limit=page_size,
@@ -62,6 +64,7 @@ class AdvanceAnalyticsEngagementView(AnalyticsPaginationMixin, ViewSet):
62
64
  )
63
65
  total_count = FactEngagementAdminDashTable().get_engagement_count(
64
66
  enterprise_customer_uuid=enterprise_uuid,
67
+ group_uuid=group_uuid,
65
68
  start_date=start_date,
66
69
  end_date=end_date,
67
70
  )
@@ -79,7 +82,7 @@ class AdvanceAnalyticsEngagementView(AnalyticsPaginationMixin, ViewSet):
79
82
 
80
83
  return StreamingHttpResponse(
81
84
  IndividualEngagementsCSVRenderer().render(self._stream_serialized_data(
82
- enterprise_uuid, start_date, end_date, total_count
85
+ enterprise_uuid, group_uuid, start_date, end_date, total_count
83
86
  )),
84
87
  content_type="text/csv",
85
88
  headers={"Content-Disposition": f'attachment; filename="{filename}"'},
@@ -94,7 +97,7 @@ class AdvanceAnalyticsEngagementView(AnalyticsPaginationMixin, ViewSet):
94
97
  )
95
98
 
96
99
  @staticmethod
97
- def _stream_serialized_data(enterprise_uuid, start_date, end_date, total_count, page_size=50000):
100
+ def _stream_serialized_data(enterprise_uuid, group_uuid, start_date, end_date, total_count, page_size=50000):
98
101
  """
99
102
  Stream the serialized data.
100
103
  """
@@ -102,6 +105,7 @@ class AdvanceAnalyticsEngagementView(AnalyticsPaginationMixin, ViewSet):
102
105
  while offset < total_count:
103
106
  engagements = FactEngagementAdminDashTable().get_all_engagements(
104
107
  enterprise_customer_uuid=enterprise_uuid,
108
+ group_uuid=group_uuid,
105
109
  start_date=start_date,
106
110
  end_date=end_date,
107
111
  limit=page_size,
@@ -133,16 +137,17 @@ class AdvanceAnalyticsEngagementView(AnalyticsPaginationMixin, ViewSet):
133
137
  # get values from query params or use default
134
138
  start_date = serializer.data.get('start_date', min_enrollment_date)
135
139
  end_date = serializer.data.get('end_date', date.today())
140
+ group_uuid = serializer.data.get('group_uuid')
136
141
  with timer('construct_engagement_all_stats'):
137
142
  data = {
138
143
  'engagement_over_time': FactEngagementAdminDashTable().get_engagement_time_series_data(
139
- enterprise_uuid, start_date, end_date
144
+ enterprise_uuid, group_uuid, start_date, end_date
140
145
  ),
141
146
  'top_courses_by_engagement': FactEngagementAdminDashTable().get_top_courses_by_engagement(
142
- enterprise_uuid, start_date, end_date,
147
+ enterprise_uuid, group_uuid, start_date, end_date,
143
148
  ),
144
149
  'top_subjects_by_engagement': FactEngagementAdminDashTable().get_top_subjects_by_engagement(
145
- enterprise_uuid, start_date, end_date,
150
+ enterprise_uuid, group_uuid, start_date, end_date,
146
151
  ),
147
152
  }
148
153
  return Response(data)
@@ -108,12 +108,13 @@ class EnterpriseAdminAnalyticsAggregatesView(APIView):
108
108
  'start_date', min_enrollment_date
109
109
  )
110
110
  end_date = serializer.data.get('end_date', datetime.today())
111
+ group_uuid = serializer.data.get('group_uuid', None)
111
112
 
112
113
  enrolls, courses = FactEnrollmentAdminDashTable().get_enrollment_and_course_count(
113
114
  enterprise_id, start_date, end_date,
114
115
  )
115
116
  completions = FactEnrollmentAdminDashTable().get_completion_count(
116
- enterprise_id, start_date, end_date,
117
+ enterprise_id, group_uuid, start_date, end_date,
117
118
  )
118
119
  hours, sessions = FactEngagementAdminDashTable().get_learning_hours_and_daily_sessions(
119
120
  enterprise_id, start_date, end_date,