From 7bc56c46ed94f82deda5c540a39ea4f41c55d0e2 Mon Sep 17 00:00:00 2001 From: uzairr Date: Wed, 2 Mar 2022 19:10:01 +0500 Subject: [PATCH] feat: paid unpaid named course modes Add executive education variants for paid and unpaid modes. PROD-2708 --- common/djangoapps/course_modes/models.py | 16 ++++++++--- .../migrations/0033_auto_20220307_1100.py | 28 +++++++++++++++++++ lms/djangoapps/certificates/models.py | 8 ++++-- .../program_enrollments/rest_api/v1/utils.py | 4 ++- lms/envs/common.py | 14 +++++++++- .../instructor_dashboard_2/course_info.html | 10 +++++++ 6 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 lms/djangoapps/certificates/migrations/0033_auto_20220307_1100.py diff --git a/common/djangoapps/course_modes/models.py b/common/djangoapps/course_modes/models.py index d5dcaa46e2..53c8078e0b 100644 --- a/common/djangoapps/course_modes/models.py +++ b/common/djangoapps/course_modes/models.py @@ -136,6 +136,8 @@ class CourseMode(models.Model): CREDIT_MODE = 'credit' MASTERS = 'masters' EXECUTIVE_EDUCATION = 'executive-education' + PAID_EXECUTIVE_EDUCATION = 'paid-executive-education' + UNPAID_EXECUTIVE_EDUCATION = 'unpaid-executive-education' DEFAULT_MODE = Mode( settings.COURSE_MODE_DEFAULTS['slug'], @@ -158,14 +160,18 @@ class CourseMode(models.Model): PROFESSIONAL, VERIFIED, MASTERS, - EXECUTIVE_EDUCATION + EXECUTIVE_EDUCATION, + PAID_EXECUTIVE_EDUCATION, + UNPAID_EXECUTIVE_EDUCATION ] # Modes utilized for audit/free enrollments - AUDIT_MODES = [AUDIT, HONOR] + AUDIT_MODES = [AUDIT, HONOR, UNPAID_EXECUTIVE_EDUCATION] # Modes that allow a student to pursue a verified certificate - VERIFIED_MODES = [VERIFIED, PROFESSIONAL, MASTERS, EXECUTIVE_EDUCATION] + VERIFIED_MODES = [ + VERIFIED, PROFESSIONAL, MASTERS, EXECUTIVE_EDUCATION, PAID_EXECUTIVE_EDUCATION + ] # Modes that allow a student to pursue a non-verified certificate NON_VERIFIED_MODES = [HONOR, AUDIT, NO_ID_PROFESSIONAL_MODE] @@ -174,7 +180,9 @@ class CourseMode(models.Model): CREDIT_MODES = [CREDIT_MODE] # Modes that are eligible to purchase credit - CREDIT_ELIGIBLE_MODES = [VERIFIED, PROFESSIONAL, NO_ID_PROFESSIONAL_MODE, EXECUTIVE_EDUCATION] + CREDIT_ELIGIBLE_MODES = [ + VERIFIED, PROFESSIONAL, NO_ID_PROFESSIONAL_MODE, EXECUTIVE_EDUCATION, PAID_EXECUTIVE_EDUCATION + ] # Modes for which certificates/programs may need to be updated CERTIFICATE_RELEVANT_MODES = CREDIT_MODES + CREDIT_ELIGIBLE_MODES + [MASTERS] diff --git a/lms/djangoapps/certificates/migrations/0033_auto_20220307_1100.py b/lms/djangoapps/certificates/migrations/0033_auto_20220307_1100.py new file mode 100644 index 0000000000..9d8766f60e --- /dev/null +++ b/lms/djangoapps/certificates/migrations/0033_auto_20220307_1100.py @@ -0,0 +1,28 @@ +# Generated by Django 3.2.12 on 2022-03-07 11:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('certificates', '0032_change_certificatedateoverride_date'), + ] + + operations = [ + migrations.AlterField( + model_name='certificatetemplate', + name='mode', + field=models.CharField(blank=True, choices=[('verified', 'verified'), ('honor', 'honor'), ('audit', 'audit'), ('professional', 'professional'), ('no-id-professional', 'no-id-professional'), ('masters', 'masters'), ('executive-education', 'executive-education'), ('paid-executive-education', 'paid-executive-education')], default='honor', help_text='The course mode for this template.', max_length=125, null=True), + ), + migrations.AlterField( + model_name='generatedcertificate', + name='mode', + field=models.CharField(choices=[('verified', 'verified'), ('honor', 'honor'), ('audit', 'audit'), ('professional', 'professional'), ('no-id-professional', 'no-id-professional'), ('masters', 'masters'), ('executive-education', 'executive-education'), ('paid-executive-education', 'paid-executive-education')], default='honor', max_length=32), + ), + migrations.AlterField( + model_name='historicalgeneratedcertificate', + name='mode', + field=models.CharField(choices=[('verified', 'verified'), ('honor', 'honor'), ('audit', 'audit'), ('professional', 'professional'), ('no-id-professional', 'no-id-professional'), ('masters', 'masters'), ('executive-education', 'executive-education'), ('paid-executive-education', 'paid-executive-education')], default='honor', max_length=32), + ), + ] diff --git a/lms/djangoapps/certificates/models.py b/lms/djangoapps/certificates/models.py index 3a176e9183..35b14d17fd 100644 --- a/lms/djangoapps/certificates/models.py +++ b/lms/djangoapps/certificates/models.py @@ -211,10 +211,14 @@ class GeneratedCertificate(models.Model): 'professional', 'no-id-professional', 'masters', - 'executive-education' + 'executive-education', + 'paid-executive-education', ) - VERIFIED_CERTS_MODES = [CourseMode.VERIFIED, CourseMode.CREDIT_MODE, CourseMode.MASTERS, CourseMode.EXECUTIVE_EDUCATION] # pylint: disable=line-too-long + VERIFIED_CERTS_MODES = [ + CourseMode.VERIFIED, CourseMode.CREDIT_MODE, CourseMode.MASTERS, CourseMode.EXECUTIVE_EDUCATION, + CourseMode.PAID_EXECUTIVE_EDUCATION + ] user = models.ForeignKey(User, on_delete=models.CASCADE) course_id = CourseKeyField(max_length=255, blank=True, default=None) diff --git a/lms/djangoapps/program_enrollments/rest_api/v1/utils.py b/lms/djangoapps/program_enrollments/rest_api/v1/utils.py index d1b08b35d7..1b62654827 100644 --- a/lms/djangoapps/program_enrollments/rest_api/v1/utils.py +++ b/lms/djangoapps/program_enrollments/rest_api/v1/utils.py @@ -216,7 +216,9 @@ def get_enrollments_for_courses_in_program(user, program): return CourseEnrollment.objects.filter( user=user, course_id__in=course_keys, - mode__in=[CourseMode.VERIFIED, CourseMode.MASTERS, CourseMode.EXECUTIVE_EDUCATION], + mode__in=[ + CourseMode.VERIFIED, CourseMode.MASTERS, CourseMode.EXECUTIVE_EDUCATION, CourseMode.PAID_EXECUTIVE_EDUCATION + ], is_active=True, ) diff --git a/lms/envs/common.py b/lms/envs/common.py index 5f289a301b..60ab1084d7 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -4579,7 +4579,19 @@ COURSE_ENROLLMENT_MODES = { "slug": "executive-educations", "display_name": _("Executive Education"), "min_price": 1 - } + }, + "unpaid-executive-education": { + "id": 9, + "slug": "unpaid-executive-education", + "display_name": _("Unpaid Executive Education"), + "min_price": 0 + }, + "paid-executive-education": { + "id": 10, + "slug": "paid-executive-education", + "display_name": _("Paid Executive Education"), + "min_price": 1 + }, } CONTENT_TYPE_GATE_GROUP_IDS = { diff --git a/lms/templates/instructor/instructor_dashboard_2/course_info.html b/lms/templates/instructor/instructor_dashboard_2/course_info.html index 6f2a20b622..60cf57b2e4 100644 --- a/lms/templates/instructor/instructor_dashboard_2/course_info.html +++ b/lms/templates/instructor/instructor_dashboard_2/course_info.html @@ -29,6 +29,16 @@ from openedx.core.djangolib.markup import HTML, Text ${_("Executive Education")}${modes['executive-education']} %endif + %if modes["unpaid-executive-education"] > 0: + + ${_("Unpaid Executive Education")}${modes['unpaid-executive-education']} + + %endif + %if modes["paid-executive-education"] > 0: + + ${_("Paid Executive Education")}${modes['paid-executive-education']} + + %endif %if modes['masters'] > 0: ${_("Master's")}${modes['masters']}