edx-enterprise-data 9.6.0__tar.gz → 9.7.1__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-9.6.0 → edx_enterprise_data-9.7.1}/CHANGELOG.rst +4 -0
- {edx_enterprise_data-9.6.0/edx_enterprise_data.egg-info → edx_enterprise_data-9.7.1}/PKG-INFO +1 -1
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1/edx_enterprise_data.egg-info}/PKG-INFO +1 -1
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/edx_enterprise_data.egg-info/SOURCES.txt +2 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/__init__.py +1 -1
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/database/queries/fact_enrollment_admin_dash.py +12 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/database/tables/fact_enrollment_admin_dash.py +17 -1
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/serializers.py +13 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/urls.py +5 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/views/analytics_completions.py +3 -3
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/views/analytics_engagements.py +3 -3
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/views/analytics_enrollments.py +3 -3
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/views/analytics_leaderboard.py +2 -2
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/views/enterprise_admin.py +26 -2
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/views/enterprise_learner.py +4 -0
- edx_enterprise_data-9.7.1/enterprise_data/management/commands/pre_warm_analytics_cache.py +218 -0
- edx_enterprise_data-9.7.1/enterprise_data/management/commands/tests/test_pre_warm_analytics_cache.py +51 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/api/v1/views/test_enterprise_admin.py +47 -1
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/LICENSE +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/MANIFEST.in +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/README.md +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/edx_enterprise_data.egg-info/dependency_links.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/edx_enterprise_data.egg-info/not-zip-safe +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/edx_enterprise_data.egg-info/requires.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/edx_enterprise_data.egg-info/top_level.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/constants.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/data_loaders.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/database/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/database/queries/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/database/queries/fact_engagement_admin_dash.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/database/queries/skills_daily_rollup_admin_dash.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/database/tables/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/database/tables/base.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/database/tables/fact_engagement_admin_dash.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/database/tables/skills_daily_rollup_admin_dash.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/database/utils.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/urls.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v0/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v0/serializers.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v0/urls.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v0/views.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/views/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/views/base.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/views/enterprise_offers.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/apps.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/cache/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/cache/decorators.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/clients.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/constants.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/filters.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/fixtures/enterprise_enrollment.json +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/fixtures/enterprise_user.json +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/create_dummy_data.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/create_dummy_data_lpr_v1.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/create_enterprise_enrollment.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/create_enterprise_learner_enrollment_lpr_v1.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/create_enterprise_learner_lpr_v1.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/create_enterprise_offer.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/create_enterprise_user.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/tests/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/tests/test_create_dummy_data_lpr_v1.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/tests/test_create_enterprise_enrollment.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/tests/test_create_enterprise_learner_enrollment_lpr_v1.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/tests/test_create_enterprise_learner_lpr_v1.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/management/commands/tests/test_create_enterprise_user.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0001_initial.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0002_auto_20180430_1358.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0003_auto_20180501_0603.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0004_auto_20180501_0928.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0004_auto_20180508_1652.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0005_auto_20180524_2204.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0006_auto_20180612_0336.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0007_auto_20180612_0534.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0008_auto_20180614_0108.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0009_auto_20180628_1152.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0010_enterpriseenrollment_created.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0011_enterpriseuser.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0012_auto_20180831_1930.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0013_auto_20180831_1931.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0014_enterpriseuser_created.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0015_auto_20180907_1757.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0016_auto_20180924_2138.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0017_enterpriseenrollment_unenrollment_timestamp.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0018_enterprisedatafeaturerole_enterprisedataroleassignment.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0019_add_enterprise_data_feature_roles.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0020_add_role_based_access_control_switch.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0021_auto_20190329_1241.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0022_remove_role_based_access_control_switch.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0023_enterpriselearner_enterpriselearnerenrollment.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0024_auto_20210602_1811.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0025_auto_20210703_1854.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0026_auto_20210916_0414.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0027_enterpriselearnerenrollment_total_learning_time_seconds.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0028_enterpriselearnerenrollment_offer_id.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0029_enterpriseoffer.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0030_auto_20230609_1353.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0031_auto_20230615_0705.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0032_auto_20230704_0818.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0033_enterpriseadminlearnerprogress_enterpriseadminsummarizeinsights.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0034_auto_20230907_0834.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0035_auto_20230907_1154.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0036_enterprisesubsidybudget_subsidy_access_policy_display_name.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0037_alter_enterpriseenrollment_consent_granted.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0038_enterpriseoffer_export_timestamp.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0039_auto_20240212_1403.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0040_auto_20240718_0536_squashed_0043_alter_enterpriselearnerenrollment_enterprise_enrollment_id.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/0044_enterpriseexecedlcmoduleperformance.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/migrations/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/models.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/paginators.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/renderers.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/settings/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/settings/test.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/signals.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/admin_analytics/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/admin_analytics/mock_analytics_data.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/admin_analytics/mock_enrollments.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/admin_analytics/test_analytics_engagements.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/admin_analytics/test_analytics_enrollments.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/admin_analytics/test_analytics_leaderboard.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/admin_analytics/test_data_loaders.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/admin_analytics/test_enterprise_completions.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/api/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/api/v0/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/api/v0/test_serializers.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/api/v1/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/api/v1/test_serializers.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/api/v1/test_views.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/api/v1/views/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/factories.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/mixins.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/test_clients.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/test_filters.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/test_models.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/test_utils.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/tests/test_views.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/urls.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/utils.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/admin.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/apps.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/constants.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/migrations/0001_initial.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/migrations/0002_add_enterprise_data_feature_roles.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/migrations/0003_add_role_based_access_control_switch.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/migrations/0004_enterprisedataroleassignment_enterprise_id.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/migrations/0005_turn_on_role_based_access_control_switch.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/migrations/0006_remove_role_based_access_control_switch.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/migrations/0007_enterprisedataroleassignment_applies_to_all_contexts.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/migrations/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/models.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/rules.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/tests/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/tests/factories.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data_roles/tests/test_models.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/clients/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/clients/enterprise.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/clients/s3.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/clients/snowflake.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/clients/vertica.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/delivery_method.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/external_resource_link_report.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/fixtures/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/fixtures/enterprise_customer_reporting.json +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/reporter.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/send_enterprise_reports.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/tests/__init__.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/tests/test_clients.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/tests/test_delivery_method.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/tests/test_enterprise_client.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/tests/test_external_link_report.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/tests/test_reporter.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/tests/test_send_enterprise_reports.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/tests/test_utils.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/tests/test_vertica_client.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/tests/utils.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_reporting/utils.py +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/base.in +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/base.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/ci.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/common_constraints.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/constraints.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/dev.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/django.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/pip.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/pip_tools.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/quality.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/reporting.in +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/test-master.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/test-reporting.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/requirements/test.txt +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/setup.cfg +0 -0
- {edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/setup.py +0 -0
@@ -16,6 +16,10 @@ Unreleased
|
|
16
16
|
|
17
17
|
=========================
|
18
18
|
|
19
|
+
[9.7.0] - 2024-10-23
|
20
|
+
---------------------
|
21
|
+
* feat: Add API to fetch enterprise budgets information
|
22
|
+
|
19
23
|
[9.6.0] - 2024-10-14
|
20
24
|
---------------------
|
21
25
|
* feat: Added caching for API endpoints related to advanced analytics.
|
{edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/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
|
@@ -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
|
"""
|
@@ -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.
|
{edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/api/v1/serializers.py
RENAMED
@@ -240,6 +240,19 @@ class EnterpriseExecEdLCModulePerformanceSerializer(serializers.ModelSerializer)
|
|
240
240
|
return obj.extensions_requested if obj.extensions_requested is not None else 0
|
241
241
|
|
242
242
|
|
243
|
+
class EnterpriseBudgetSerializer(serializers.ModelSerializer):
|
244
|
+
"""
|
245
|
+
Serializer for EnterpriseSubsidyBudget model.
|
246
|
+
"""
|
247
|
+
|
248
|
+
class Meta:
|
249
|
+
model = EnterpriseSubsidyBudget
|
250
|
+
fields = (
|
251
|
+
'subsidy_access_policy_uuid',
|
252
|
+
'subsidy_access_policy_display_name',
|
253
|
+
)
|
254
|
+
|
255
|
+
|
243
256
|
class AdvanceAnalyticsQueryParamSerializer(serializers.Serializer): # pylint: disable=abstract-method
|
244
257
|
"""Serializer for validating query params"""
|
245
258
|
RESPONSE_TYPES = [
|
@@ -96,6 +96,11 @@ urlpatterns = [
|
|
96
96
|
enterprise_admin_views.EnterpriseAdminAnalyticsSkillsView.as_view(),
|
97
97
|
name='enterprise-admin-analytics-skills'
|
98
98
|
),
|
99
|
+
re_path(
|
100
|
+
fr'^enterprise/(?P<enterprise_uuid>{UUID4_REGEX})/budgets',
|
101
|
+
enterprise_admin_views.EnterpriseBudgetView.as_view(),
|
102
|
+
name='enterprise-budgets'
|
103
|
+
),
|
99
104
|
]
|
100
105
|
|
101
106
|
urlpatterns += router.urls
|
@@ -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(
|
@@ -1,7 +1,7 @@
|
|
1
1
|
"""
|
2
2
|
Advance Analytics for API endpoints to fetch enterprise enrollments data.
|
3
3
|
"""
|
4
|
-
from datetime import
|
4
|
+
from datetime import date
|
5
5
|
from logging import getLogger
|
6
6
|
|
7
7
|
from edx_rbac.decorators import permission_required
|
@@ -49,7 +49,7 @@ class AdvanceAnalyticsEnrollmentsView(AnalyticsPaginationMixin, ViewSet):
|
|
49
49
|
|
50
50
|
# get values from query params or use default values
|
51
51
|
start_date = serializer.data.get('start_date', min_enrollment_date)
|
52
|
-
end_date = serializer.data.get('end_date',
|
52
|
+
end_date = serializer.data.get('end_date', date.today())
|
53
53
|
page = serializer.data.get('page', 1)
|
54
54
|
page_size = serializer.data.get('page_size', 100)
|
55
55
|
enrollments = FactEnrollmentAdminDashTable().get_all_enrollments(
|
@@ -131,7 +131,7 @@ class AdvanceAnalyticsEnrollmentsView(AnalyticsPaginationMixin, ViewSet):
|
|
131
131
|
)
|
132
132
|
# get values from query params or use default
|
133
133
|
start_date = serializer.data.get('start_date', min_enrollment_date)
|
134
|
-
end_date = serializer.data.get('end_date',
|
134
|
+
end_date = serializer.data.get('end_date', date.today())
|
135
135
|
with timer('construct_enrollment_all_stats'):
|
136
136
|
data = {
|
137
137
|
'enrollments_over_time': FactEnrollmentAdminDashTable().get_enrolment_time_series_data(
|
@@ -2,7 +2,7 @@
|
|
2
2
|
Views for fetching leaderboard data.
|
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
|
@@ -46,7 +46,7 @@ class AdvanceAnalyticsLeaderboardView(AnalyticsPaginationMixin, ViewSet):
|
|
46
46
|
|
47
47
|
# get values from query params or use default values
|
48
48
|
start_date = serializer.data.get('start_date', min_enrollment_date)
|
49
|
-
end_date = serializer.data.get('end_date',
|
49
|
+
end_date = serializer.data.get('end_date', date.today())
|
50
50
|
page = serializer.data.get('page', 1)
|
51
51
|
page_size = serializer.data.get('page_size', 100)
|
52
52
|
leaderboard = FactEngagementAdminDashTable().get_all_leaderboard_data(
|
@@ -1,7 +1,7 @@
|
|
1
1
|
"""
|
2
2
|
Views for enterprise admin api v1.
|
3
3
|
"""
|
4
|
-
from datetime import datetime
|
4
|
+
from datetime import date, datetime
|
5
5
|
|
6
6
|
from edx_rbac.decorators import permission_required
|
7
7
|
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
|
@@ -21,6 +21,7 @@ from enterprise_data.models import (
|
|
21
21
|
EnterpriseAdminLearnerProgress,
|
22
22
|
EnterpriseAdminSummarizeInsights,
|
23
23
|
EnterpriseExecEdLCModulePerformance,
|
24
|
+
EnterpriseSubsidyBudget,
|
24
25
|
)
|
25
26
|
from enterprise_data.utils import timer
|
26
27
|
|
@@ -159,7 +160,7 @@ class EnterpriseAdminAnalyticsSkillsView(APIView):
|
|
159
160
|
if (start_date := serializer.data.get('start_date')) is None:
|
160
161
|
start_date, _ = FactEnrollmentAdminDashTable().get_enrollment_date_range(enterprise_id)
|
161
162
|
|
162
|
-
end_date = serializer.data.get('end_date',
|
163
|
+
end_date = serializer.data.get('end_date', date.today())
|
163
164
|
|
164
165
|
with timer('top_skills'):
|
165
166
|
skills = SkillsDailyRollupAdminDashTable().get_top_skills(enterprise_id, start_date, end_date)
|
@@ -206,3 +207,26 @@ class EnterpriseExecEdLCModulePerformanceViewSet(EnterpriseViewSetMixin, viewset
|
|
206
207
|
return EnterpriseExecEdLCModulePerformance.objects.filter(
|
207
208
|
enterprise_customer_uuid=self.kwargs['enterprise_id'],
|
208
209
|
)
|
210
|
+
|
211
|
+
|
212
|
+
class EnterpriseBudgetView(APIView):
|
213
|
+
"""
|
214
|
+
View for getting budgets information for an enterprise.
|
215
|
+
"""
|
216
|
+
authentication_classes = (JwtAuthentication,)
|
217
|
+
http_method_names = ["get"]
|
218
|
+
|
219
|
+
@permission_required("can_access_enterprise", fn=lambda request, enterprise_uuid: enterprise_uuid)
|
220
|
+
def get(self, request, enterprise_uuid):
|
221
|
+
"""
|
222
|
+
Return the queryset of EnterpriseSubsidyBudget objects.
|
223
|
+
"""
|
224
|
+
budgets = EnterpriseSubsidyBudget.objects.filter(
|
225
|
+
enterprise_customer_uuid=enterprise_uuid,
|
226
|
+
).values(
|
227
|
+
'subsidy_access_policy_uuid',
|
228
|
+
'subsidy_access_policy_display_name',
|
229
|
+
)
|
230
|
+
|
231
|
+
serializer = serializers.EnterpriseBudgetSerializer(budgets, many=True)
|
232
|
+
return Response(serializer.data)
|
@@ -150,6 +150,10 @@ class EnterpriseLearnerEnrollmentViewSet(EnterpriseViewSetMixin, viewsets.ReadOn
|
|
150
150
|
if search_start_date:
|
151
151
|
queryset = queryset.filter(course_start_date=search_start_date)
|
152
152
|
|
153
|
+
budget_uuid = query_filters.get('budget_uuid')
|
154
|
+
if budget_uuid:
|
155
|
+
queryset = queryset.filter(budget_id=budget_uuid)
|
156
|
+
|
153
157
|
offer_id = query_filters.get('offer_id')
|
154
158
|
if offer_id:
|
155
159
|
queryset = self.filter_by_offer_id(queryset, offer_id)
|
@@ -0,0 +1,218 @@
|
|
1
|
+
"""
|
2
|
+
Management command for pre-warming the analytics cache for large enterprises.
|
3
|
+
"""
|
4
|
+
from datetime import date
|
5
|
+
|
6
|
+
from django.core.management.base import BaseCommand, CommandError
|
7
|
+
|
8
|
+
from enterprise_data.admin_analytics.database.tables import (
|
9
|
+
FactEngagementAdminDashTable,
|
10
|
+
FactEnrollmentAdminDashTable,
|
11
|
+
SkillsDailyRollupAdminDashTable,
|
12
|
+
)
|
13
|
+
|
14
|
+
|
15
|
+
class Command(BaseCommand):
|
16
|
+
"""
|
17
|
+
Add cache entries for analytics related data for a large enterprise.
|
18
|
+
|
19
|
+
The top enterprises will be the ones with the most enrollments.
|
20
|
+
"""
|
21
|
+
help = 'Pre-warm the analytics cache for a large enterprises.'
|
22
|
+
|
23
|
+
@staticmethod
|
24
|
+
def __cache_enrollment_data(enterprise_customer_uuid):
|
25
|
+
"""
|
26
|
+
Helper method to cache all the enrollment related data for the given enterprise.
|
27
|
+
|
28
|
+
Arguments:
|
29
|
+
enterprise_customer_uuid (str): The UUID of the enterprise customer.
|
30
|
+
"""
|
31
|
+
enterprise_enrollment_table = FactEnrollmentAdminDashTable()
|
32
|
+
start_date, _ = enterprise_enrollment_table.get_enrollment_date_range(
|
33
|
+
enterprise_customer_uuid,
|
34
|
+
)
|
35
|
+
end_date = date.today()
|
36
|
+
enterprise_enrollment_table.get_enrollment_count(
|
37
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
38
|
+
start_date=start_date,
|
39
|
+
end_date=end_date,
|
40
|
+
)
|
41
|
+
page_size = 100
|
42
|
+
enterprise_enrollment_table.get_all_enrollments(
|
43
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
44
|
+
start_date=start_date,
|
45
|
+
end_date=end_date,
|
46
|
+
limit=page_size,
|
47
|
+
offset=0,
|
48
|
+
)
|
49
|
+
enterprise_enrollment_table.get_enrollment_and_course_count(
|
50
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
51
|
+
start_date=start_date,
|
52
|
+
end_date=end_date,
|
53
|
+
)
|
54
|
+
enterprise_enrollment_table.get_completion_count(
|
55
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
56
|
+
start_date=start_date,
|
57
|
+
end_date=end_date,
|
58
|
+
)
|
59
|
+
enterprise_enrollment_table.get_top_courses_by_enrollments(
|
60
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
61
|
+
start_date=start_date,
|
62
|
+
end_date=end_date,
|
63
|
+
)
|
64
|
+
enterprise_enrollment_table.get_top_subjects_by_enrollments(
|
65
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
66
|
+
start_date=start_date,
|
67
|
+
end_date=end_date,
|
68
|
+
)
|
69
|
+
enterprise_enrollment_table.get_enrolment_time_series_data(
|
70
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
71
|
+
start_date=start_date,
|
72
|
+
end_date=end_date,
|
73
|
+
)
|
74
|
+
|
75
|
+
@staticmethod
|
76
|
+
def __cache_completions_data(enterprise_customer_uuid):
|
77
|
+
"""
|
78
|
+
Helper method to cache all the completions related data for the given enterprise.
|
79
|
+
|
80
|
+
Arguments:
|
81
|
+
enterprise_customer_uuid (str): The UUID of the enterprise customer.
|
82
|
+
"""
|
83
|
+
enterprise_enrollment_table = FactEnrollmentAdminDashTable()
|
84
|
+
start_date, _ = enterprise_enrollment_table.get_enrollment_date_range(
|
85
|
+
enterprise_customer_uuid,
|
86
|
+
)
|
87
|
+
end_date = date.today()
|
88
|
+
|
89
|
+
page_size = 100
|
90
|
+
enterprise_enrollment_table.get_all_completions(
|
91
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
92
|
+
start_date=start_date,
|
93
|
+
end_date=end_date,
|
94
|
+
limit=page_size,
|
95
|
+
offset=0,
|
96
|
+
)
|
97
|
+
enterprise_enrollment_table.get_completion_count(
|
98
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
99
|
+
start_date=start_date,
|
100
|
+
end_date=end_date,
|
101
|
+
)
|
102
|
+
enterprise_enrollment_table.get_top_courses_by_completions(
|
103
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
104
|
+
start_date=start_date,
|
105
|
+
end_date=end_date,
|
106
|
+
)
|
107
|
+
enterprise_enrollment_table.get_top_subjects_by_completions(
|
108
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
109
|
+
start_date=start_date,
|
110
|
+
end_date=end_date,
|
111
|
+
)
|
112
|
+
enterprise_enrollment_table.get_completions_time_series_data(
|
113
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
114
|
+
start_date=start_date,
|
115
|
+
end_date=end_date,
|
116
|
+
)
|
117
|
+
|
118
|
+
@staticmethod
|
119
|
+
def __cache_engagement_data(enterprise_customer_uuid):
|
120
|
+
"""
|
121
|
+
Helper method to cache all the engagement related data for the given enterprise.
|
122
|
+
|
123
|
+
Arguments:
|
124
|
+
enterprise_customer_uuid (str): The UUID of the enterprise customer.
|
125
|
+
"""
|
126
|
+
start_date, _ = FactEnrollmentAdminDashTable().get_enrollment_date_range(
|
127
|
+
enterprise_customer_uuid,
|
128
|
+
)
|
129
|
+
end_date = date.today()
|
130
|
+
enterprise_engagement_table = FactEngagementAdminDashTable()
|
131
|
+
enterprise_engagement_table.get_learning_hours_and_daily_sessions(
|
132
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
133
|
+
start_date=start_date,
|
134
|
+
end_date=end_date,
|
135
|
+
)
|
136
|
+
enterprise_engagement_table.get_engagement_count(
|
137
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
138
|
+
start_date=start_date,
|
139
|
+
end_date=end_date,
|
140
|
+
)
|
141
|
+
page_size = 100
|
142
|
+
enterprise_engagement_table.get_all_engagements(
|
143
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
144
|
+
start_date=start_date,
|
145
|
+
end_date=end_date,
|
146
|
+
limit=page_size,
|
147
|
+
offset=0,
|
148
|
+
)
|
149
|
+
enterprise_engagement_table.get_top_courses_by_engagement(
|
150
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
151
|
+
start_date=start_date,
|
152
|
+
end_date=end_date,
|
153
|
+
)
|
154
|
+
enterprise_engagement_table.get_top_subjects_by_engagement(
|
155
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
156
|
+
start_date=start_date,
|
157
|
+
end_date=end_date,
|
158
|
+
)
|
159
|
+
enterprise_engagement_table.get_engagement_time_series_data(
|
160
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
161
|
+
start_date=start_date,
|
162
|
+
end_date=end_date,
|
163
|
+
)
|
164
|
+
enterprise_engagement_table.get_all_leaderboard_data(
|
165
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
166
|
+
start_date=start_date,
|
167
|
+
end_date=end_date,
|
168
|
+
limit=page_size,
|
169
|
+
offset=0,
|
170
|
+
)
|
171
|
+
enterprise_engagement_table.get_leaderboard_data_count(
|
172
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
173
|
+
start_date=start_date,
|
174
|
+
end_date=end_date,
|
175
|
+
)
|
176
|
+
|
177
|
+
@staticmethod
|
178
|
+
def __cache_skills_data(enterprise_customer_uuid):
|
179
|
+
"""
|
180
|
+
Helper method to cache all the skills related data for the given enterprise.
|
181
|
+
|
182
|
+
Arguments:
|
183
|
+
enterprise_customer_uuid (str): The UUID of the enterprise customer.
|
184
|
+
"""
|
185
|
+
start_date, _ = FactEnrollmentAdminDashTable().get_enrollment_date_range(
|
186
|
+
enterprise_customer_uuid,
|
187
|
+
)
|
188
|
+
end_date = date.today()
|
189
|
+
skills_table = SkillsDailyRollupAdminDashTable()
|
190
|
+
skills_table.get_top_skills(
|
191
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
192
|
+
start_date=start_date,
|
193
|
+
end_date=end_date,
|
194
|
+
)
|
195
|
+
skills_table.get_top_skills_by_enrollment(
|
196
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
197
|
+
start_date=start_date,
|
198
|
+
end_date=end_date,
|
199
|
+
)
|
200
|
+
skills_table.get_top_skills_by_completion(
|
201
|
+
enterprise_customer_uuid=enterprise_customer_uuid,
|
202
|
+
start_date=start_date,
|
203
|
+
end_date=end_date,
|
204
|
+
)
|
205
|
+
|
206
|
+
def handle(self, *args, **options):
|
207
|
+
for enterprise_customer_uuid in FactEnrollmentAdminDashTable().get_top_enterprises():
|
208
|
+
try:
|
209
|
+
self.__cache_enrollment_data(enterprise_customer_uuid)
|
210
|
+
self.__cache_completions_data(enterprise_customer_uuid)
|
211
|
+
self.__cache_engagement_data(enterprise_customer_uuid)
|
212
|
+
self.__cache_skills_data(enterprise_customer_uuid)
|
213
|
+
except Exception as exc:
|
214
|
+
info = (
|
215
|
+
'Error trying to add cache entries for enterprise '
|
216
|
+
'{}: {}'.format(enterprise_customer_uuid, exc)
|
217
|
+
)
|
218
|
+
raise CommandError(info) from exc
|
edx_enterprise_data-9.7.1/enterprise_data/management/commands/tests/test_pre_warm_analytics_cache.py
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
"""
|
2
|
+
Tests for `./manage.py pre_warm_analytics_cache` management command.
|
3
|
+
"""
|
4
|
+
from datetime import datetime
|
5
|
+
from unittest import TestCase
|
6
|
+
|
7
|
+
from mock import MagicMock, patch
|
8
|
+
from pytest import mark
|
9
|
+
|
10
|
+
from django.core.management import call_command
|
11
|
+
|
12
|
+
|
13
|
+
@mark.django_db
|
14
|
+
class Test(TestCase):
|
15
|
+
"""
|
16
|
+
Tests to validate the behavior of `./manage.py pre_warm_analytics_cache` management command.
|
17
|
+
"""
|
18
|
+
def setUp(self):
|
19
|
+
"""
|
20
|
+
Setup method.
|
21
|
+
"""
|
22
|
+
super().setUp()
|
23
|
+
self.enterprise_uuid = 'ee5e6b3a-069a-4947-bb8d-d2dbc323396c'
|
24
|
+
|
25
|
+
get_enrollment_date_range_patcher = patch(
|
26
|
+
'enterprise_data.api.v1.views.analytics_enrollments.FactEnrollmentAdminDashTable.get_enrollment_date_range',
|
27
|
+
return_value=(datetime.now(), datetime.now())
|
28
|
+
)
|
29
|
+
|
30
|
+
get_enrollment_date_range_patcher.start()
|
31
|
+
self.addCleanup(get_enrollment_date_range_patcher.stop)
|
32
|
+
|
33
|
+
@patch('enterprise_data.admin_analytics.database.tables.fact_engagement_admin_dash.run_query', MagicMock())
|
34
|
+
@patch('enterprise_data.admin_analytics.database.tables.fact_enrollment_admin_dash.run_query', MagicMock())
|
35
|
+
@patch('enterprise_data.admin_analytics.database.tables.skills_daily_rollup_admin_dash.run_query', MagicMock())
|
36
|
+
@patch('enterprise_data.api.v1.views.analytics_enrollments.FactEnrollmentAdminDashTable.get_top_enterprises')
|
37
|
+
@patch('enterprise_data.cache.decorators.cache.set')
|
38
|
+
@patch('enterprise_data.cache.decorators.cache.get')
|
39
|
+
def test_pre_warm_analytics_cache(self, mock_get_cache, mock_set_cache, mock_get_top_enterprises):
|
40
|
+
"""
|
41
|
+
Validate that the command caches the analytics data for a large enterprise.
|
42
|
+
"""
|
43
|
+
mock_get_top_enterprises.return_value = [
|
44
|
+
self.enterprise_uuid
|
45
|
+
]
|
46
|
+
mock_get_cache.return_value = MagicMock(is_found=False)
|
47
|
+
|
48
|
+
call_command('pre_warm_analytics_cache')
|
49
|
+
|
50
|
+
assert mock_get_cache.call_count == 24
|
51
|
+
assert mock_set_cache.call_count == 24
|
@@ -21,7 +21,7 @@ from enterprise_data.tests.admin_analytics.mock_analytics_data import (
|
|
21
21
|
TOP_SKILLS_BY_ENROLLMENTS,
|
22
22
|
)
|
23
23
|
from enterprise_data.tests.mixins import JWTTestMixin
|
24
|
-
from enterprise_data.tests.test_utils import UserFactory, get_dummy_enterprise_api_data
|
24
|
+
from enterprise_data.tests.test_utils import EnterpriseSubsidyBudgetFactory, UserFactory, get_dummy_enterprise_api_data
|
25
25
|
from enterprise_data_roles.constants import ENTERPRISE_DATA_ADMIN_ROLE
|
26
26
|
from enterprise_data_roles.models import EnterpriseDataFeatureRole, EnterpriseDataRoleAssignment
|
27
27
|
|
@@ -245,3 +245,49 @@ class TestSkillsStatsAPI(JWTTestMixin, APITransactionTestCase):
|
|
245
245
|
response = self.client.get(self.url, params)
|
246
246
|
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
247
247
|
assert response.json() == error
|
248
|
+
|
249
|
+
|
250
|
+
@ddt.ddt
|
251
|
+
class TestEnterpriseBudgetAPI(JWTTestMixin, APITransactionTestCase):
|
252
|
+
"""Tests for EnterpriseBudgetView."""
|
253
|
+
|
254
|
+
def setUp(self):
|
255
|
+
"""
|
256
|
+
Setup method.
|
257
|
+
"""
|
258
|
+
super().setUp()
|
259
|
+
self.user = UserFactory(is_staff=True)
|
260
|
+
role, __ = EnterpriseDataFeatureRole.objects.get_or_create(
|
261
|
+
name=ENTERPRISE_DATA_ADMIN_ROLE
|
262
|
+
)
|
263
|
+
self.role_assignment = EnterpriseDataRoleAssignment.objects.create(
|
264
|
+
role=role, user=self.user
|
265
|
+
)
|
266
|
+
self.client.force_authenticate(user=self.user)
|
267
|
+
|
268
|
+
self.enterprise_uuid = "ee5e6b3a069a4947bb8dd2dbc323396c"
|
269
|
+
self.set_jwt_cookie()
|
270
|
+
|
271
|
+
self.url = reverse(
|
272
|
+
"v1:enterprise-budgets",
|
273
|
+
kwargs={"enterprise_uuid": self.enterprise_uuid},
|
274
|
+
)
|
275
|
+
|
276
|
+
self.enterprise_subsidy_budget = EnterpriseSubsidyBudgetFactory(
|
277
|
+
enterprise_customer_uuid=self.enterprise_uuid,
|
278
|
+
subsidy_access_policy_uuid='8d6503dd-e40d-42b8-442b-37dd4c5450e3',
|
279
|
+
subsidy_access_policy_display_name='test-budget'
|
280
|
+
)
|
281
|
+
|
282
|
+
def test_get(self):
|
283
|
+
"""
|
284
|
+
Test the GET method for the EnterpriseBudgetView works.
|
285
|
+
"""
|
286
|
+
response = self.client.get(self.url)
|
287
|
+
assert response.status_code == status.HTTP_200_OK
|
288
|
+
assert response.json() == [
|
289
|
+
{
|
290
|
+
'subsidy_access_policy_uuid': '8d6503dd-e40d-42b8-442b-37dd4c5450e3',
|
291
|
+
'subsidy_access_policy_display_name': 'test-budget',
|
292
|
+
}
|
293
|
+
]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/edx_enterprise_data.egg-info/not-zip-safe
RENAMED
File without changes
|
{edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/edx_enterprise_data.egg-info/requires.txt
RENAMED
File without changes
|
{edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/edx_enterprise_data.egg-info/top_level.txt
RENAMED
File without changes
|
{edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/__init__.py
RENAMED
File without changes
|
{edx_enterprise_data-9.6.0 → edx_enterprise_data-9.7.1}/enterprise_data/admin_analytics/constants.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|