From ee350884ff2d1c715cbbe276bb99a5d01f6b8fee Mon Sep 17 00:00:00 2001 From: Katrina Nguyen <71999631+katrinan029@users.noreply.github.com> Date: Mon, 30 Sep 2024 13:48:11 -0700 Subject: [PATCH] feat: update enterprise group model and serializer (#2251) --- CHANGELOG.rst | 4 ++++ enterprise/__init__.py | 2 +- enterprise/api/v1/serializers.py | 18 +++++++++++++-- enterprise/constants.py | 6 +++++ ...221_enterprisegroup_group_type_and_more.py | 23 +++++++++++++++++++ ...ter_enterprisegroup_group_type_and_more.py | 23 +++++++++++++++++++ enterprise/models.py | 9 ++++++++ tests/test_enterprise/api/test_views.py | 6 ++++- 8 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 enterprise/migrations/0221_enterprisegroup_group_type_and_more.py create mode 100644 enterprise/migrations/0222_alter_enterprisegroup_group_type_and_more.py diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d72b87f56..b62d134e5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -17,6 +17,10 @@ Unreleased ---------- * nothing unreleased +[4.26.0] +--------- +* feat: add new field to EnterpriseGroup model and EnterpriseGroupSerializer + [4.25.19] --------- * feat: remove logging to debug SAP SuccessFactors transmission issues diff --git a/enterprise/__init__.py b/enterprise/__init__.py index 2a77a8588..40a089a7c 100644 --- a/enterprise/__init__.py +++ b/enterprise/__init__.py @@ -2,4 +2,4 @@ Your project description goes here. """ -__version__ = "4.25.19" +__version__ = "4.26.0" diff --git a/enterprise/api/v1/serializers.py b/enterprise/api/v1/serializers.py index 2215c9e54..945e4e795 100644 --- a/enterprise/api/v1/serializers.py +++ b/enterprise/api/v1/serializers.py @@ -23,7 +23,12 @@ from enterprise import models, utils # pylint: disable=cyclic-import from enterprise.api.v1.fields import Base64EmailCSVField from enterprise.api_client.lms import ThirdPartyAuthApiClient -from enterprise.constants import ENTERPRISE_ADMIN_ROLE, ENTERPRISE_PERMISSION_GROUPS, DefaultColors +from enterprise.constants import ( + ENTERPRISE_ADMIN_ROLE, + ENTERPRISE_PERMISSION_GROUPS, + GROUP_MEMBERSHIP_ACCEPTED_STATUS, + DefaultColors, +) from enterprise.logging import getEnterpriseLogger from enterprise.models import ( AdminNotification, @@ -632,7 +637,16 @@ class EnterpriseGroupSerializer(serializers.ModelSerializer): """ class Meta: model = models.EnterpriseGroup - fields = ('enterprise_customer', 'name', 'uuid', 'applies_to_all_contexts') + fields = ( + 'enterprise_customer', 'name', 'uuid', 'applies_to_all_contexts', + 'accepted_members_count', 'group_type') + + accepted_members_count = serializers.SerializerMethodField() + + def get_accepted_members_count(self, obj): + "Returns count for accepted members" + all_members = obj.get_all_learners().filter(status=GROUP_MEMBERSHIP_ACCEPTED_STATUS) + return len(all_members) class EnterpriseGroupMembershipSerializer(serializers.ModelSerializer): diff --git a/enterprise/constants.py b/enterprise/constants.py index d38e88dce..87d2cec4a 100644 --- a/enterprise/constants.py +++ b/enterprise/constants.py @@ -263,6 +263,12 @@ class FulfillmentTypes: (GROUP_MEMBERSHIP_INTERNAL_API_ERROR_STATUS, 'Internal API error'), (GROUP_MEMBERSHIP_EMAIL_ERROR_STATUS, 'Email error') ) +GROUP_TYPE_BUDGET = 'budget' +GROUP_TYPE_FLEX = 'flex' +GROUP_TYPE_CHOICES = ( + (GROUP_TYPE_BUDGET, 'Budget'), + (GROUP_TYPE_FLEX, 'Flex') +) ENTITY_ID_REGEX = r"<(\w+:)?EntityDescriptor.*?entityID=['\"](.*?)['\"].*?>" diff --git a/enterprise/migrations/0221_enterprisegroup_group_type_and_more.py b/enterprise/migrations/0221_enterprisegroup_group_type_and_more.py new file mode 100644 index 000000000..090cb9da0 --- /dev/null +++ b/enterprise/migrations/0221_enterprisegroup_group_type_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.15 on 2024-09-24 21:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('enterprise', '0220_alter_updateroleassignmentswithcustomersconfig_role'), + ] + + operations = [ + migrations.AddField( + model_name='enterprisegroup', + name='group_type', + field=models.CharField(blank=True, choices=[('budget', 'Budget'), ('flex', 'Flex')], default='flex', help_text='The type of enterprise group', max_length=20, null=True, verbose_name='Group Type'), + ), + migrations.AddField( + model_name='historicalenterprisegroup', + name='group_type', + field=models.CharField(blank=True, choices=[('budget', 'Budget'), ('flex', 'Flex')], default='flex', help_text='The type of enterprise group', max_length=20, null=True, verbose_name='Group Type'), + ), + ] diff --git a/enterprise/migrations/0222_alter_enterprisegroup_group_type_and_more.py b/enterprise/migrations/0222_alter_enterprisegroup_group_type_and_more.py new file mode 100644 index 000000000..9ed277f65 --- /dev/null +++ b/enterprise/migrations/0222_alter_enterprisegroup_group_type_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.15 on 2024-09-25 20:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('enterprise', '0221_enterprisegroup_group_type_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='enterprisegroup', + name='group_type', + field=models.CharField(choices=[('budget', 'Budget'), ('flex', 'Flex')], default='flex', help_text='The type of enterprise group', max_length=20, verbose_name='Group Type'), + ), + migrations.AlterField( + model_name='historicalenterprisegroup', + name='group_type', + field=models.CharField(choices=[('budget', 'Budget'), ('flex', 'Flex')], default='flex', help_text='The type of enterprise group', max_length=20, verbose_name='Group Type'), + ), + ] diff --git a/enterprise/models.py b/enterprise/models.py index f9d241c4c..014f8eaf2 100644 --- a/enterprise/models.py +++ b/enterprise/models.py @@ -54,6 +54,8 @@ GROUP_MEMBERSHIP_ACCEPTED_STATUS, GROUP_MEMBERSHIP_PENDING_STATUS, GROUP_MEMBERSHIP_STATUS_CHOICES, + GROUP_TYPE_CHOICES, + GROUP_TYPE_FLEX, MAX_INVITE_KEYS, DefaultColors, FulfillmentTypes, @@ -4405,6 +4407,13 @@ class EnterpriseGroup(TimeStampedModel, SoftDeletableModel): "When enabled, all learners connected to the org will be considered a member." ) ) + group_type = models.CharField( + verbose_name="Group Type", + max_length=20, + choices=GROUP_TYPE_CHOICES, + default=GROUP_TYPE_FLEX, + help_text=_("The type of enterprise group"), + ) history = HistoricalRecords() diff --git a/tests/test_enterprise/api/test_views.py b/tests/test_enterprise/api/test_views.py index aa61af33d..e14bff222 100644 --- a/tests/test_enterprise/api/test_views.py +++ b/tests/test_enterprise/api/test_views.py @@ -8030,7 +8030,8 @@ def setUp(self): group=self.group_1, pending_enterprise_customer_user=None, enterprise_customer_user__enterprise_customer=self.enterprise_customer, - activated_at=datetime.now() + activated_at=datetime.now(), + status='accepted', )) def test_group_permissions(self): @@ -8054,6 +8055,9 @@ def test_successful_list_groups(self): ) response = self.client.get(url) assert response.json().get('count') == 2 + assert response.json().get('results')[0].get('group_type') == 'flex' + serializer = serializers.EnterpriseGroupSerializer(self.group_1) + assert serializer.data['accepted_members_count'] == 11 def test_successful_retrieve_group(self): """