edx-enterprise-data 9.8.1__tar.gz → 9.9.2__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 (204) hide show
  1. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/CHANGELOG.rst +12 -0
  2. {edx_enterprise_data-9.8.1/edx_enterprise_data.egg-info → edx_enterprise_data-9.9.2}/PKG-INFO +1 -1
  3. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2/edx_enterprise_data.egg-info}/PKG-INFO +1 -1
  4. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/edx_enterprise_data.egg-info/SOURCES.txt +1 -0
  5. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/__init__.py +1 -1
  6. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v1/serializers.py +51 -2
  7. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v1/views/enterprise_learner.py +47 -6
  8. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/clients.py +27 -0
  9. edx_enterprise_data-9.9.2/enterprise_data/migrations/0048_alter_enterpriseexecedlcmoduleperformance_avg_after_lo_score_and_more.py +23 -0
  10. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/models.py +2 -2
  11. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/renderers.py +1 -1
  12. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/LICENSE +0 -0
  13. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/MANIFEST.in +0 -0
  14. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/README.md +0 -0
  15. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/edx_enterprise_data.egg-info/dependency_links.txt +0 -0
  16. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/edx_enterprise_data.egg-info/not-zip-safe +0 -0
  17. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/edx_enterprise_data.egg-info/requires.txt +0 -0
  18. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/edx_enterprise_data.egg-info/top_level.txt +0 -0
  19. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/__init__.py +0 -0
  20. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/constants.py +0 -0
  21. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/data_loaders.py +0 -0
  22. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/database/__init__.py +0 -0
  23. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/database/queries/__init__.py +0 -0
  24. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/database/queries/fact_engagement_admin_dash.py +0 -0
  25. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/database/queries/fact_enrollment_admin_dash.py +0 -0
  26. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/database/queries/skills_daily_rollup_admin_dash.py +0 -0
  27. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/database/tables/__init__.py +0 -0
  28. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/database/tables/base.py +0 -0
  29. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/database/tables/fact_engagement_admin_dash.py +0 -0
  30. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/database/tables/fact_enrollment_admin_dash.py +0 -0
  31. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/database/tables/skills_daily_rollup_admin_dash.py +0 -0
  32. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/admin_analytics/database/utils.py +0 -0
  33. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/__init__.py +0 -0
  34. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/urls.py +0 -0
  35. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v0/__init__.py +0 -0
  36. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v0/serializers.py +0 -0
  37. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v0/urls.py +0 -0
  38. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v0/views.py +0 -0
  39. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v1/__init__.py +0 -0
  40. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v1/urls.py +0 -0
  41. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v1/views/__init__.py +0 -0
  42. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v1/views/analytics_completions.py +0 -0
  43. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v1/views/analytics_engagements.py +0 -0
  44. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v1/views/analytics_enrollments.py +0 -0
  45. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v1/views/analytics_leaderboard.py +0 -0
  46. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v1/views/base.py +0 -0
  47. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v1/views/enterprise_admin.py +0 -0
  48. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/api/v1/views/enterprise_offers.py +0 -0
  49. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/apps.py +0 -0
  50. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/cache/__init__.py +0 -0
  51. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/cache/decorators.py +0 -0
  52. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/constants.py +0 -0
  53. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/filters.py +0 -0
  54. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/fixtures/enterprise_enrollment.json +0 -0
  55. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/fixtures/enterprise_user.json +0 -0
  56. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/__init__.py +0 -0
  57. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/__init__.py +0 -0
  58. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/create_dummy_data.py +0 -0
  59. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/create_dummy_data_lpr_v1.py +0 -0
  60. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/create_enterprise_enrollment.py +0 -0
  61. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/create_enterprise_learner_enrollment_lpr_v1.py +0 -0
  62. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/create_enterprise_learner_lpr_v1.py +0 -0
  63. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/create_enterprise_offer.py +0 -0
  64. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/create_enterprise_user.py +0 -0
  65. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/pre_warm_analytics_cache.py +0 -0
  66. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/tests/__init__.py +0 -0
  67. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/tests/test_create_dummy_data_lpr_v1.py +0 -0
  68. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/tests/test_create_enterprise_enrollment.py +0 -0
  69. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/tests/test_create_enterprise_learner_enrollment_lpr_v1.py +0 -0
  70. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/tests/test_create_enterprise_learner_lpr_v1.py +0 -0
  71. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/tests/test_create_enterprise_user.py +0 -0
  72. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/management/commands/tests/test_pre_warm_analytics_cache.py +0 -0
  73. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0001_initial.py +0 -0
  74. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0002_auto_20180430_1358.py +0 -0
  75. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0003_auto_20180501_0603.py +0 -0
  76. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0004_auto_20180501_0928.py +0 -0
  77. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0004_auto_20180508_1652.py +0 -0
  78. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0005_auto_20180524_2204.py +0 -0
  79. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0006_auto_20180612_0336.py +0 -0
  80. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0007_auto_20180612_0534.py +0 -0
  81. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0008_auto_20180614_0108.py +0 -0
  82. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0009_auto_20180628_1152.py +0 -0
  83. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0010_enterpriseenrollment_created.py +0 -0
  84. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0011_enterpriseuser.py +0 -0
  85. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0012_auto_20180831_1930.py +0 -0
  86. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0013_auto_20180831_1931.py +0 -0
  87. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0014_enterpriseuser_created.py +0 -0
  88. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0015_auto_20180907_1757.py +0 -0
  89. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0016_auto_20180924_2138.py +0 -0
  90. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0017_enterpriseenrollment_unenrollment_timestamp.py +0 -0
  91. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0018_enterprisedatafeaturerole_enterprisedataroleassignment.py +0 -0
  92. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0019_add_enterprise_data_feature_roles.py +0 -0
  93. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0020_add_role_based_access_control_switch.py +0 -0
  94. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0021_auto_20190329_1241.py +0 -0
  95. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0022_remove_role_based_access_control_switch.py +0 -0
  96. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0023_enterpriselearner_enterpriselearnerenrollment.py +0 -0
  97. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0024_auto_20210602_1811.py +0 -0
  98. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0025_auto_20210703_1854.py +0 -0
  99. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0026_auto_20210916_0414.py +0 -0
  100. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0027_enterpriselearnerenrollment_total_learning_time_seconds.py +0 -0
  101. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0028_enterpriselearnerenrollment_offer_id.py +0 -0
  102. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0029_enterpriseoffer.py +0 -0
  103. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0030_auto_20230609_1353.py +0 -0
  104. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0031_auto_20230615_0705.py +0 -0
  105. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0032_auto_20230704_0818.py +0 -0
  106. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0033_enterpriseadminlearnerprogress_enterpriseadminsummarizeinsights.py +0 -0
  107. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0034_auto_20230907_0834.py +0 -0
  108. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0035_auto_20230907_1154.py +0 -0
  109. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0036_enterprisesubsidybudget_subsidy_access_policy_display_name.py +0 -0
  110. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0037_alter_enterpriseenrollment_consent_granted.py +0 -0
  111. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0038_enterpriseoffer_export_timestamp.py +0 -0
  112. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0039_auto_20240212_1403.py +0 -0
  113. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0040_auto_20240718_0536_squashed_0043_alter_enterpriselearnerenrollment_enterprise_enrollment_id.py +0 -0
  114. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0044_enterpriseexecedlcmoduleperformance.py +0 -0
  115. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0045_alter_enterpriseexecedlcmoduleperformance_options_and_more.py +0 -0
  116. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0046_enterprisegroupmembership.py +0 -0
  117. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/0047_enterpriseexecedlcmoduleperformance_avg_after_lo_score_and_more.py +0 -0
  118. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/migrations/__init__.py +0 -0
  119. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/paginators.py +0 -0
  120. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/settings/__init__.py +0 -0
  121. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/settings/test.py +0 -0
  122. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/signals.py +0 -0
  123. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/__init__.py +0 -0
  124. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/admin_analytics/__init__.py +0 -0
  125. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/admin_analytics/mock_analytics_data.py +0 -0
  126. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/admin_analytics/mock_enrollments.py +0 -0
  127. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/admin_analytics/test_analytics_engagements.py +0 -0
  128. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/admin_analytics/test_analytics_enrollments.py +0 -0
  129. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/admin_analytics/test_analytics_leaderboard.py +0 -0
  130. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/admin_analytics/test_data_loaders.py +0 -0
  131. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/admin_analytics/test_enterprise_completions.py +0 -0
  132. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/api/__init__.py +0 -0
  133. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/api/v0/__init__.py +0 -0
  134. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/api/v0/test_serializers.py +0 -0
  135. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/api/v1/__init__.py +0 -0
  136. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/api/v1/test_serializers.py +0 -0
  137. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/api/v1/test_views.py +0 -0
  138. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/api/v1/views/__init__.py +0 -0
  139. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/api/v1/views/test_enterprise_admin.py +0 -0
  140. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/factories.py +0 -0
  141. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/mixins.py +0 -0
  142. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/test_clients.py +0 -0
  143. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/test_filters.py +0 -0
  144. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/test_models.py +0 -0
  145. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/test_utils.py +0 -0
  146. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/tests/test_views.py +0 -0
  147. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/urls.py +0 -0
  148. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data/utils.py +0 -0
  149. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/__init__.py +0 -0
  150. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/admin.py +0 -0
  151. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/apps.py +0 -0
  152. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/constants.py +0 -0
  153. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/migrations/0001_initial.py +0 -0
  154. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/migrations/0002_add_enterprise_data_feature_roles.py +0 -0
  155. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/migrations/0003_add_role_based_access_control_switch.py +0 -0
  156. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/migrations/0004_enterprisedataroleassignment_enterprise_id.py +0 -0
  157. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/migrations/0005_turn_on_role_based_access_control_switch.py +0 -0
  158. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/migrations/0006_remove_role_based_access_control_switch.py +0 -0
  159. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/migrations/0007_enterprisedataroleassignment_applies_to_all_contexts.py +0 -0
  160. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/migrations/__init__.py +0 -0
  161. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/models.py +0 -0
  162. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/rules.py +0 -0
  163. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/tests/__init__.py +0 -0
  164. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/tests/factories.py +0 -0
  165. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_data_roles/tests/test_models.py +0 -0
  166. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/__init__.py +0 -0
  167. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/clients/__init__.py +0 -0
  168. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/clients/enterprise.py +0 -0
  169. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/clients/s3.py +0 -0
  170. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/clients/snowflake.py +0 -0
  171. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/clients/vertica.py +0 -0
  172. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/delivery_method.py +0 -0
  173. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/external_resource_link_report.py +0 -0
  174. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/fixtures/__init__.py +0 -0
  175. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/fixtures/enterprise_customer_reporting.json +0 -0
  176. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/reporter.py +0 -0
  177. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/send_enterprise_reports.py +0 -0
  178. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/tests/__init__.py +0 -0
  179. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/tests/test_clients.py +0 -0
  180. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/tests/test_delivery_method.py +0 -0
  181. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/tests/test_enterprise_client.py +0 -0
  182. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/tests/test_external_link_report.py +0 -0
  183. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/tests/test_reporter.py +0 -0
  184. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/tests/test_send_enterprise_reports.py +0 -0
  185. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/tests/test_utils.py +0 -0
  186. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/tests/test_vertica_client.py +0 -0
  187. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/tests/utils.py +0 -0
  188. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/enterprise_reporting/utils.py +0 -0
  189. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/base.in +0 -0
  190. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/base.txt +0 -0
  191. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/ci.txt +0 -0
  192. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/common_constraints.txt +0 -0
  193. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/constraints.txt +0 -0
  194. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/dev.txt +0 -0
  195. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/django.txt +0 -0
  196. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/pip.txt +0 -0
  197. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/pip_tools.txt +0 -0
  198. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/quality.txt +0 -0
  199. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/reporting.in +0 -0
  200. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/test-master.txt +0 -0
  201. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/test-reporting.txt +0 -0
  202. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/requirements/test.txt +0 -0
  203. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/setup.cfg +0 -0
  204. {edx_enterprise_data-9.8.1 → edx_enterprise_data-9.9.2}/setup.py +0 -0
@@ -16,6 +16,18 @@ Unreleased
16
16
 
17
17
  =========================
18
18
 
19
+ [10.9.2] - 2025-03-11
20
+ ---------------------
21
+ * feat: support flex groups in csv report on LPR.
22
+
23
+ [10.9.0] - 2025-02-24
24
+ ---------------------
25
+ * feat: get groups data from membership endpoint using enterprise client.
26
+
27
+ [10.8.1] - 2025-02-20
28
+ ---------------------
29
+ * fix: Limited accuracy of floating pointing numbers to 2 places.
30
+
19
31
  [10.8.1] - 2025-02-20
20
32
  ---------------------
21
33
  * feat: Added 2 new columns in module performance report model and exposed them via associated REST API.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edx-enterprise-data
3
- Version: 9.8.1
3
+ Version: 9.9.2
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.8.1
3
+ Version: 9.9.2
4
4
  Summary: Enterprise Reporting
5
5
  Home-page: https://github.com/openedx/edx-enterprise-data
6
6
  Author: edX
@@ -118,6 +118,7 @@ enterprise_data/migrations/0044_enterpriseexecedlcmoduleperformance.py
118
118
  enterprise_data/migrations/0045_alter_enterpriseexecedlcmoduleperformance_options_and_more.py
119
119
  enterprise_data/migrations/0046_enterprisegroupmembership.py
120
120
  enterprise_data/migrations/0047_enterpriseexecedlcmoduleperformance_avg_after_lo_score_and_more.py
121
+ enterprise_data/migrations/0048_alter_enterpriseexecedlcmoduleperformance_avg_after_lo_score_and_more.py
121
122
  enterprise_data/migrations/__init__.py
122
123
  enterprise_data/settings/__init__.py
123
124
  enterprise_data/settings/test.py
@@ -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.8.1"
5
+ __version__ = "9.9.2"
@@ -6,6 +6,7 @@ from uuid import UUID
6
6
  from rest_framework import serializers
7
7
 
8
8
  from enterprise_data.admin_analytics.constants import ResponseType
9
+ from enterprise_data.cache.decorators import cache_it
9
10
  from enterprise_data.models import (
10
11
  EnterpriseAdminLearnerProgress,
11
12
  EnterpriseAdminSummarizeInsights,
@@ -26,6 +27,8 @@ class EnterpriseLearnerEnrollmentSerializer(serializers.ModelSerializer):
26
27
  course_api_url = serializers.SerializerMethodField()
27
28
  enterprise_user_id = serializers.SerializerMethodField()
28
29
  total_learning_time_hours = serializers.SerializerMethodField()
30
+ enterprise_flex_group_name = serializers.SerializerMethodField()
31
+ enterprise_flex_group_uuid = serializers.SerializerMethodField()
29
32
 
30
33
  class Meta:
31
34
  model = EnterpriseLearnerEnrollment
@@ -44,8 +47,9 @@ class EnterpriseLearnerEnrollmentSerializer(serializers.ModelSerializer):
44
47
  'last_activity_date', 'progress_status', 'passed_date', 'current_grade',
45
48
  'letter_grade', 'enterprise_user_id', 'user_email', 'user_account_creation_date',
46
49
  'user_country_code', 'user_username', 'user_first_name', 'user_last_name', 'enterprise_name',
47
- 'enterprise_customer_uuid', 'enterprise_sso_uid', 'created', 'course_api_url', 'total_learning_time_hours',
48
- 'is_subsidy', 'course_product_line', 'budget_id', 'enterprise_group_name', 'enterprise_group_uuid',
50
+ 'enterprise_customer_uuid', 'enterprise_sso_uid', 'created', 'course_api_url',
51
+ 'total_learning_time_hours', 'is_subsidy', 'course_product_line', 'budget_id',
52
+ 'enterprise_flex_group_name', 'enterprise_flex_group_uuid',
49
53
  )
50
54
 
51
55
  def get_course_api_url(self, obj):
@@ -62,6 +66,51 @@ class EnterpriseLearnerEnrollmentSerializer(serializers.ModelSerializer):
62
66
  """Returns the learners total learning time in hours"""
63
67
  return round((obj.total_learning_time_seconds or 0.0)/3600.0, 2)
64
68
 
69
+ @cache_it()
70
+ def _get_flex_groups(self, obj):
71
+ """
72
+ Returns list of tuples containing group (name, uuid) pairs for the learner.
73
+ This is cached to prevent duplicate database queries.
74
+ """
75
+ enterprise_user_id = obj.enterprise_user_id
76
+
77
+ if not enterprise_user_id:
78
+ return []
79
+
80
+ # Get all group memberships for this user in a single query
81
+ # Order by name for consistent ordering
82
+ return list(
83
+ EnterpriseGroupMembership.objects.filter(
84
+ enterprise_customer_user_id=enterprise_user_id,
85
+ membership_is_removed=False,
86
+ group_is_removed=False,
87
+ group_type="flex",
88
+ )
89
+ .order_by("enterprise_group_name")
90
+ .values_list("enterprise_group_name", "enterprise_group_uuid")
91
+ .distinct()
92
+ )
93
+
94
+ def get_enterprise_flex_group_name(self, obj):
95
+ """Returns a comma-separated list of enterprise group names that the learner is associated with"""
96
+ groups = self._get_flex_groups(obj)
97
+
98
+ if not groups:
99
+ return obj.enterprise_group_name
100
+
101
+ # Return comma-separated list of group names (first element of each tuple)
102
+ return ', '.join(group[0] for group in groups)
103
+
104
+ def get_enterprise_flex_group_uuid(self, obj):
105
+ """Returns a comma-separated list of enterprise group UUIDs that the learner is associated with"""
106
+ groups = self._get_flex_groups(obj)
107
+
108
+ if not groups:
109
+ return obj.enterprise_group_uuid
110
+
111
+ # Return comma-separated list of group UUIDs (second element of each tuple)
112
+ return ', '.join(str(group[1]) for group in groups)
113
+
65
114
 
66
115
  class EnterpriseSubsidyBudgetSerializer(serializers.ModelSerializer):
67
116
  """
@@ -8,6 +8,7 @@ from uuid import UUID
8
8
 
9
9
  from rest_framework import filters, viewsets
10
10
  from rest_framework.decorators import action
11
+ from rest_framework.exceptions import NotFound
11
12
  from rest_framework.response import Response
12
13
 
13
14
  from django.conf import settings
@@ -20,6 +21,7 @@ from django.utils import timezone
20
21
 
21
22
  from enterprise_data.admin_analytics.database.utils import LOGGER
22
23
  from enterprise_data.api.v1 import serializers
24
+ from enterprise_data.clients import EnterpriseApiClient
23
25
  from enterprise_data.models import EnterpriseGroupMembership, EnterpriseLearner, EnterpriseLearnerEnrollment
24
26
  from enterprise_data.paginators import EnterpriseEnrollmentsPagination
25
27
  from enterprise_data.renderers import EnrollmentsCSVRenderer
@@ -176,12 +178,51 @@ class EnterpriseLearnerEnrollmentViewSet(EnterpriseViewSetMixin, viewsets.ReadOn
176
178
 
177
179
  group_uuid = query_filters.get('group_uuid')
178
180
  if group_uuid:
179
- flex_group_exists = EnterpriseGroupMembership.objects.filter(
180
- enterprise_customer_user_id=OuterRef('enterprise_user_id'),
181
- enterprise_group_uuid=group_uuid,
182
- group_type='flex'
183
- )
184
- queryset = queryset.filter(Exists(flex_group_exists))
181
+ queryset = self.filter_by_group_uuid(queryset, group_uuid)
182
+
183
+ return queryset
184
+
185
+ def filter_by_group_uuid(self, queryset, group_uuid):
186
+ """
187
+ Filters the queryset based on the provided group_uuid. If no records are found,
188
+ it attempts to fetch group learners from the API and filter the queryset again.
189
+
190
+ Args:
191
+ queryset (QuerySet): The initial queryset to filter.
192
+ group_uuid (str): The UUID of the group to filter by.
193
+
194
+ Returns:
195
+ QuerySet: The filtered queryset.
196
+ """
197
+ flex_group_exists = EnterpriseGroupMembership.objects.filter(
198
+ enterprise_customer_user_id=OuterRef('enterprise_user_id'),
199
+ enterprise_group_uuid=group_uuid,
200
+ group_type='flex'
201
+ )
202
+
203
+ # First, filter the queryset using flex_group_exists
204
+ filtered_queryset = queryset.filter(Exists(flex_group_exists))
205
+
206
+ # If no records are found, attempt to fetch group_learners from the API
207
+ if not filtered_queryset.exists():
208
+ try:
209
+ enterprise_api_client = EnterpriseApiClient(
210
+ settings.BACKEND_SERVICE_EDX_OAUTH2_PROVIDER_URL,
211
+ settings.BACKEND_SERVICE_EDX_OAUTH2_KEY,
212
+ settings.BACKEND_SERVICE_EDX_OAUTH2_SECRET,
213
+ )
214
+ group_learners = enterprise_api_client.get_enterprise_group_learners(group_uuid)
215
+ if group_learners:
216
+ group_learners_ids = [learner['enterprise_customer_user_id'] for learner in group_learners]
217
+ queryset = queryset.filter(enterprise_user_id__in=group_learners_ids)
218
+ else:
219
+ LOGGER.warning(f"No group learners found for group: {group_uuid}")
220
+ raise NotFound(f"No learners found for group: {group_uuid}")
221
+ except (Exception) as e: # pylint: disable=broad-exception-caught
222
+ LOGGER.error("Failed to fetch group learners from API: %s", e)
223
+ queryset = queryset.none() # API call failed or unexpected error, return an empty queryset
224
+ else:
225
+ queryset = filtered_queryset
185
226
 
186
227
  return queryset
187
228
 
@@ -101,3 +101,30 @@ class EnterpriseApiClient(OAuthAPIClient):
101
101
  TieredCache.set_all_tiers(cache_key, data, DEFAULT_REPORTING_CACHE_TIMEOUT)
102
102
 
103
103
  return data
104
+
105
+ def get_enterprise_group_learners(self, group_uuid):
106
+ """
107
+ Get the learners associated with a given enterprise group.
108
+
109
+ Returns: list of learners or None if unable to retrieve or no learners exist
110
+ """
111
+ LOGGER.info(f'[EnterpriseApiClient] getting learners for enterprise group:{group_uuid}')
112
+ url = urljoin(self.API_BASE_URL, f'enterprise-group/{group_uuid}/learners/')
113
+ all_learners = []
114
+
115
+ try:
116
+ while url:
117
+ response = self.get(url)
118
+ response.raise_for_status()
119
+ data = response.json()
120
+ all_learners.extend(data.get('results', []))
121
+ url = data.get('next') # Get the URL for the next page, if any
122
+
123
+ except (HTTPError, RequestException) as exc:
124
+ LOGGER.warning(
125
+ "[Data Overview Failure] Unable to retrieve Enterprise Group Learners details. "
126
+ f"Group: {group_uuid}, Exception: {exc}"
127
+ )
128
+ return None
129
+
130
+ return all_learners
@@ -0,0 +1,23 @@
1
+ # Generated by Django 4.2.15 on 2025-02-25 08:17
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('enterprise_data', '0047_enterpriseexecedlcmoduleperformance_avg_after_lo_score_and_more'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='enterpriseexecedlcmoduleperformance',
15
+ name='avg_after_lo_score',
16
+ field=models.DecimalField(decimal_places=2, max_digits=38, null=True),
17
+ ),
18
+ migrations.AlterField(
19
+ model_name='enterpriseexecedlcmoduleperformance',
20
+ name='avg_before_lo_score',
21
+ field=models.DecimalField(decimal_places=2, max_digits=38, null=True),
22
+ ),
23
+ ]
@@ -559,8 +559,8 @@ class EnterpriseExecEdLCModulePerformance(models.Model):
559
559
  discussion_forum_activities_total_count = models.PositiveIntegerField(null=True)
560
560
  pass_grade = models.DecimalField(max_digits=38, decimal_places=2, null=True)
561
561
  question_name = models.CharField(max_length=500, null=True)
562
- avg_before_lo_score = models.DecimalField(max_digits=38, decimal_places=6, null=True)
563
- avg_after_lo_score = models.DecimalField(max_digits=38, decimal_places=6, null=True)
562
+ avg_before_lo_score = models.DecimalField(max_digits=38, decimal_places=2, null=True)
563
+ avg_after_lo_score = models.DecimalField(max_digits=38, decimal_places=2, null=True)
564
564
 
565
565
  def __str__(self):
566
566
  """
@@ -27,7 +27,7 @@ class EnrollmentsCSVRenderer(CSVStreamingRenderer):
27
27
  'letter_grade', 'enterprise_user_id', 'user_email', 'user_account_creation_date',
28
28
  'user_country_code', 'user_username', 'user_first_name', 'user_last_name', 'enterprise_name',
29
29
  'enterprise_customer_uuid', 'enterprise_sso_uid', 'created', 'course_api_url', 'total_learning_time_hours',
30
- 'is_subsidy', 'course_product_line', 'budget_id', 'enterprise_group_name', 'enterprise_group_uuid',
30
+ 'is_subsidy', 'course_product_line', 'budget_id', 'enterprise_flex_group_name', 'enterprise_flex_group_uuid',
31
31
  ]
32
32
 
33
33