feat!: remove the clean_certificate_available_date mgmt cmd (#34596)

This PR removes the `clean_certificate_available_date` management command. Recently, a change was made to sync the end date of a course run with a display behavior of "end" as its certificate available date in the Credentials IDA. This change was made to resolve a long running issue with the Credentials IDA not displaying certificates to learners correctly on learner records when the display behavior is set to "end".

This management command, if run, would clear the certificate available date from the course certificate configurations in the Credentials IDA. This would be a regression based on the new functionality.  Other improvements have been made to ensure that updates made in the LMS properly flow to Credentials.

TL;DR -- this management command is no longer needed because of feature changes in edx-platform. Allowing this management command to run would break functionality for learners.
This commit is contained in:
Justin Hynes
2024-04-25 12:02:34 -04:00
committed by GitHub
parent 3852358ca2
commit e2e014cab5
4 changed files with 12 additions and 83 deletions

View File

@@ -1,18 +0,0 @@
"""
This task will clean out the misconfigured certificate available date. When courses Change their
certificates_display_behavior, the certificate_available_date was not updating properly. This is
command is meant to be ran one time to clean up any courses that were not supposed to have
certificate_available_date
"""
from django.core.management.base import BaseCommand
from openedx.core.djangoapps.credentials.tasks.v1.tasks import clean_certificate_available_date
class Command(BaseCommand):
"""
Cleans out misconfigured certificate available dates on courses that
are not meant to have them.
"""
def handle(self, *args, **options):
clean_certificate_available_date.delay()

View File

@@ -1,15 +1,15 @@
""" Command to create a credentials api configuration """
"""
Django management command used to enable Credentials functionality in this Open edX instance.
"""
from django.core.management.base import BaseCommand, CommandError
from openedx.core.djangoapps.credentials.models import CredentialsApiConfig
class Command(BaseCommand):
"""
Creates a api configuration between LMS <--> Credentials service.
This command is meant to be used in combination with other commands to
create a fully connected path to awarding program certificates in devstack.
Creates a CredentialsApiConfig in the LMS to enable Credentials functionality. This command was primarily used as
part of an optional devstack provisioning step for developers who work with the Credentials IDA.
"""
# pylint: disable=unused-argument
def handle(self, *args, **kwargs):
try:

View File

@@ -1,12 +1,10 @@
"""
A manangement command to populate the new available_date field in all CourseCertificates
in credentials. Accomplished by sending the COURSE_CERT_DATE_CHANGE signal accross all
course runs in the LMS to call a new API in credentials that will populate the date if one
is found.
A manangement command to populate the `certificate_available_date` field of the CourseCertificateConfiguration model in
the Credentials IDA.
This command is designed to be ran once to backpopulate data. New courses added or any time
the COURSE_CERT_DATE_CHANGE signal fires, the API will automatically be called as a part of
that flow.
This command is designed to be ran once to initially backpopulate data. Otherwise, anytime an existing course run
adjusts its certificate available date or certificates display behavior settings, updates will automatically be queued
and transmit to the Credentials IDA.
"""
from django.core.management.base import BaseCommand
@@ -15,9 +13,8 @@ from openedx.core.djangoapps.credentials.tasks.v1.tasks import backfill_date_for
class Command(BaseCommand):
"""
A command to populate the available_date field in the CourseCertificate model for every
course run inside of the LMS.
A management command reponsible for populating the `certificate_available_date` field of
CourseCertificateConfiguration instances in the Credentials IDA.
"""
def handle(self, *args, **options):
backfill_date_for_all_course_runs.delay()

View File

@@ -477,53 +477,3 @@ def backfill_date_for_all_course_runs():
logger.exception(error_msg)
if index % 10 == 0:
time.sleep(3)
@shared_task(base=LoggedTask, ignore_result=True)
@set_code_owner_attribute
def clean_certificate_available_date():
"""
Historically, when courses changed their certificates_display_behavior, the certificate_available_date was not
updating properly. This task will clean out course runs that have a misconfigured certificate available date in the
Credentials IDA.
"""
course_run_list = CourseOverview.objects.exclude(
self_paced=0,
certificates_display_behavior="end",
certificate_available_date__isnull=False
)
for index, course_run in enumerate(course_run_list):
logger.info(f"removing certificate_available_date for course {course_run.id}")
course_key = str(course_run.id)
course_modes = CourseMode.objects.filter(course_id=course_key)
# There should only ever be one certificate relevant mode per course run
modes = [
mode.slug for mode in course_modes
if mode.slug in CourseMode.CERTIFICATE_RELEVANT_MODES or CourseMode.is_eligible_for_certificate(mode.slug)
]
if len(modes) != 1:
logger.exception(f'Either course {course_key} has no certificate mode or multiple modes. Task failed.')
# if there is only one relevant mode, post to credentials
else:
try:
credentials_client = get_credentials_api_client(
User.objects.get(username=settings.CREDENTIALS_SERVICE_USERNAME),
)
credentials_api_base_url = get_credentials_api_base_url()
api_url = urljoin(f"{credentials_api_base_url}/", "course_certificates/")
response = credentials_client.post(
api_url,
json={
"course_id": course_key,
"certificate_type": modes[0],
"certificate_available_date": None,
"is_active": True,
}
)
response.raise_for_status()
logger.info(f"certificate_available_date updated for course {course_key}")
except Exception: # lint-amnesty, pylint: disable=W0703
error_msg = f"Failed to send certificate_available_date for course {course_key}."
logger.exception(error_msg)
if index % 10 == 0:
time.sleep(3)