edx-enterprise-data 9.0.1__tar.gz → 9.1.0__tar.gz

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 (207) hide show
  1. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/CHANGELOG.rst +5 -0
  2. {edx_enterprise_data-9.0.1/edx_enterprise_data.egg-info → edx_enterprise_data-9.1.0}/PKG-INFO +1 -1
  3. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0/edx_enterprise_data.egg-info}/PKG-INFO +1 -1
  4. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/edx_enterprise_data.egg-info/SOURCES.txt +1 -2
  5. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/__init__.py +1 -1
  6. edx_enterprise_data-9.1.0/enterprise_data/admin_analytics/constants.py +25 -0
  7. edx_enterprise_data-9.1.0/enterprise_data/admin_analytics/database/queries/fact_engagement_admin_dash.py +111 -0
  8. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/admin_analytics/database/queries/fact_enrollment_admin_dash.py +83 -4
  9. edx_enterprise_data-9.1.0/enterprise_data/admin_analytics/database/tables/fact_engagement_admin_dash.py +154 -0
  10. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/admin_analytics/database/tables/fact_enrollment_admin_dash.py +97 -3
  11. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v1/serializers.py +1 -55
  12. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v1/urls.py +14 -17
  13. edx_enterprise_data-9.1.0/enterprise_data/api/v1/views/analytics_completions.py +150 -0
  14. edx_enterprise_data-9.1.0/enterprise_data/api/v1/views/analytics_engagements.py +150 -0
  15. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v1/views/analytics_enrollments.py +3 -6
  16. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/renderers.py +22 -7
  17. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/admin_analytics/mock_analytics_data.py +12 -90
  18. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/admin_analytics/mock_enrollments.py +0 -66
  19. edx_enterprise_data-9.1.0/enterprise_data/tests/admin_analytics/test_analytics_engagements.py +270 -0
  20. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/admin_analytics/test_analytics_enrollments.py +12 -81
  21. edx_enterprise_data-9.1.0/enterprise_data/tests/admin_analytics/test_enterprise_completions.py +187 -0
  22. edx_enterprise_data-9.0.1/enterprise_data/admin_analytics/completions_utils.py +0 -261
  23. edx_enterprise_data-9.0.1/enterprise_data/admin_analytics/constants.py +0 -41
  24. edx_enterprise_data-9.0.1/enterprise_data/admin_analytics/database/queries/fact_engagement_admin_dash.py +0 -21
  25. edx_enterprise_data-9.0.1/enterprise_data/admin_analytics/database/tables/fact_engagement_admin_dash.py +0 -38
  26. edx_enterprise_data-9.0.1/enterprise_data/api/v1/views/analytics_engagements.py +0 -395
  27. edx_enterprise_data-9.0.1/enterprise_data/api/v1/views/enterprise_completions.py +0 -200
  28. edx_enterprise_data-9.0.1/enterprise_data/tests/admin_analytics/test_analytics_engagements.py +0 -390
  29. edx_enterprise_data-9.0.1/enterprise_data/tests/admin_analytics/test_enterprise_completions.py +0 -202
  30. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/LICENSE +0 -0
  31. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/MANIFEST.in +0 -0
  32. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/README.md +0 -0
  33. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/edx_enterprise_data.egg-info/dependency_links.txt +0 -0
  34. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/edx_enterprise_data.egg-info/not-zip-safe +0 -0
  35. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/edx_enterprise_data.egg-info/requires.txt +0 -0
  36. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/edx_enterprise_data.egg-info/top_level.txt +0 -0
  37. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/admin_analytics/__init__.py +0 -0
  38. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/admin_analytics/data_loaders.py +0 -0
  39. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/admin_analytics/database/__init__.py +0 -0
  40. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/admin_analytics/database/queries/__init__.py +0 -0
  41. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/admin_analytics/database/queries/skills_daily_rollup_admin_dash.py +0 -0
  42. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/admin_analytics/database/tables/__init__.py +0 -0
  43. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/admin_analytics/database/tables/base.py +0 -0
  44. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/admin_analytics/database/tables/skills_daily_rollup_admin_dash.py +0 -0
  45. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/admin_analytics/database/utils.py +0 -0
  46. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/admin_analytics/utils.py +0 -0
  47. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/__init__.py +0 -0
  48. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/urls.py +0 -0
  49. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v0/__init__.py +0 -0
  50. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v0/serializers.py +0 -0
  51. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v0/urls.py +0 -0
  52. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v0/views.py +0 -0
  53. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v1/__init__.py +0 -0
  54. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v1/paginators.py +0 -0
  55. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v1/views/__init__.py +0 -0
  56. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v1/views/analytics_leaderboard.py +0 -0
  57. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v1/views/base.py +0 -0
  58. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v1/views/enterprise_admin.py +0 -0
  59. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v1/views/enterprise_learner.py +0 -0
  60. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/api/v1/views/enterprise_offers.py +0 -0
  61. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/apps.py +0 -0
  62. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/clients.py +0 -0
  63. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/constants.py +0 -0
  64. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/filters.py +0 -0
  65. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/fixtures/enterprise_enrollment.json +0 -0
  66. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/fixtures/enterprise_user.json +0 -0
  67. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/__init__.py +0 -0
  68. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/__init__.py +0 -0
  69. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/create_dummy_data.py +0 -0
  70. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/create_dummy_data_lpr_v1.py +0 -0
  71. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/create_enterprise_enrollment.py +0 -0
  72. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/create_enterprise_learner_enrollment_lpr_v1.py +0 -0
  73. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/create_enterprise_learner_lpr_v1.py +0 -0
  74. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/create_enterprise_offer.py +0 -0
  75. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/create_enterprise_user.py +0 -0
  76. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/tests/__init__.py +0 -0
  77. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/tests/test_create_dummy_data_lpr_v1.py +0 -0
  78. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/tests/test_create_enterprise_enrollment.py +0 -0
  79. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/tests/test_create_enterprise_learner_enrollment_lpr_v1.py +0 -0
  80. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/tests/test_create_enterprise_learner_lpr_v1.py +0 -0
  81. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/management/commands/tests/test_create_enterprise_user.py +0 -0
  82. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0001_initial.py +0 -0
  83. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0002_auto_20180430_1358.py +0 -0
  84. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0003_auto_20180501_0603.py +0 -0
  85. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0004_auto_20180501_0928.py +0 -0
  86. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0004_auto_20180508_1652.py +0 -0
  87. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0005_auto_20180524_2204.py +0 -0
  88. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0006_auto_20180612_0336.py +0 -0
  89. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0007_auto_20180612_0534.py +0 -0
  90. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0008_auto_20180614_0108.py +0 -0
  91. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0009_auto_20180628_1152.py +0 -0
  92. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0010_enterpriseenrollment_created.py +0 -0
  93. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0011_enterpriseuser.py +0 -0
  94. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0012_auto_20180831_1930.py +0 -0
  95. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0013_auto_20180831_1931.py +0 -0
  96. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0014_enterpriseuser_created.py +0 -0
  97. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0015_auto_20180907_1757.py +0 -0
  98. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0016_auto_20180924_2138.py +0 -0
  99. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0017_enterpriseenrollment_unenrollment_timestamp.py +0 -0
  100. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0018_enterprisedatafeaturerole_enterprisedataroleassignment.py +0 -0
  101. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0019_add_enterprise_data_feature_roles.py +0 -0
  102. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0020_add_role_based_access_control_switch.py +0 -0
  103. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0021_auto_20190329_1241.py +0 -0
  104. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0022_remove_role_based_access_control_switch.py +0 -0
  105. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0023_enterpriselearner_enterpriselearnerenrollment.py +0 -0
  106. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0024_auto_20210602_1811.py +0 -0
  107. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0025_auto_20210703_1854.py +0 -0
  108. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0026_auto_20210916_0414.py +0 -0
  109. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0027_enterpriselearnerenrollment_total_learning_time_seconds.py +0 -0
  110. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0028_enterpriselearnerenrollment_offer_id.py +0 -0
  111. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0029_enterpriseoffer.py +0 -0
  112. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0030_auto_20230609_1353.py +0 -0
  113. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0031_auto_20230615_0705.py +0 -0
  114. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0032_auto_20230704_0818.py +0 -0
  115. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0033_enterpriseadminlearnerprogress_enterpriseadminsummarizeinsights.py +0 -0
  116. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0034_auto_20230907_0834.py +0 -0
  117. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0035_auto_20230907_1154.py +0 -0
  118. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0036_enterprisesubsidybudget_subsidy_access_policy_display_name.py +0 -0
  119. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0037_alter_enterpriseenrollment_consent_granted.py +0 -0
  120. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0038_enterpriseoffer_export_timestamp.py +0 -0
  121. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0039_auto_20240212_1403.py +0 -0
  122. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0040_auto_20240718_0536_squashed_0043_alter_enterpriselearnerenrollment_enterprise_enrollment_id.py +0 -0
  123. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/0044_enterpriseexecedlcmoduleperformance.py +0 -0
  124. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/migrations/__init__.py +0 -0
  125. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/models.py +0 -0
  126. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/paginators.py +0 -0
  127. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/settings/__init__.py +0 -0
  128. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/settings/test.py +0 -0
  129. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/signals.py +0 -0
  130. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/__init__.py +0 -0
  131. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/admin_analytics/__init__.py +0 -0
  132. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/admin_analytics/test_analytics_leaderboard.py +0 -0
  133. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/admin_analytics/test_data_loaders.py +0 -0
  134. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/admin_analytics/test_utils.py +0 -0
  135. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/api/__init__.py +0 -0
  136. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/api/v0/__init__.py +0 -0
  137. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/api/v0/test_serializers.py +0 -0
  138. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/api/v1/__init__.py +0 -0
  139. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/api/v1/test_serializers.py +0 -0
  140. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/api/v1/test_views.py +0 -0
  141. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/api/v1/views/__init__.py +0 -0
  142. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/api/v1/views/test_enterprise_admin.py +0 -0
  143. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/factories.py +0 -0
  144. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/mixins.py +0 -0
  145. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/test_clients.py +0 -0
  146. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/test_filters.py +0 -0
  147. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/test_models.py +0 -0
  148. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/test_utils.py +0 -0
  149. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/tests/test_views.py +0 -0
  150. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/urls.py +0 -0
  151. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data/utils.py +0 -0
  152. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/__init__.py +0 -0
  153. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/admin.py +0 -0
  154. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/apps.py +0 -0
  155. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/constants.py +0 -0
  156. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/migrations/0001_initial.py +0 -0
  157. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/migrations/0002_add_enterprise_data_feature_roles.py +0 -0
  158. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/migrations/0003_add_role_based_access_control_switch.py +0 -0
  159. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/migrations/0004_enterprisedataroleassignment_enterprise_id.py +0 -0
  160. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/migrations/0005_turn_on_role_based_access_control_switch.py +0 -0
  161. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/migrations/0006_remove_role_based_access_control_switch.py +0 -0
  162. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/migrations/0007_enterprisedataroleassignment_applies_to_all_contexts.py +0 -0
  163. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/migrations/__init__.py +0 -0
  164. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/models.py +0 -0
  165. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/rules.py +0 -0
  166. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/tests/__init__.py +0 -0
  167. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/tests/factories.py +0 -0
  168. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_data_roles/tests/test_models.py +0 -0
  169. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/__init__.py +0 -0
  170. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/clients/__init__.py +0 -0
  171. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/clients/enterprise.py +0 -0
  172. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/clients/s3.py +0 -0
  173. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/clients/snowflake.py +0 -0
  174. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/clients/vertica.py +0 -0
  175. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/delivery_method.py +0 -0
  176. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/external_resource_link_report.py +0 -0
  177. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/fixtures/__init__.py +0 -0
  178. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/fixtures/enterprise_customer_reporting.json +0 -0
  179. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/reporter.py +0 -0
  180. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/send_enterprise_reports.py +0 -0
  181. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/tests/__init__.py +0 -0
  182. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/tests/test_clients.py +0 -0
  183. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/tests/test_delivery_method.py +0 -0
  184. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/tests/test_enterprise_client.py +0 -0
  185. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/tests/test_external_link_report.py +0 -0
  186. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/tests/test_reporter.py +0 -0
  187. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/tests/test_send_enterprise_reports.py +0 -0
  188. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/tests/test_utils.py +0 -0
  189. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/tests/test_vertica_client.py +0 -0
  190. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/tests/utils.py +0 -0
  191. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/enterprise_reporting/utils.py +0 -0
  192. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/base.in +0 -0
  193. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/base.txt +0 -0
  194. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/ci.txt +0 -0
  195. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/common_constraints.txt +0 -0
  196. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/constraints.txt +0 -0
  197. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/dev.txt +0 -0
  198. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/django.txt +0 -0
  199. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/pip.txt +0 -0
  200. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/pip_tools.txt +0 -0
  201. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/quality.txt +0 -0
  202. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/reporting.in +0 -0
  203. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/test-master.txt +0 -0
  204. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/test-reporting.txt +0 -0
  205. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/requirements/test.txt +0 -0
  206. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/setup.cfg +0 -0
  207. {edx_enterprise_data-9.0.1 → edx_enterprise_data-9.1.0}/setup.py +0 -0
@@ -15,6 +15,11 @@ Unreleased
15
15
  ----------
16
16
 
17
17
  =========================
18
+
19
+ [9.1.0] - 2024-09-23
20
+ ---------------------
21
+ * refactor: Performance optimizations for engagement and completions related API endpoints.
22
+
18
23
  [9.0.1] - 2024-09-23
19
24
  ---------------------
20
25
  * revert: Revert "feat!: Python 3.12 Upgrade"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edx-enterprise-data
3
- Version: 9.0.1
3
+ Version: 9.1.0
4
4
  Summary: Enterprise Reporting
5
5
  Home-page: https://github.com/openedx/edx-enterprise-data
6
6
  Author: edX
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edx-enterprise-data
3
- Version: 9.0.1
3
+ Version: 9.1.0
4
4
  Summary: Enterprise Reporting
5
5
  Home-page: https://github.com/openedx/edx-enterprise-data
6
6
  Author: edX
@@ -21,7 +21,6 @@ enterprise_data/signals.py
21
21
  enterprise_data/urls.py
22
22
  enterprise_data/utils.py
23
23
  enterprise_data/admin_analytics/__init__.py
24
- enterprise_data/admin_analytics/completions_utils.py
25
24
  enterprise_data/admin_analytics/constants.py
26
25
  enterprise_data/admin_analytics/data_loaders.py
27
26
  enterprise_data/admin_analytics/utils.py
@@ -47,12 +46,12 @@ enterprise_data/api/v1/paginators.py
47
46
  enterprise_data/api/v1/serializers.py
48
47
  enterprise_data/api/v1/urls.py
49
48
  enterprise_data/api/v1/views/__init__.py
49
+ enterprise_data/api/v1/views/analytics_completions.py
50
50
  enterprise_data/api/v1/views/analytics_engagements.py
51
51
  enterprise_data/api/v1/views/analytics_enrollments.py
52
52
  enterprise_data/api/v1/views/analytics_leaderboard.py
53
53
  enterprise_data/api/v1/views/base.py
54
54
  enterprise_data/api/v1/views/enterprise_admin.py
55
- enterprise_data/api/v1/views/enterprise_completions.py
56
55
  enterprise_data/api/v1/views/enterprise_learner.py
57
56
  enterprise_data/api/v1/views/enterprise_offers.py
58
57
  enterprise_data/fixtures/enterprise_enrollment.json
@@ -2,4 +2,4 @@
2
2
  Enterprise data api application. This Django app exposes API endpoints used by enterprises.
3
3
  """
4
4
 
5
- __version__ = "9.0.1"
5
+ __version__ = "9.1.0"
@@ -0,0 +1,25 @@
1
+ """Advanced Analytics Constants"""
2
+
3
+ from enum import Enum
4
+
5
+
6
+ class Granularity(Enum):
7
+ """Granularity choices"""
8
+ DAILY = 'Daily'
9
+ WEEKLY = 'Weekly'
10
+ MONTHLY = 'Monthly'
11
+ QUARTERLY = 'Quarterly'
12
+
13
+
14
+ class Calculation(Enum):
15
+ """Calculation choices"""
16
+ TOTAL = 'Total'
17
+ RUNNING_TOTAL = 'Running Total'
18
+ MOVING_AVERAGE_3_PERIOD = 'Moving Average (3 Period)'
19
+ MOVING_AVERAGE_7_PERIOD = 'Moving Average (7 Period)'
20
+
21
+
22
+ class ResponseType(Enum):
23
+ """Response type choices"""
24
+ JSON = 'json'
25
+ CSV = 'csv'
@@ -0,0 +1,111 @@
1
+ """
2
+ Module containing queries for the fact_enrollment_engagement_day_admin_dash table.
3
+ """
4
+
5
+
6
+ class FactEngagementAdminDashQueries:
7
+ """
8
+ Queries related to the fact_enrollment_engagement_day_admin_dash table.
9
+ """
10
+ @staticmethod
11
+ def get_learning_hours_and_daily_sessions_query():
12
+ """
13
+ Get the query to fetch the learning hours and daily sessions.
14
+ """
15
+ return """
16
+ SELECT
17
+ ROUND(SUM(learning_time_seconds) / 60 / 60, 1) as hours, SUM(is_engaged) as sessions
18
+ FROM fact_enrollment_engagement_day_admin_dash
19
+ WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
20
+ activity_date BETWEEN %(start_date)s AND %(end_date)s;
21
+ """
22
+
23
+ @staticmethod
24
+ def get_engagement_count_query():
25
+ """
26
+ Get the query to fetch the total number of engagements for an enterprise customer.
27
+ """
28
+ return """
29
+ SELECT count(*)
30
+ FROM fact_enrollment_engagement_day_admin_dash
31
+ WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
32
+ activity_date BETWEEN %(start_date)s AND %(end_date)s;
33
+ """
34
+
35
+ @staticmethod
36
+ def get_all_engagement_query():
37
+ """
38
+ Get the query to fetch all engagement data.
39
+ """
40
+ return """
41
+ SELECT
42
+ email, course_title, course_subject, enroll_type, activity_date,
43
+ learning_time_seconds/3600 as learning_time_hours
44
+ FROM fact_enrollment_engagement_day_admin_dash
45
+ WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
46
+ activity_date BETWEEN %(start_date)s AND %(end_date)s
47
+ ORDER BY activity_date DESC LIMIT %(limit)s OFFSET %(offset)s;
48
+ """
49
+
50
+ @staticmethod
51
+ def get_top_courses_by_engagement_query(record_count=20):
52
+ """
53
+ Get the query to fetch the learning time in hours by courses.
54
+
55
+ Query should fetch the top N courses by user engagement. Where N is the value of record_count.
56
+
57
+ Arguments:
58
+ record_count (int): Number of records to fetch.
59
+
60
+ Returns:
61
+ (str): Query to fetch the learning time in hours by courses for the top courses by user engagement.
62
+ """
63
+ return f"""
64
+ SELECT course_key, course_title, enroll_type, SUM(learning_time_seconds)/3600 as learning_time_hours
65
+ FROM fact_enrollment_engagement_day_admin_dash
66
+ WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
67
+ activity_date BETWEEN %(start_date)s AND %(end_date)s
68
+ GROUP BY course_key, course_title, enroll_type
69
+ ORDER BY learning_time_hours DESC LIMIT {record_count};
70
+ """
71
+
72
+ @staticmethod
73
+ def get_top_subjects_by_engagement_query(record_count=20):
74
+ """
75
+ Get the query to fetch the learning time in hours by subjects.
76
+
77
+ Query should fetch the top N subjects by user engagement. Where N is the value of record_count.
78
+
79
+ Arguments:
80
+ record_count (int): Number of records to fetch.
81
+
82
+ Returns:
83
+ (str): Query to fetch the learning time in hours by subjects for the top subjects by user engagement.
84
+ """
85
+ return f"""
86
+ SELECT course_subject, enroll_type, SUM(learning_time_seconds)/3600 as learning_time_hours
87
+ FROM fact_enrollment_engagement_day_admin_dash
88
+ WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
89
+ activity_date BETWEEN %(start_date)s AND %(end_date)s
90
+ GROUP BY course_subject, enroll_type
91
+ ORDER BY learning_time_hours DESC LIMIT {record_count};
92
+ """
93
+
94
+ @staticmethod
95
+ def get_engagement_time_series_data_query():
96
+ """
97
+ Get the query to fetch the completion time series data.
98
+
99
+ Query should fetch the time series data with daily granularity.
100
+
101
+ Returns:
102
+ (str): Query to fetch the completion time series data.
103
+ """
104
+ return """
105
+ SELECT activity_date, enroll_type, SUM(learning_time_seconds)/3600 as learning_time_hours
106
+ FROM fact_enrollment_engagement_day_admin_dash
107
+ WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
108
+ activity_date BETWEEN %(start_date)s AND %(end_date)s
109
+ GROUP BY activity_date, enroll_type
110
+ ORDER BY activity_date;
111
+ """
@@ -68,6 +68,7 @@ class FactEnrollmentAdminDashQueries:
68
68
  SUM(has_passed) as completions
69
69
  FROM fact_enrollment_admin_dash
70
70
  WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
71
+ has_passed=1 AND
71
72
  passed_date BETWEEN %(start_date)s AND %(end_date)s;
72
73
  """
73
74
 
@@ -85,7 +86,7 @@ class FactEnrollmentAdminDashQueries:
85
86
  """
86
87
 
87
88
  @staticmethod
88
- def get_top_courses_enrollments_query(record_count=20):
89
+ def get_top_courses_by_enrollments_query(record_count=20):
89
90
  """
90
91
  Get the query to fetch the enrollment count by courses.
91
92
 
@@ -94,14 +95,12 @@ class FactEnrollmentAdminDashQueries:
94
95
  Arguments:
95
96
  record_count (int): Number of records to fetch.
96
97
  """
97
- # Some local environments raise error when course_title is added in SELECT without GROUP BY.
98
- # If you face this issue, you can remove course_title from SELECT.
99
98
  return f"""
100
99
  SELECT course_key, course_title , enroll_type, count(course_key) as enrollment_count
101
100
  FROM fact_enrollment_admin_dash
102
101
  WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
103
102
  enterprise_enrollment_date BETWEEN %(start_date)s AND %(end_date)s
104
- GROUP BY course_key, enroll_type ORDER BY enrollment_count DESC LIMIT {record_count};
103
+ GROUP BY course_key, course_title, enroll_type ORDER BY enrollment_count DESC LIMIT {record_count};
105
104
  """
106
105
 
107
106
  @staticmethod
@@ -135,3 +134,83 @@ class FactEnrollmentAdminDashQueries:
135
134
  GROUP BY enterprise_enrollment_date, enroll_type
136
135
  ORDER BY enterprise_enrollment_date;
137
136
  """
137
+
138
+ @staticmethod
139
+ def get_all_completions_query():
140
+ """
141
+ Get the query to fetch all completions.
142
+ """
143
+ return """
144
+ SELECT email, course_title, course_subject, enroll_type, passed_date
145
+ FROM fact_enrollment_admin_dash
146
+ WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
147
+ has_passed=1 AND
148
+ passed_date BETWEEN %(start_date)s AND %(end_date)s
149
+ ORDER BY passed_date DESC LIMIT %(limit)s OFFSET %(offset)s
150
+ """
151
+
152
+ @staticmethod
153
+ def get_top_courses_by_completions_query(record_count=20):
154
+ """
155
+ Get the query to fetch the completion count by courses.
156
+
157
+ Query should fetch the top N courses by completion count. Where N is the value of record_count.
158
+
159
+ Arguments:
160
+ record_count (int): Number of records to fetch.
161
+
162
+ Returns:
163
+ (str): Query to fetch the enrollment count by courses for the top courses by enrollment count.
164
+ """
165
+ return f"""
166
+ SELECT course_key, course_title, enroll_type, count(course_key) as completion_count
167
+ FROM fact_enrollment_admin_dash
168
+ WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
169
+ has_passed=1 AND
170
+ passed_date BETWEEN %(start_date)s AND %(end_date)s
171
+ GROUP BY course_key, course_title, enroll_type
172
+ ORDER BY completion_count DESC LIMIT {record_count};
173
+ """
174
+
175
+ @staticmethod
176
+ def get_top_subjects_by_completions_query(record_count=20):
177
+ """
178
+ Get the query to fetch the completion count by subjects.
179
+
180
+ Query should fetch the top N subjects by completion count. Where N is the value of record_count.
181
+
182
+ Arguments:
183
+ record_count (int): Number of records to fetch.
184
+
185
+ Returns:
186
+ (str): Query to fetch the completion count by subjects for the top subjects by completion count.
187
+ """
188
+ return f"""
189
+ SELECT course_subject, enroll_type, count(course_subject) as completion_count
190
+ FROM fact_enrollment_admin_dash
191
+ WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
192
+ has_passed=1 AND
193
+ passed_date BETWEEN %(start_date)s AND %(end_date)s
194
+ GROUP BY course_subject, enroll_type
195
+ ORDER BY completion_count DESC LIMIT {record_count};
196
+ """
197
+
198
+ @staticmethod
199
+ def get_completions_time_series_data_query():
200
+ """
201
+ Get the query to fetch the completion time series data.
202
+
203
+ Query should fetch the time series data with daily granularity.
204
+
205
+ Returns:
206
+ (str): Query to fetch the completion time series data.
207
+ """
208
+ return """
209
+ SELECT passed_date, enroll_type, count(course_key) as completion_count
210
+ FROM fact_enrollment_admin_dash
211
+ WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
212
+ has_passed=1 AND
213
+ passed_date BETWEEN %(start_date)s AND %(end_date)s
214
+ GROUP BY passed_date, enroll_type
215
+ ORDER BY passed_date;
216
+ """
@@ -0,0 +1,154 @@
1
+ """
2
+ Module for interacting with the fact_enrollment_engagement_day_admin_dash table.
3
+ """
4
+ from datetime import date
5
+ from uuid import UUID
6
+
7
+ from ..queries import FactEngagementAdminDashQueries
8
+ from ..utils import run_query
9
+ from .base import BaseTable
10
+
11
+
12
+ class FactEngagementAdminDashTable(BaseTable):
13
+ """
14
+ Class for communicating with the fact_enrollment_engagement_day_admin_dash table.
15
+ """
16
+ queries = FactEngagementAdminDashQueries()
17
+
18
+ def get_learning_hours_and_daily_sessions(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
19
+ """
20
+ Get the learning hours and daily sessions for the given enterprise customer.
21
+
22
+ Arguments:
23
+ enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
24
+ start_date (date): The start date.
25
+ end_date (date): The end date.
26
+
27
+ Returns:
28
+ (tuple<float, int>): The learning hours and daily sessions.
29
+ """
30
+ results = run_query(
31
+ query=self.queries.get_learning_hours_and_daily_sessions_query(),
32
+ params={
33
+ 'enterprise_customer_uuid': enterprise_customer_uuid,
34
+ 'start_date': start_date,
35
+ 'end_date': end_date,
36
+ }
37
+ )
38
+ return tuple(results[0])
39
+
40
+ def get_engagement_count(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
41
+ """
42
+ Get the total number of engagements for the given enterprise customer.
43
+
44
+ Arguments:
45
+ enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
46
+ start_date (date): The start date.
47
+ end_date (date): The end date.
48
+
49
+ Returns:
50
+ int: The total number of engagements.
51
+ """
52
+ results = run_query(
53
+ query=self.queries.get_engagement_count_query(),
54
+ params={
55
+ 'enterprise_customer_uuid': enterprise_customer_uuid,
56
+ 'start_date': start_date,
57
+ 'end_date': end_date,
58
+ }
59
+ )
60
+ return results[0][0]
61
+
62
+ def get_all_engagements(
63
+ self, enterprise_customer_uuid: UUID, start_date: date, end_date: date, limit: int, offset: int
64
+ ):
65
+ """
66
+ Get all engagement data for the given enterprise customer.
67
+
68
+ Arguments:
69
+ enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
70
+ start_date (date): The start date.
71
+ end_date (date): The end date.
72
+ limit (int): The maximum number of records to return.
73
+ offset (int): The number of records to skip.
74
+
75
+ Returns:
76
+ list<dict>: A list of dictionaries containing the engagement data.
77
+ """
78
+ return run_query(
79
+ query=self.queries.get_all_engagement_query(),
80
+ params={
81
+ 'enterprise_customer_uuid': enterprise_customer_uuid,
82
+ 'start_date': start_date,
83
+ 'end_date': end_date,
84
+ 'limit': limit,
85
+ 'offset': offset,
86
+ },
87
+ as_dict=True,
88
+ )
89
+
90
+ def get_top_courses_by_engagement(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
91
+ """
92
+ Get the top courses by user engagement for the given enterprise customer.
93
+
94
+ Arguments:
95
+ enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
96
+ start_date (date): The start date.
97
+ end_date (date): The end date.
98
+
99
+ Returns:
100
+ list<dict>: A list of dictionaries containing the course data.
101
+ """
102
+ return run_query(
103
+ query=self.queries.get_top_courses_by_engagement_query(),
104
+ params={
105
+ 'enterprise_customer_uuid': enterprise_customer_uuid,
106
+ 'start_date': start_date,
107
+ 'end_date': end_date,
108
+ },
109
+ as_dict=True,
110
+ )
111
+
112
+ def get_top_subjects_by_engagement(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
113
+ """
114
+ Get the top subjects by user engagement for the given enterprise customer.
115
+
116
+ Arguments:
117
+ enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
118
+ start_date (date): The start date.
119
+ end_date (date): The end date.
120
+
121
+ Returns:
122
+ list<dict>: A list of dictionaries containing the subject data.
123
+ """
124
+ return run_query(
125
+ query=self.queries.get_top_subjects_by_engagement_query(),
126
+ params={
127
+ 'enterprise_customer_uuid': enterprise_customer_uuid,
128
+ 'start_date': start_date,
129
+ 'end_date': end_date,
130
+ },
131
+ as_dict=True,
132
+ )
133
+
134
+ def get_engagement_time_series_data(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
135
+ """
136
+ Get the engagement time series data.
137
+
138
+ Arguments:
139
+ enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
140
+ start_date (date): The start date.
141
+ end_date (date): The end date.
142
+
143
+ Returns:
144
+ list<dict>: A list of dictionaries containing the engagement time series data.
145
+ """
146
+ return run_query(
147
+ query=self.queries.get_engagement_time_series_data_query(),
148
+ params={
149
+ 'enterprise_customer_uuid': enterprise_customer_uuid,
150
+ 'start_date': start_date,
151
+ 'end_date': end_date,
152
+ },
153
+ as_dict=True,
154
+ )
@@ -35,7 +35,7 @@ class FactEnrollmentAdminDashTable(BaseTable):
35
35
  'end_date': end_date,
36
36
  }
37
37
  )
38
- return results[0][0]
38
+ return int(results[0][0] or 0)
39
39
 
40
40
  def get_all_enrollments(
41
41
  self, enterprise_customer_uuid: UUID, start_date: date, end_date: date, limit: int, offset: int
@@ -132,7 +132,7 @@ class FactEnrollmentAdminDashTable(BaseTable):
132
132
  'end_date': end_date,
133
133
  }
134
134
  )
135
- return results[0][0]
135
+ return int(results[0][0] or 0)
136
136
 
137
137
  def get_top_courses_by_enrollments(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
138
138
  """
@@ -147,7 +147,7 @@ class FactEnrollmentAdminDashTable(BaseTable):
147
147
  list<dict>: A list of dictionaries containing the course key, course_title and enrollment count.
148
148
  """
149
149
  return run_query(
150
- query=self.queries.get_top_courses_enrollments_query(),
150
+ query=self.queries.get_top_courses_by_enrollments_query(),
151
151
  params={
152
152
  'enterprise_customer_uuid': enterprise_customer_uuid,
153
153
  'start_date': start_date,
@@ -199,3 +199,97 @@ class FactEnrollmentAdminDashTable(BaseTable):
199
199
  },
200
200
  as_dict=True,
201
201
  )
202
+
203
+ def get_all_completions(
204
+ self, enterprise_customer_uuid: UUID, start_date: date, end_date: date, limit: int, offset: int
205
+ ):
206
+ """
207
+ Get all completions for the given enterprise customer.
208
+
209
+ Arguments:
210
+ enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
211
+ start_date (date): The start date.
212
+ end_date (date): The end date.
213
+ limit (int): The maximum number of records to return.
214
+ offset (int): The number of records to skip.
215
+
216
+ Returns:
217
+ list<dict>: A list of dictionaries containing the completions data.
218
+ """
219
+ return run_query(
220
+ query=self.queries.get_all_completions_query(),
221
+ params={
222
+ 'enterprise_customer_uuid': enterprise_customer_uuid,
223
+ 'start_date': start_date,
224
+ 'end_date': end_date,
225
+ 'limit': limit,
226
+ 'offset': offset,
227
+ },
228
+ as_dict=True,
229
+ )
230
+
231
+ def get_top_courses_by_completions(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
232
+ """
233
+ Get the top courses by completion for the given enterprise customer.
234
+
235
+ Arguments:
236
+ enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
237
+ start_date (date): The start date.
238
+ end_date (date): The end date.
239
+
240
+ Returns:
241
+ list<dict>: A list of dictionaries containing the course key, course_title and completion count.
242
+ """
243
+ return run_query(
244
+ query=self.queries.get_top_courses_by_completions_query(),
245
+ params={
246
+ 'enterprise_customer_uuid': enterprise_customer_uuid,
247
+ 'start_date': start_date,
248
+ 'end_date': end_date,
249
+ },
250
+ as_dict=True,
251
+ )
252
+
253
+ def get_top_subjects_by_completions(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
254
+ """
255
+ Get the top subjects by completions for the given enterprise customer.
256
+
257
+ Arguments:
258
+ enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
259
+ start_date (date): The start date.
260
+ end_date (date): The end date.
261
+
262
+ Returns:
263
+ list<dict>: A list of dictionaries containing the subject and completion count.
264
+ """
265
+ return run_query(
266
+ query=self.queries.get_top_subjects_by_completions_query(),
267
+ params={
268
+ 'enterprise_customer_uuid': enterprise_customer_uuid,
269
+ 'start_date': start_date,
270
+ 'end_date': end_date,
271
+ },
272
+ as_dict=True,
273
+ )
274
+
275
+ def get_completions_time_series_data(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
276
+ """
277
+ Get the completions time series data for the given enterprise customer.
278
+
279
+ Arguments:
280
+ enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
281
+ start_date (date): The start date.
282
+ end_date (date): The end date.
283
+
284
+ Returns:
285
+ list<dict>: A list of dictionaries containing the date and completion count.
286
+ """
287
+ return run_query(
288
+ query=self.queries.get_completions_time_series_data_query(),
289
+ params={
290
+ 'enterprise_customer_uuid': enterprise_customer_uuid,
291
+ 'start_date': start_date,
292
+ 'end_date': end_date,
293
+ },
294
+ as_dict=True,
295
+ )
@@ -5,13 +5,7 @@ from uuid import UUID
5
5
 
6
6
  from rest_framework import serializers
7
7
 
8
- from enterprise_data.admin_analytics.constants import (
9
- Calculation,
10
- EngagementChart,
11
- EnrollmentChart,
12
- Granularity,
13
- ResponseType,
14
- )
8
+ from enterprise_data.admin_analytics.constants import Calculation, Granularity, ResponseType
15
9
  from enterprise_data.models import (
16
10
  EnterpriseAdminLearnerProgress,
17
11
  EnterpriseAdminSummarizeInsights,
@@ -315,51 +309,3 @@ class AdvanceAnalyticsQueryParamSerializer(serializers.Serializer): # pylint: d
315
309
  if value not in self.CALCULATION_CHOICES:
316
310
  raise serializers.ValidationError(f"Calculation must be one of {self.CALCULATION_CHOICES}")
317
311
  return value
318
-
319
-
320
- class AdvanceAnalyticsEnrollmentStatsSerializer(
321
- AdvanceAnalyticsQueryParamSerializer
322
- ): # pylint: disable=abstract-method
323
- """Serializer for validating Advance Analytics Enrollments Stats API"""
324
- CHART_TYPES = [
325
- EnrollmentChart.ENROLLMENTS_OVER_TIME.value,
326
- EnrollmentChart.TOP_COURSES_BY_ENROLLMENTS.value,
327
- EnrollmentChart.TOP_SUBJECTS_BY_ENROLLMENTS.value
328
- ]
329
-
330
- chart_type = serializers.CharField(required=False)
331
-
332
- def validate_chart_type(self, value):
333
- """
334
- Validate the chart_type value.
335
-
336
- Raises:
337
- serializers.ValidationError: If chart_type is not one of the valid choices
338
- """
339
- if value not in self.CHART_TYPES:
340
- raise serializers.ValidationError(f"chart_type must be one of {self.CHART_TYPES}")
341
- return value
342
-
343
-
344
- class AdvanceAnalyticsEngagementStatsSerializer(
345
- AdvanceAnalyticsQueryParamSerializer
346
- ): # pylint: disable=abstract-method
347
- """Serializer for validating Advance Analytics Engagements Stats API"""
348
- CHART_TYPES = [
349
- EngagementChart.ENGAGEMENTS_OVER_TIME.value,
350
- EngagementChart.TOP_COURSES_BY_ENGAGEMENTS.value,
351
- EngagementChart.TOP_SUBJECTS_BY_ENGAGEMENTS.value
352
- ]
353
-
354
- chart_type = serializers.CharField(required=False)
355
-
356
- def validate_chart_type(self, value):
357
- """
358
- Validate the chart_type value.
359
-
360
- Raises:
361
- serializers.ValidationError: If chart_type is not one of the valid choices
362
- """
363
- if value not in self.CHART_TYPES:
364
- raise serializers.ValidationError(f"chart_type must be one of {self.CHART_TYPES}")
365
- return value