edx-enterprise-data 10.0.1__tar.gz → 10.3.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.
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/CHANGELOG.rst +13 -0
- {edx_enterprise_data-10.0.1/edx_enterprise_data.egg-info → edx_enterprise_data-10.3.0}/PKG-INFO +1 -1
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0/edx_enterprise_data.egg-info}/PKG-INFO +1 -1
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/edx_enterprise_data.egg-info/SOURCES.txt +2 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/__init__.py +1 -1
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/database/queries/fact_engagement_admin_dash.py +107 -12
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/database/queries/fact_enrollment_admin_dash.py +113 -24
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/database/tables/fact_engagement_admin_dash.py +71 -6
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/database/tables/fact_enrollment_admin_dash.py +17 -1
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v1/views/analytics_completions.py +3 -3
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v1/views/analytics_engagements.py +3 -3
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v1/views/analytics_enrollments.py +3 -3
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v1/views/analytics_leaderboard.py +8 -6
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v1/views/enterprise_admin.py +2 -2
- edx_enterprise_data-10.3.0/enterprise_data/management/commands/pre_warm_analytics_cache.py +219 -0
- edx_enterprise_data-10.3.0/enterprise_data/management/commands/tests/test_pre_warm_analytics_cache.py +60 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/utils.py +17 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/rules.py +1 -1
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/base.txt +8 -7
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/ci.txt +1 -1
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/common_constraints.txt +4 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/dev.txt +19 -11
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/pip.txt +4 -2
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/quality.txt +20 -12
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/test-master.txt +9 -8
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/test-reporting.txt +7 -6
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/test.txt +9 -8
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/LICENSE +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/MANIFEST.in +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/README.md +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/edx_enterprise_data.egg-info/dependency_links.txt +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/edx_enterprise_data.egg-info/not-zip-safe +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/edx_enterprise_data.egg-info/requires.txt +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/edx_enterprise_data.egg-info/top_level.txt +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/constants.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/data_loaders.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/database/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/database/queries/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/database/queries/skills_daily_rollup_admin_dash.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/database/tables/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/database/tables/base.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/database/tables/skills_daily_rollup_admin_dash.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/admin_analytics/database/utils.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/urls.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v0/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v0/serializers.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v0/urls.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v0/views.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v1/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v1/serializers.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v1/urls.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v1/views/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v1/views/base.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v1/views/enterprise_learner.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/api/v1/views/enterprise_offers.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/apps.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/cache/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/cache/decorators.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/clients.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/constants.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/filters.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/fixtures/enterprise_enrollment.json +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/fixtures/enterprise_user.json +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/create_dummy_data.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/create_dummy_data_lpr_v1.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/create_enterprise_enrollment.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/create_enterprise_learner_enrollment_lpr_v1.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/create_enterprise_learner_lpr_v1.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/create_enterprise_offer.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/create_enterprise_user.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/tests/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/tests/test_create_dummy_data_lpr_v1.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/tests/test_create_enterprise_enrollment.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/tests/test_create_enterprise_learner_enrollment_lpr_v1.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/tests/test_create_enterprise_learner_lpr_v1.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/management/commands/tests/test_create_enterprise_user.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0001_initial.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0002_auto_20180430_1358.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0003_auto_20180501_0603.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0004_auto_20180501_0928.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0004_auto_20180508_1652.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0005_auto_20180524_2204.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0006_auto_20180612_0336.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0007_auto_20180612_0534.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0008_auto_20180614_0108.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0009_auto_20180628_1152.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0010_enterpriseenrollment_created.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0011_enterpriseuser.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0012_auto_20180831_1930.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0013_auto_20180831_1931.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0014_enterpriseuser_created.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0015_auto_20180907_1757.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0016_auto_20180924_2138.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0017_enterpriseenrollment_unenrollment_timestamp.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0018_enterprisedatafeaturerole_enterprisedataroleassignment.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0019_add_enterprise_data_feature_roles.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0020_add_role_based_access_control_switch.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0021_auto_20190329_1241.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0022_remove_role_based_access_control_switch.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0023_enterpriselearner_enterpriselearnerenrollment.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0024_auto_20210602_1811.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0025_auto_20210703_1854.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0026_auto_20210916_0414.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0027_enterpriselearnerenrollment_total_learning_time_seconds.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0028_enterpriselearnerenrollment_offer_id.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0029_enterpriseoffer.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0030_auto_20230609_1353.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0031_auto_20230615_0705.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0032_auto_20230704_0818.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0033_enterpriseadminlearnerprogress_enterpriseadminsummarizeinsights.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0034_auto_20230907_0834.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0035_auto_20230907_1154.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0036_enterprisesubsidybudget_subsidy_access_policy_display_name.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0037_alter_enterpriseenrollment_consent_granted.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0038_enterpriseoffer_export_timestamp.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0039_auto_20240212_1403.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0040_auto_20240718_0536_squashed_0043_alter_enterpriselearnerenrollment_enterprise_enrollment_id.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/0044_enterpriseexecedlcmoduleperformance.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/migrations/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/models.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/paginators.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/renderers.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/settings/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/settings/test.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/signals.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/admin_analytics/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/admin_analytics/mock_analytics_data.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/admin_analytics/mock_enrollments.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/admin_analytics/test_analytics_engagements.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/admin_analytics/test_analytics_enrollments.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/admin_analytics/test_analytics_leaderboard.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/admin_analytics/test_data_loaders.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/admin_analytics/test_enterprise_completions.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/api/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/api/v0/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/api/v0/test_serializers.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/api/v1/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/api/v1/test_serializers.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/api/v1/test_views.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/api/v1/views/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/api/v1/views/test_enterprise_admin.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/factories.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/mixins.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/test_clients.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/test_filters.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/test_models.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/test_utils.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/tests/test_views.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data/urls.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/admin.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/apps.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/constants.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/migrations/0001_initial.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/migrations/0002_add_enterprise_data_feature_roles.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/migrations/0003_add_role_based_access_control_switch.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/migrations/0004_enterprisedataroleassignment_enterprise_id.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/migrations/0005_turn_on_role_based_access_control_switch.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/migrations/0006_remove_role_based_access_control_switch.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/migrations/0007_enterprisedataroleassignment_applies_to_all_contexts.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/migrations/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/models.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/tests/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/tests/factories.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_data_roles/tests/test_models.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/clients/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/clients/enterprise.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/clients/s3.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/clients/snowflake.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/clients/vertica.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/delivery_method.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/external_resource_link_report.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/fixtures/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/fixtures/enterprise_customer_reporting.json +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/reporter.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/send_enterprise_reports.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/tests/__init__.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/tests/test_clients.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/tests/test_delivery_method.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/tests/test_enterprise_client.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/tests/test_external_link_report.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/tests/test_reporter.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/tests/test_send_enterprise_reports.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/tests/test_utils.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/tests/test_vertica_client.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/tests/utils.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/enterprise_reporting/utils.py +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/base.in +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/constraints.txt +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/django.txt +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/pip_tools.txt +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/requirements/reporting.in +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/setup.cfg +0 -0
- {edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/setup.py +0 -0
@@ -16,6 +16,19 @@ Unreleased
|
|
16
16
|
|
17
17
|
=========================
|
18
18
|
|
19
|
+
[10.3.0] - 2024-11-13
|
20
|
+
---------------------
|
21
|
+
* Re-write top 10 charts queries for Enrollments, Engagements and Completions
|
22
|
+
|
23
|
+
[10.2.0] - 2024-11-12
|
24
|
+
---------------------
|
25
|
+
* Fixed null email issue for leaderboard.
|
26
|
+
|
27
|
+
|
28
|
+
[10.1.0] - 2024-10-29
|
29
|
+
---------------------
|
30
|
+
* Added management command to pre-warm analytics data.
|
31
|
+
|
19
32
|
[10.0.1] - 2024-10-25
|
20
33
|
---------------------
|
21
34
|
* Same as ``10.0.0``
|
{edx_enterprise_data-10.0.1 → edx_enterprise_data-10.3.0}/edx_enterprise_data.egg-info/SOURCES.txt
RENAMED
@@ -65,12 +65,14 @@ enterprise_data/management/commands/create_enterprise_learner_enrollment_lpr_v1.
|
|
65
65
|
enterprise_data/management/commands/create_enterprise_learner_lpr_v1.py
|
66
66
|
enterprise_data/management/commands/create_enterprise_offer.py
|
67
67
|
enterprise_data/management/commands/create_enterprise_user.py
|
68
|
+
enterprise_data/management/commands/pre_warm_analytics_cache.py
|
68
69
|
enterprise_data/management/commands/tests/__init__.py
|
69
70
|
enterprise_data/management/commands/tests/test_create_dummy_data_lpr_v1.py
|
70
71
|
enterprise_data/management/commands/tests/test_create_enterprise_enrollment.py
|
71
72
|
enterprise_data/management/commands/tests/test_create_enterprise_learner_enrollment_lpr_v1.py
|
72
73
|
enterprise_data/management/commands/tests/test_create_enterprise_learner_lpr_v1.py
|
73
74
|
enterprise_data/management/commands/tests/test_create_enterprise_user.py
|
75
|
+
enterprise_data/management/commands/tests/test_pre_warm_analytics_cache.py
|
74
76
|
enterprise_data/migrations/0001_initial.py
|
75
77
|
enterprise_data/migrations/0002_auto_20180430_1358.py
|
76
78
|
enterprise_data/migrations/0003_auto_20180501_0603.py
|
@@ -48,7 +48,7 @@ class FactEngagementAdminDashQueries:
|
|
48
48
|
"""
|
49
49
|
|
50
50
|
@staticmethod
|
51
|
-
def get_top_courses_by_engagement_query(record_count=
|
51
|
+
def get_top_courses_by_engagement_query(record_count=10):
|
52
52
|
"""
|
53
53
|
Get the query to fetch the learning time in hours by courses.
|
54
54
|
|
@@ -61,16 +61,40 @@ class FactEngagementAdminDashQueries:
|
|
61
61
|
(str): Query to fetch the learning time in hours by courses for the top courses by user engagement.
|
62
62
|
"""
|
63
63
|
return f"""
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
WITH filtered_data AS (
|
65
|
+
SELECT
|
66
|
+
course_key,
|
67
|
+
course_title,
|
68
|
+
enroll_type,
|
69
|
+
(learning_time_seconds / 60.0 / 60.0) AS learning_time_hours,
|
70
|
+
activity_date
|
71
|
+
FROM fact_enrollment_engagement_day_admin_dash
|
72
|
+
WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
|
67
73
|
activity_date BETWEEN %(start_date)s AND %(end_date)s
|
68
|
-
|
69
|
-
|
74
|
+
),
|
75
|
+
top_10_courses AS (
|
76
|
+
SELECT
|
77
|
+
course_key,
|
78
|
+
SUM(learning_time_hours) as total_learning_time
|
79
|
+
FROM filtered_data
|
80
|
+
GROUP BY course_key
|
81
|
+
ORDER BY total_learning_time DESC
|
82
|
+
LIMIT {record_count}
|
83
|
+
)
|
84
|
+
SELECT
|
85
|
+
d.course_key,
|
86
|
+
d.course_title,
|
87
|
+
d.enroll_type,
|
88
|
+
ROUND(SUM(d.learning_time_hours)) AS learning_time_hours
|
89
|
+
FROM filtered_data d
|
90
|
+
JOIN top_10_courses tc
|
91
|
+
ON d.course_key = tc.course_key
|
92
|
+
GROUP BY d.course_key, d.course_title, d.enroll_type
|
93
|
+
ORDER BY total_learning_time DESC;
|
70
94
|
"""
|
71
95
|
|
72
96
|
@staticmethod
|
73
|
-
def get_top_subjects_by_engagement_query(record_count=
|
97
|
+
def get_top_subjects_by_engagement_query(record_count=10):
|
74
98
|
"""
|
75
99
|
Get the query to fetch the learning time in hours by subjects.
|
76
100
|
|
@@ -83,12 +107,34 @@ class FactEngagementAdminDashQueries:
|
|
83
107
|
(str): Query to fetch the learning time in hours by subjects for the top subjects by user engagement.
|
84
108
|
"""
|
85
109
|
return f"""
|
86
|
-
|
87
|
-
|
88
|
-
|
110
|
+
WITH filtered_data AS (
|
111
|
+
SELECT
|
112
|
+
course_subject,
|
113
|
+
enroll_type,
|
114
|
+
(learning_time_seconds / 60.0 / 60.0) AS learning_time_hours,
|
115
|
+
activity_date
|
116
|
+
FROM fact_enrollment_engagement_day_admin_dash
|
117
|
+
WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
|
89
118
|
activity_date BETWEEN %(start_date)s AND %(end_date)s
|
90
|
-
|
91
|
-
|
119
|
+
),
|
120
|
+
top_10_subjects AS (
|
121
|
+
SELECT
|
122
|
+
course_subject,
|
123
|
+
SUM(learning_time_hours) as total_learning_time
|
124
|
+
FROM filtered_data
|
125
|
+
GROUP BY course_subject
|
126
|
+
ORDER BY total_learning_time DESC
|
127
|
+
LIMIT {record_count}
|
128
|
+
)
|
129
|
+
SELECT
|
130
|
+
d.course_subject,
|
131
|
+
d.enroll_type,
|
132
|
+
ROUND(SUM(d.learning_time_hours)) AS learning_time_hours
|
133
|
+
FROM filtered_data d
|
134
|
+
JOIN top_10_subjects ts
|
135
|
+
ON d.course_subject = ts.course_subject
|
136
|
+
GROUP BY d.course_subject, d.enroll_type
|
137
|
+
ORDER BY total_learning_time DESC;
|
92
138
|
"""
|
93
139
|
|
94
140
|
@staticmethod
|
@@ -163,6 +209,55 @@ class FactEngagementAdminDashQueries:
|
|
163
209
|
GROUP BY email;
|
164
210
|
"""
|
165
211
|
|
212
|
+
@staticmethod
|
213
|
+
def get_engagement_data_for_leaderboard_null_email_only_query():
|
214
|
+
"""
|
215
|
+
Get the query to fetch the engagement data for leaderboard for NULL emails only.
|
216
|
+
|
217
|
+
Query should fetch the engagement data for like learning time, session length of
|
218
|
+
the enterprise learners to show in the leaderboard.
|
219
|
+
|
220
|
+
Returns:
|
221
|
+
(str): Query to fetch the engagement data for leaderboard.
|
222
|
+
"""
|
223
|
+
return """
|
224
|
+
SELECT
|
225
|
+
email,
|
226
|
+
ROUND(SUM(learning_time_seconds) / 3600, 1) as learning_time_hours,
|
227
|
+
SUM(is_engaged) as session_count,
|
228
|
+
CASE
|
229
|
+
WHEN SUM(is_engaged) = 0 THEN 0.0
|
230
|
+
ELSE ROUND(SUM(learning_time_seconds) / 3600 / SUM(is_engaged), 1)
|
231
|
+
END AS average_session_length
|
232
|
+
FROM fact_enrollment_engagement_day_admin_dash
|
233
|
+
WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
|
234
|
+
(activity_date BETWEEN %(start_date)s AND %(end_date)s) AND
|
235
|
+
is_engaged = 1 AND
|
236
|
+
email is NULL
|
237
|
+
GROUP BY email;
|
238
|
+
"""
|
239
|
+
|
240
|
+
@staticmethod
|
241
|
+
def get_completion_data_for_leaderboard_null_email_only_query():
|
242
|
+
"""
|
243
|
+
Get the query to fetch the completions data for leaderboard for NULL emails.
|
244
|
+
|
245
|
+
Query should fetch the completion data for like course completion count of
|
246
|
+
the enterprise learners to show in the leaderboard.
|
247
|
+
|
248
|
+
Returns:
|
249
|
+
(list<str>): Query to fetch the completions data for leaderboard.
|
250
|
+
"""
|
251
|
+
return """
|
252
|
+
SELECT email, count(course_key) as course_completion_count
|
253
|
+
FROM fact_enrollment_admin_dash
|
254
|
+
WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
|
255
|
+
(passed_date BETWEEN %(start_date)s AND %(end_date)s) AND
|
256
|
+
has_passed = 1 AND
|
257
|
+
email is NULL
|
258
|
+
GROUP BY email;
|
259
|
+
"""
|
260
|
+
|
166
261
|
@staticmethod
|
167
262
|
def get_leaderboard_data_count_query():
|
168
263
|
"""
|
@@ -7,6 +7,18 @@ class FactEnrollmentAdminDashQueries:
|
|
7
7
|
"""
|
8
8
|
Queries related to the fact_enrollment_admin_dash table.
|
9
9
|
"""
|
10
|
+
@staticmethod
|
11
|
+
def get_top_enterprises_query(count=10):
|
12
|
+
"""
|
13
|
+
Get the query to fetch the top enterprises by enrollments.
|
14
|
+
"""
|
15
|
+
return f"""
|
16
|
+
SELECT enterprise_customer_uuid
|
17
|
+
FROM fact_enrollment_admin_dash
|
18
|
+
GROUP BY enterprise_customer_uuid
|
19
|
+
ORDER BY COUNT(enterprise_customer_uuid) DESC LIMIT {count};
|
20
|
+
"""
|
21
|
+
|
10
22
|
@staticmethod
|
11
23
|
def get_enrollment_count_query():
|
12
24
|
"""
|
@@ -86,7 +98,7 @@ class FactEnrollmentAdminDashQueries:
|
|
86
98
|
"""
|
87
99
|
|
88
100
|
@staticmethod
|
89
|
-
def get_top_courses_by_enrollments_query(record_count=
|
101
|
+
def get_top_courses_by_enrollments_query(record_count=10):
|
90
102
|
"""
|
91
103
|
Get the query to fetch the enrollment count by courses.
|
92
104
|
|
@@ -96,15 +108,32 @@ class FactEnrollmentAdminDashQueries:
|
|
96
108
|
record_count (int): Number of records to fetch.
|
97
109
|
"""
|
98
110
|
return f"""
|
99
|
-
|
100
|
-
|
101
|
-
|
111
|
+
WITH filtered_data AS (
|
112
|
+
SELECT *
|
113
|
+
FROM fact_enrollment_admin_dash
|
114
|
+
WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
|
102
115
|
enterprise_enrollment_date BETWEEN %(start_date)s AND %(end_date)s
|
103
|
-
|
116
|
+
),
|
117
|
+
top_10_courses AS (
|
118
|
+
SELECT course_key
|
119
|
+
FROM filtered_data
|
120
|
+
GROUP BY course_key
|
121
|
+
ORDER BY COUNT(*) DESC
|
122
|
+
LIMIT {record_count}
|
123
|
+
)
|
124
|
+
|
125
|
+
SELECT
|
126
|
+
d.course_key,
|
127
|
+
d.enroll_type,
|
128
|
+
COUNT(*) AS enrollment_count
|
129
|
+
FROM filtered_data d
|
130
|
+
JOIN top_10_courses tc
|
131
|
+
ON d.course_key = tc.course_key
|
132
|
+
GROUP BY d.course_key, d.enroll_type;
|
104
133
|
"""
|
105
134
|
|
106
135
|
@staticmethod
|
107
|
-
def get_top_subjects_by_enrollments_query(record_count=
|
136
|
+
def get_top_subjects_by_enrollments_query(record_count=10):
|
108
137
|
"""
|
109
138
|
Get the query to fetch the enrollment count by subjects.
|
110
139
|
|
@@ -114,11 +143,27 @@ class FactEnrollmentAdminDashQueries:
|
|
114
143
|
record_count (int): Number of records to fetch.
|
115
144
|
"""
|
116
145
|
return f"""
|
117
|
-
|
118
|
-
|
119
|
-
|
146
|
+
WITH filtered_data AS (
|
147
|
+
SELECT *
|
148
|
+
FROM fact_enrollment_admin_dash
|
149
|
+
WHERE enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
|
120
150
|
enterprise_enrollment_date BETWEEN %(start_date)s AND %(end_date)s
|
121
|
-
|
151
|
+
),
|
152
|
+
top_10_subjects AS (
|
153
|
+
SELECT course_subject
|
154
|
+
FROM filtered_data
|
155
|
+
GROUP BY course_subject
|
156
|
+
ORDER BY COUNT(*) DESC
|
157
|
+
LIMIT {record_count}
|
158
|
+
)
|
159
|
+
SELECT
|
160
|
+
d.course_subject,
|
161
|
+
d.enroll_type,
|
162
|
+
COUNT(*) AS enrollment_count
|
163
|
+
FROM filtered_data d
|
164
|
+
JOIN top_10_subjects ts
|
165
|
+
ON d.course_subject = ts.course_subject
|
166
|
+
GROUP BY d.course_subject, d.enroll_type;
|
122
167
|
"""
|
123
168
|
|
124
169
|
@staticmethod
|
@@ -150,7 +195,7 @@ class FactEnrollmentAdminDashQueries:
|
|
150
195
|
"""
|
151
196
|
|
152
197
|
@staticmethod
|
153
|
-
def get_top_courses_by_completions_query(record_count=
|
198
|
+
def get_top_courses_by_completions_query(record_count=10):
|
154
199
|
"""
|
155
200
|
Get the query to fetch the completion count by courses.
|
156
201
|
|
@@ -163,17 +208,40 @@ class FactEnrollmentAdminDashQueries:
|
|
163
208
|
(str): Query to fetch the enrollment count by courses for the top courses by enrollment count.
|
164
209
|
"""
|
165
210
|
return f"""
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
211
|
+
WITH filtered_data AS (
|
212
|
+
SELECT
|
213
|
+
course_key,
|
214
|
+
course_title,
|
215
|
+
enroll_type,
|
216
|
+
passed_date
|
217
|
+
FROM fact_enrollment_admin_dash
|
218
|
+
WHERE has_passed = 1 AND
|
219
|
+
enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
|
170
220
|
passed_date BETWEEN %(start_date)s AND %(end_date)s
|
171
|
-
|
172
|
-
|
221
|
+
),
|
222
|
+
top_10_courses AS (
|
223
|
+
SELECT
|
224
|
+
course_key,
|
225
|
+
COUNT(*) AS total_completion_count
|
226
|
+
FROM filtered_data
|
227
|
+
GROUP BY course_key
|
228
|
+
ORDER BY total_completion_count DESC
|
229
|
+
LIMIT {record_count}
|
230
|
+
)
|
231
|
+
SELECT
|
232
|
+
d.course_key,
|
233
|
+
d.course_title,
|
234
|
+
d.enroll_type,
|
235
|
+
COUNT(*) AS completion_count
|
236
|
+
FROM filtered_data d
|
237
|
+
JOIN top_10_courses tc
|
238
|
+
ON d.course_key = tc.course_key
|
239
|
+
GROUP BY d.course_key, d.course_title, d.enroll_type
|
240
|
+
ORDER BY total_completion_count DESC;
|
173
241
|
"""
|
174
242
|
|
175
243
|
@staticmethod
|
176
|
-
def get_top_subjects_by_completions_query(record_count=
|
244
|
+
def get_top_subjects_by_completions_query(record_count=10):
|
177
245
|
"""
|
178
246
|
Get the query to fetch the completion count by subjects.
|
179
247
|
|
@@ -186,13 +254,34 @@ class FactEnrollmentAdminDashQueries:
|
|
186
254
|
(str): Query to fetch the completion count by subjects for the top subjects by completion count.
|
187
255
|
"""
|
188
256
|
return f"""
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
257
|
+
WITH filtered_data AS (
|
258
|
+
SELECT
|
259
|
+
course_subject,
|
260
|
+
enroll_type,
|
261
|
+
passed_date
|
262
|
+
FROM fact_enrollment_admin_dash
|
263
|
+
WHERE has_passed = 1 AND
|
264
|
+
enterprise_customer_uuid=%(enterprise_customer_uuid)s AND
|
193
265
|
passed_date BETWEEN %(start_date)s AND %(end_date)s
|
194
|
-
|
195
|
-
|
266
|
+
),
|
267
|
+
top_10_subjects AS (
|
268
|
+
SELECT
|
269
|
+
course_subject,
|
270
|
+
COUNT(*) AS total_completion_count
|
271
|
+
FROM filtered_data
|
272
|
+
GROUP BY course_subject
|
273
|
+
ORDER BY total_completion_count DESC
|
274
|
+
LIMIT {record_count}
|
275
|
+
)
|
276
|
+
SELECT
|
277
|
+
d.course_subject,
|
278
|
+
d.enroll_type,
|
279
|
+
COUNT(*) AS completion_count
|
280
|
+
FROM filtered_data d
|
281
|
+
JOIN top_10_subjects ts
|
282
|
+
ON d.course_subject = ts.course_subject
|
283
|
+
GROUP BY d.course_subject, d.enroll_type
|
284
|
+
ORDER BY total_completion_count DESC;
|
196
285
|
"""
|
197
286
|
|
198
287
|
@staticmethod
|
@@ -5,6 +5,7 @@ from datetime import date
|
|
5
5
|
from uuid import UUID
|
6
6
|
|
7
7
|
from enterprise_data.cache.decorators import cache_it
|
8
|
+
from enterprise_data.utils import find_first
|
8
9
|
|
9
10
|
from ..queries import FactEngagementAdminDashQueries
|
10
11
|
from ..utils import run_query
|
@@ -168,7 +169,14 @@ class FactEngagementAdminDashTable(BaseTable):
|
|
168
169
|
|
169
170
|
@cache_it()
|
170
171
|
def _get_engagement_data_for_leaderboard(
|
171
|
-
self,
|
172
|
+
self,
|
173
|
+
enterprise_customer_uuid: UUID,
|
174
|
+
start_date: date,
|
175
|
+
end_date: date,
|
176
|
+
limit: int,
|
177
|
+
offset: int,
|
178
|
+
include_null_email: bool,
|
179
|
+
|
172
180
|
):
|
173
181
|
"""
|
174
182
|
Get the engagement data for leaderboard.
|
@@ -182,11 +190,12 @@ class FactEngagementAdminDashTable(BaseTable):
|
|
182
190
|
end_date (date): The end date.
|
183
191
|
limit (int): The maximum number of records to return.
|
184
192
|
offset (int): The number of records to skip.
|
193
|
+
include_null_email (bool): If True, only fetch data for NULL emails.
|
185
194
|
|
186
195
|
Returns:
|
187
196
|
list[dict]: The engagement data for leaderboard.
|
188
197
|
"""
|
189
|
-
|
198
|
+
engagements = run_query(
|
190
199
|
query=self.queries.get_engagement_data_for_leaderboard_query(),
|
191
200
|
params={
|
192
201
|
'enterprise_customer_uuid': enterprise_customer_uuid,
|
@@ -198,9 +207,27 @@ class FactEngagementAdminDashTable(BaseTable):
|
|
198
207
|
as_dict=True,
|
199
208
|
)
|
200
209
|
|
210
|
+
if include_null_email:
|
211
|
+
engagement_for_null_email = run_query(
|
212
|
+
query=self.queries.get_engagement_data_for_leaderboard_null_email_only_query(),
|
213
|
+
params={
|
214
|
+
'enterprise_customer_uuid': enterprise_customer_uuid,
|
215
|
+
'start_date': start_date,
|
216
|
+
'end_date': end_date,
|
217
|
+
},
|
218
|
+
as_dict=True,
|
219
|
+
)
|
220
|
+
engagements += engagement_for_null_email
|
221
|
+
return engagements
|
222
|
+
|
201
223
|
@cache_it()
|
202
224
|
def _get_completion_data_for_leaderboard_query(
|
203
|
-
self,
|
225
|
+
self,
|
226
|
+
enterprise_customer_uuid: UUID,
|
227
|
+
start_date: date,
|
228
|
+
end_date: date,
|
229
|
+
email_list: list,
|
230
|
+
include_null_email: bool,
|
204
231
|
):
|
205
232
|
"""
|
206
233
|
Get the completion data for leaderboard.
|
@@ -213,11 +240,13 @@ class FactEngagementAdminDashTable(BaseTable):
|
|
213
240
|
start_date (date): The start date.
|
214
241
|
end_date (date): The end date.
|
215
242
|
email_list (list<str>): List of emails of the enterprise learners.
|
243
|
+
include_null_email (bool): If True, only fetch data for NULL emails.
|
216
244
|
|
217
245
|
Returns:
|
218
246
|
list[dict]: The engagement data for leaderboard.
|
219
247
|
"""
|
220
|
-
|
248
|
+
|
249
|
+
completions = run_query(
|
221
250
|
query=self.queries.get_completion_data_for_leaderboard_query(email_list),
|
222
251
|
params={
|
223
252
|
'enterprise_customer_uuid': enterprise_customer_uuid,
|
@@ -227,8 +256,28 @@ class FactEngagementAdminDashTable(BaseTable):
|
|
227
256
|
as_dict=True,
|
228
257
|
)
|
229
258
|
|
259
|
+
if include_null_email:
|
260
|
+
completions_for_null_email = run_query(
|
261
|
+
query=self.queries.get_completion_data_for_leaderboard_null_email_only_query(),
|
262
|
+
params={
|
263
|
+
'enterprise_customer_uuid': enterprise_customer_uuid,
|
264
|
+
'start_date': start_date,
|
265
|
+
'end_date': end_date,
|
266
|
+
},
|
267
|
+
as_dict=True,
|
268
|
+
)
|
269
|
+
completions += completions_for_null_email
|
270
|
+
|
271
|
+
return completions
|
272
|
+
|
230
273
|
def get_all_leaderboard_data(
|
231
|
-
self,
|
274
|
+
self,
|
275
|
+
enterprise_customer_uuid: UUID,
|
276
|
+
start_date: date,
|
277
|
+
end_date: date,
|
278
|
+
limit: int,
|
279
|
+
offset: int,
|
280
|
+
total_count: int,
|
232
281
|
):
|
233
282
|
"""
|
234
283
|
Get the leaderboard data for the given enterprise customer.
|
@@ -239,32 +288,48 @@ class FactEngagementAdminDashTable(BaseTable):
|
|
239
288
|
end_date (date): The end date.
|
240
289
|
limit (int): The maximum number of records to return.
|
241
290
|
offset (int): The number of records to skip.
|
291
|
+
total_count (int): The total number of records.
|
242
292
|
|
243
293
|
Returns:
|
244
294
|
list[dict]: The leaderboard data.
|
245
295
|
"""
|
296
|
+
include_null_email = False
|
297
|
+
# If this is the last or only page, we need to include NULL emails record.
|
298
|
+
if total_count <= offset + limit:
|
299
|
+
include_null_email = True
|
300
|
+
|
246
301
|
engagement_data = self._get_engagement_data_for_leaderboard(
|
247
302
|
enterprise_customer_uuid=enterprise_customer_uuid,
|
248
303
|
start_date=start_date,
|
249
304
|
end_date=end_date,
|
250
305
|
limit=limit,
|
251
306
|
offset=offset,
|
307
|
+
include_null_email=include_null_email,
|
252
308
|
)
|
253
309
|
# If there is no data, no need to proceed.
|
254
310
|
if not engagement_data:
|
255
311
|
return []
|
256
312
|
|
257
|
-
engagement_data_dict = {
|
313
|
+
engagement_data_dict = {
|
314
|
+
engagement['email']: engagement for engagement in engagement_data if engagement['email']
|
315
|
+
}
|
258
316
|
completion_data = self._get_completion_data_for_leaderboard_query(
|
259
317
|
enterprise_customer_uuid=enterprise_customer_uuid,
|
260
318
|
start_date=start_date,
|
261
319
|
end_date=end_date,
|
262
320
|
email_list=list(engagement_data_dict.keys()),
|
321
|
+
include_null_email=include_null_email,
|
263
322
|
)
|
264
323
|
for completion in completion_data:
|
265
324
|
email = completion['email']
|
266
325
|
engagement_data_dict[email]['course_completion_count'] = completion['course_completion_count']
|
267
326
|
|
327
|
+
if include_null_email:
|
328
|
+
engagement_data_dict['None'] = find_first(engagement_data, lambda x: x['email'] is None) or {}
|
329
|
+
completion = find_first(completion_data, lambda x: x['email'] is None) or \
|
330
|
+
{'course_completion_count': 'Unknown'}
|
331
|
+
engagement_data_dict['None']['course_completion_count'] = completion['course_completion_count']
|
332
|
+
|
268
333
|
return list(engagement_data_dict.values())
|
269
334
|
|
270
335
|
@cache_it()
|
@@ -17,6 +17,22 @@ class FactEnrollmentAdminDashTable(BaseTable):
|
|
17
17
|
"""
|
18
18
|
queries = FactEnrollmentAdminDashQueries()
|
19
19
|
|
20
|
+
def get_top_enterprises(self, count=10):
|
21
|
+
"""
|
22
|
+
Get the top enterprises by enrollments.
|
23
|
+
|
24
|
+
Arguments:
|
25
|
+
count (int): The number of enterprises to return.
|
26
|
+
|
27
|
+
Returns:
|
28
|
+
list<str>: A list of enterprise UUIDs.
|
29
|
+
"""
|
30
|
+
result = run_query(
|
31
|
+
query=self.queries.get_top_enterprises_query(count),
|
32
|
+
as_dict=False,
|
33
|
+
)
|
34
|
+
return [row[0] for row in result]
|
35
|
+
|
20
36
|
@cache_it()
|
21
37
|
def get_enrollment_count(self, enterprise_customer_uuid: UUID, start_date: date, end_date: date):
|
22
38
|
"""
|
@@ -77,7 +93,7 @@ class FactEnrollmentAdminDashTable(BaseTable):
|
|
77
93
|
Get the enrollment date range for the given enterprise customer.
|
78
94
|
|
79
95
|
Arguments:
|
80
|
-
enterprise_customer_uuid (UUID): The UUID of the enterprise customer.
|
96
|
+
enterprise_customer_uuid (UUID | str): The UUID of the enterprise customer.
|
81
97
|
|
82
98
|
Returns:
|
83
99
|
(tuple<date, date>): The minimum and maximum enrollment dates.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
Views for enterprise admin completions analytics.
|
3
3
|
"""
|
4
4
|
|
5
|
-
from datetime import
|
5
|
+
from datetime import date
|
6
6
|
from logging import getLogger
|
7
7
|
|
8
8
|
from edx_rbac.decorators import permission_required
|
@@ -50,7 +50,7 @@ class AdvanceAnalyticsCompletionsView(AnalyticsPaginationMixin, ViewSet):
|
|
50
50
|
|
51
51
|
# get values from query params or use default values
|
52
52
|
start_date = serializer.data.get('start_date', min_enrollment_date)
|
53
|
-
end_date = serializer.data.get('end_date',
|
53
|
+
end_date = serializer.data.get('end_date', date.today())
|
54
54
|
page = serializer.data.get('page', 1)
|
55
55
|
page_size = serializer.data.get('page_size', 100)
|
56
56
|
completions = FactEnrollmentAdminDashTable().get_all_completions(
|
@@ -132,7 +132,7 @@ class AdvanceAnalyticsCompletionsView(AnalyticsPaginationMixin, ViewSet):
|
|
132
132
|
)
|
133
133
|
# get values from query params or use default
|
134
134
|
start_date = serializer.data.get('start_date', min_enrollment_date)
|
135
|
-
end_date = serializer.data.get('end_date',
|
135
|
+
end_date = serializer.data.get('end_date', date.today())
|
136
136
|
with timer('construct_completion_all_stats'):
|
137
137
|
data = {
|
138
138
|
'completions_over_time': FactEnrollmentAdminDashTable().get_completions_time_series_data(
|
@@ -2,7 +2,7 @@
|
|
2
2
|
Views for handling REST endpoints related to Engagements analytics.
|
3
3
|
"""
|
4
4
|
|
5
|
-
from datetime import
|
5
|
+
from datetime import date
|
6
6
|
from logging import getLogger
|
7
7
|
|
8
8
|
from edx_rbac.decorators import permission_required
|
@@ -50,7 +50,7 @@ class AdvanceAnalyticsEngagementView(AnalyticsPaginationMixin, ViewSet):
|
|
50
50
|
|
51
51
|
# get values from query params or use default values
|
52
52
|
start_date = serializer.data.get('start_date', min_enrollment_date)
|
53
|
-
end_date = serializer.data.get('end_date',
|
53
|
+
end_date = serializer.data.get('end_date', date.today())
|
54
54
|
page = serializer.data.get('page', 1)
|
55
55
|
page_size = serializer.data.get('page_size', 100)
|
56
56
|
engagements = FactEngagementAdminDashTable().get_all_engagements(
|
@@ -132,7 +132,7 @@ class AdvanceAnalyticsEngagementView(AnalyticsPaginationMixin, ViewSet):
|
|
132
132
|
)
|
133
133
|
# get values from query params or use default
|
134
134
|
start_date = serializer.data.get('start_date', min_enrollment_date)
|
135
|
-
end_date = serializer.data.get('end_date',
|
135
|
+
end_date = serializer.data.get('end_date', date.today())
|
136
136
|
with timer('construct_engagement_all_stats'):
|
137
137
|
data = {
|
138
138
|
'engagement_over_time': FactEngagementAdminDashTable().get_engagement_time_series_data(
|