edx-enterprise-data 9.6.0__py3-none-any.whl → 9.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edx-enterprise-data
3
- Version: 9.6.0
3
+ Version: 9.7.0
4
4
  Summary: Enterprise Reporting
5
5
  Home-page: https://github.com/openedx/edx-enterprise-data
6
6
  Author: edX
@@ -1,4 +1,4 @@
1
- enterprise_data/__init__.py,sha256=VFLkpUM-QjqgepwwvjAotcIKFN_2QHIHdVaKNhZs3ck,123
1
+ enterprise_data/__init__.py,sha256=-XYlQBRXnJXltF46PlBf71t4JXIIDeiUw42P7lcjs5E,123
2
2
  enterprise_data/apps.py,sha256=aF6hZwDfI2oWj95tUTm_2ikHueQj-jLj-u0GrgzpsQI,414
3
3
  enterprise_data/clients.py,sha256=GvQupy5TVYfO_IKC3yzXSAgNP54r-PtIjidM5ws9Iks,3947
4
4
  enterprise_data/constants.py,sha256=uCKjfpdlMYFZJsAj3n9RMw4Cmg5_6s3NuwocO-fch3s,238
@@ -30,16 +30,16 @@ enterprise_data/api/v0/serializers.py,sha256=dngZTk6DhRxApchQKCMp1B_c8aVnQtH0NCq
30
30
  enterprise_data/api/v0/urls.py,sha256=vzJjqIo_S3AXWs9Us8XTaJc3FnxLbYzAkmLyuDQqum0,699
31
31
  enterprise_data/api/v0/views.py,sha256=4RslZ4NZOU-844bnebEQ71ji2utRY7jEijqC45oQQD0,14380
32
32
  enterprise_data/api/v1/__init__.py,sha256=1aAzAYU5hk-RW6cKUxa1645cbZMxn7GIZ7OMjWc9MKI,46
33
- enterprise_data/api/v1/serializers.py,sha256=qkHjQcqMSsJKBo2C5NpQTm1Nmrh0VBisGbosAp-w71E,10593
34
- enterprise_data/api/v1/urls.py,sha256=vPBZ7p9hsj-lMowqbp29sd2hKhHtICCMVal6th4eQxg,3995
33
+ enterprise_data/api/v1/serializers.py,sha256=oS09fMJyb3DkSc2y5TH5Yknd9NjYrlmWMRPNqBZ741U,10902
34
+ enterprise_data/api/v1/urls.py,sha256=IpOyS9UWuyip6fw6gtrxBw9SZLOdxh3sQ2j0Gdk4eOw,4180
35
35
  enterprise_data/api/v1/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
36
  enterprise_data/api/v1/views/analytics_completions.py,sha256=4jg2I50TNn2Q6InLCI9eS1MBiFo4SMRsTx4kZJtNmpI,6268
37
37
  enterprise_data/api/v1/views/analytics_engagements.py,sha256=W9DNalWIgoeo_KXqapDj2_ireRyXU47nKHw95sAEtxM,6306
38
38
  enterprise_data/api/v1/views/analytics_enrollments.py,sha256=HXgoFwvXk-CZcf6qbVOfYSCnkfDxGvfHxl0j3RcKz7A,6290
39
39
  enterprise_data/api/v1/views/analytics_leaderboard.py,sha256=zwd-2A2sctjAdx5BUjCqiwcZ5aNvM8wfm386pR-RwGQ,4114
40
40
  enterprise_data/api/v1/views/base.py,sha256=Kkmd5zgEBAhvwS_GoGXSK6lgbDNwSPioYn-QbnizI3w,3416
41
- enterprise_data/api/v1/views/enterprise_admin.py,sha256=DsR1oHFhe6LCIFjIJ4YLLZ7PUChvNlFfdZD-sxHoijY,7388
42
- enterprise_data/api/v1/views/enterprise_learner.py,sha256=NRo22ZvRBZ8nFvvOr6Tp1ZtMnjx55c9WcIdf2VoBYq4,18021
41
+ enterprise_data/api/v1/views/enterprise_admin.py,sha256=hAZR7dh8MIFMibs1rw0mPcdj_DyTjTpa0OqmrGPNdoM,8205
42
+ enterprise_data/api/v1/views/enterprise_learner.py,sha256=NqI_Tlz5v3p4fYZe2RRCg54AizslZdHB3Ckh8YQrhIM,18163
43
43
  enterprise_data/api/v1/views/enterprise_offers.py,sha256=VifxgqTLFLVw4extYPlHcN1N_yjXcsYsAlYEnAbpb10,1266
44
44
  enterprise_data/cache/__init__.py,sha256=fiBUploll1kmDy2vCmnNpeZVTD4ewsgtRF14vVs0Rb4,1850
45
45
  enterprise_data/cache/decorators.py,sha256=vLbXK9VSv-HzVkkXS1-TkuSMxudwyxz04WFsAXqmjuM,1273
@@ -128,7 +128,7 @@ enterprise_data/tests/api/v1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
128
128
  enterprise_data/tests/api/v1/test_serializers.py,sha256=DwgEHcyOP3oqNUPB2O-NkJGeO_cYs9XJiq7791vJLZE,3682
129
129
  enterprise_data/tests/api/v1/test_views.py,sha256=rLqUHfar0HdBNtz33hQxd_0qUUgr7Ku3KwQSQ1B4Ypg,15213
130
130
  enterprise_data/tests/api/v1/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
- enterprise_data/tests/api/v1/views/test_enterprise_admin.py,sha256=ysdxVJU-beWQ7eCCTvnKR4br8VFz2lPg7w64z9mrado,9495
131
+ enterprise_data/tests/api/v1/views/test_enterprise_admin.py,sha256=OxeCL_-wotTOoe7cQxJTFDNataBRn5y8ei6GM5-EklA,11052
132
132
  enterprise_data_roles/__init__.py,sha256=toCpbypm2uDoWVw29_em9gPFNly8vNUS__C0b4TCqEg,112
133
133
  enterprise_data_roles/admin.py,sha256=QNP0VeWE092vZzpyxOA5UJK1nNGl5e71B1J0RCwo_nU,998
134
134
  enterprise_data_roles/apps.py,sha256=nKi8TyuQ5Q6WGtKs5QeXvUTc3N-YQjKhyBnm2EM3Bng,260
@@ -169,8 +169,8 @@ enterprise_reporting/tests/test_send_enterprise_reports.py,sha256=WtL-RqGgu2x5PP
169
169
  enterprise_reporting/tests/test_utils.py,sha256=Zt_TA0LVb-B6fQGkUkAKKVlUKKnQh8jnw1US1jKe7g8,9493
170
170
  enterprise_reporting/tests/test_vertica_client.py,sha256=-R2yNCGUjRtoXwLMBloVFQkFYrJoo613VCr61gwI3kQ,140
171
171
  enterprise_reporting/tests/utils.py,sha256=xms2LM7DV3wczXEfctOK1ddel1EE0J_YSr17UzbCDy4,1401
172
- edx_enterprise_data-9.6.0.dist-info/LICENSE,sha256=dql8h4yceoMhuzlcK0TT_i-NgTFNIZsgE47Q4t3dUYI,34520
173
- edx_enterprise_data-9.6.0.dist-info/METADATA,sha256=JsMdNqhhyF1TMgIgv6t6t489_NzHkuaS9SI0ZFnvfu4,1569
174
- edx_enterprise_data-9.6.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
175
- edx_enterprise_data-9.6.0.dist-info/top_level.txt,sha256=f5F2kU-dob6MqiHJpgZkFzoCD5VMhsdpkTV5n9Tvq3I,59
176
- edx_enterprise_data-9.6.0.dist-info/RECORD,,
172
+ edx_enterprise_data-9.7.0.dist-info/LICENSE,sha256=dql8h4yceoMhuzlcK0TT_i-NgTFNIZsgE47Q4t3dUYI,34520
173
+ edx_enterprise_data-9.7.0.dist-info/METADATA,sha256=bDigs0YXxVqQLa6h2E7tuDnZ-WVtg6VkvlEt6i5dWsk,1569
174
+ edx_enterprise_data-9.7.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
175
+ edx_enterprise_data-9.7.0.dist-info/top_level.txt,sha256=f5F2kU-dob6MqiHJpgZkFzoCD5VMhsdpkTV5n9Tvq3I,59
176
+ edx_enterprise_data-9.7.0.dist-info/RECORD,,
@@ -2,4 +2,4 @@
2
2
  Enterprise data api application. This Django app exposes API endpoints used by enterprises.
3
3
  """
4
4
 
5
- __version__ = "9.6.0"
5
+ __version__ = "9.7.0"
@@ -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
@@ -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
 
@@ -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)
@@ -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
+ ]