From 500cdf851c69a12b029d1e76fb2fe15b28d54853 Mon Sep 17 00:00:00 2001 From: jajjibhai008 Date: Thu, 19 Sep 2024 16:06:01 +0500 Subject: [PATCH] feat: Add fields related to custom expiration messaging to CustomerAgreement --- license_manager/apps/api/serializers.py | 4 + license_manager/apps/subscriptions/admin.py | 6 +- ...d_subscription_modal_messaging_and_more.py | 53 +++++++++++ license_manager/apps/subscriptions/models.py | 91 +++++++++++++++++-- 4 files changed, 145 insertions(+), 9 deletions(-) create mode 100644 license_manager/apps/subscriptions/migrations/0070_customeragreement_expired_subscription_modal_messaging_and_more.py diff --git a/license_manager/apps/api/serializers.py b/license_manager/apps/api/serializers.py index 2215e073..029036be 100644 --- a/license_manager/apps/api/serializers.py +++ b/license_manager/apps/api/serializers.py @@ -371,6 +371,10 @@ class Meta: model = CustomerAgreement fields = MinimalCustomerAgreementSerializer.Meta.fields + [ 'subscriptions', + 'has_custom_license_expiration_messaging', + 'expired_subscription_modal_messaging', + 'hyper_link_text_for_expired_modal', + 'url_for_expired_modal', ] @property diff --git a/license_manager/apps/subscriptions/admin.py b/license_manager/apps/subscriptions/admin.py index 0879002c..e2924184 100644 --- a/license_manager/apps/subscriptions/admin.py +++ b/license_manager/apps/subscriptions/admin.py @@ -416,7 +416,11 @@ class CustomerAgreementAdmin(admin.ModelAdmin): 'default_enterprise_catalog_uuid', 'disable_expiration_notifications', 'license_duration_before_purge', - 'disable_onboarding_notifications' + 'disable_onboarding_notifications', + 'has_custom_license_expiration_messaging', + 'expired_subscription_modal_messaging', + 'hyper_link_text_for_expired_modal', + 'url_for_expired_modal', ) custom_fields = ('subscription_for_auto_applied_licenses',) diff --git a/license_manager/apps/subscriptions/migrations/0070_customeragreement_expired_subscription_modal_messaging_and_more.py b/license_manager/apps/subscriptions/migrations/0070_customeragreement_expired_subscription_modal_messaging_and_more.py new file mode 100644 index 00000000..d0691e7e --- /dev/null +++ b/license_manager/apps/subscriptions/migrations/0070_customeragreement_expired_subscription_modal_messaging_and_more.py @@ -0,0 +1,53 @@ +# Generated by Django 4.2.16 on 2024-09-27 13:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('subscriptions', '0069_alter_customeragreement_disable_expiration_notifications_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='customeragreement', + name='expired_subscription_modal_messaging', + field=models.CharField(blank=True, help_text='The content of a modal that will appear to learners upon subscription expiration. This text can be used for custom guidance per customer.', max_length=512, null=True), + ), + migrations.AddField( + model_name='customeragreement', + name='has_custom_license_expiration_messaging', + field=models.BooleanField(default=False, help_text='Indicates if the customer has a unique license expiration experience, instead of the standard one.'), + ), + migrations.AddField( + model_name='customeragreement', + name='hyper_link_text_for_expired_modal', + field=models.CharField(blank=True, help_text='The display text for the link that will be embedded at the end of the custom expiration modal.', max_length=255, null=True), + ), + migrations.AddField( + model_name='customeragreement', + name='url_for_expired_modal', + field=models.CharField(blank=True, help_text='The underlying url that will be embedded as a hyperlink at the end of the custom expiration modal.', max_length=512, null=True), + ), + migrations.AddField( + model_name='historicalcustomeragreement', + name='expired_subscription_modal_messaging', + field=models.CharField(blank=True, help_text='The content of a modal that will appear to learners upon subscription expiration. This text can be used for custom guidance per customer.', max_length=512, null=True), + ), + migrations.AddField( + model_name='historicalcustomeragreement', + name='has_custom_license_expiration_messaging', + field=models.BooleanField(default=False, help_text='Indicates if the customer has a unique license expiration experience, instead of the standard one.'), + ), + migrations.AddField( + model_name='historicalcustomeragreement', + name='hyper_link_text_for_expired_modal', + field=models.CharField(blank=True, help_text='The display text for the link that will be embedded at the end of the custom expiration modal.', max_length=255, null=True), + ), + migrations.AddField( + model_name='historicalcustomeragreement', + name='url_for_expired_modal', + field=models.CharField(blank=True, help_text='The underlying url that will be embedded as a hyperlink at the end of the custom expiration modal.', max_length=512, null=True), + ), + ] diff --git a/license_manager/apps/subscriptions/models.py b/license_manager/apps/subscriptions/models.py index 933e9aba..355f7913 100644 --- a/license_manager/apps/subscriptions/models.py +++ b/license_manager/apps/subscriptions/models.py @@ -143,6 +143,41 @@ class CustomerAgreement(TimeStampedModel): ), ) + has_custom_license_expiration_messaging = models.BooleanField( + default=False, + help_text=_( + "Indicates if the customer has a unique license expiration experience, instead of the standard one." + ) + ) + + expired_subscription_modal_messaging = models.CharField( + max_length=512, + blank=True, + null=True, + help_text=_( + "The content of a modal that will appear to learners upon subscription expiration. This text can be used " + "for custom guidance per customer." + ) + ) + + hyper_link_text_for_expired_modal = models.CharField( + max_length=255, + blank=True, + null=True, + help_text=_( + "The display text for the link that will be embedded at the end of the custom expiration modal." + ) + ) + + url_for_expired_modal = models.CharField( + max_length=512, + blank=True, + null=True, + help_text=_( + "The underlying url that will be embedded as a hyperlink at the end of the custom expiration modal." + ) + ) + history = HistoricalRecords() @property @@ -192,15 +227,55 @@ class Meta: verbose_name = _("Customer Agreement") verbose_name_plural = _("Customer Agreements") - def __str__(self): - """ - Return human-readable string representation. - """ - return ( - "".format( - self.enterprise_customer_slug or self.enterprise_customer_name + def clean(self): + # Check if custom messaging is enabled and messaging field is blank + if self.has_custom_license_expiration_messaging: + if not self.expired_subscription_modal_messaging: + raise ValidationError({ + "expired_subscription_modal_messaging": ( + "This field cannot be blank if 'Has Custom License Expiration Messaging' is checked." + ) + }) + + # Validate that URL field is not blank if hyperlink text is provided + if self.hyper_link_text_for_expired_modal and not self.url_for_expired_modal: + raise ValidationError({ + "url_for_expired_modal": ( + "This field cannot be blank if 'Hyper Link Text for Expired Modal' has values." + ) + }) + + # Validate that hyperlink text is not blank if URL is provided + if self.url_for_expired_modal and not self.hyper_link_text_for_expired_modal: + raise ValidationError({ + "hyper_link_text_for_expired_modal": ( + "This field cannot be blank if 'URL for Expired Modal' has values." + ) + }) + + # Ensure all fields are blank if custom messaging is disabled + if not self.has_custom_license_expiration_messaging: + if any([ + self.expired_subscription_modal_messaging, + self.hyper_link_text_for_expired_modal, + self.url_for_expired_modal + ]): + error_msg = "This field must be blank if 'Has Custom License Expiration Messaging' is unchecked." + raise ValidationError({ + "expired_subscription_modal_messaging": error_msg, + "hyper_link_text_for_expired_modal": error_msg, + "url_for_expired_modal": error_msg, + }) + + def __str__(self): + """ + Return human-readable string representation. + """ + return ( + "".format( + self.enterprise_customer_slug or self.enterprise_customer_name + ) ) - ) class PlanType(models.Model):