Skip to content
Open
30 changes: 30 additions & 0 deletions lms/envs/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3218,6 +3218,36 @@ def _should_send_certificate_events(settings):
"enabled": False
},
},
'org.openedx.learning.program.certificate.awarded.v1': {
'learning-program-certificate-lifecycle': {
'event_key_field': 'program_certificate.program.uuid',
# .. toggle_name: EVENT_BUS_PRODUCER_CONFIG['org.openedx.learning.program.certificate.awarded.v1']
# ['learning-program-certificate-lifecycle']['enabled']
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: Enables sending PROGRAM_CERTIFICATE_AWARDED events over the event bus from
# edx-platform. Disabled until Credentials IDA is ready to consume these events instead of
# receiving REST API calls.
# .. toggle_use_cases: opt_in
# .. toggle_creation_date: 2026-05-26
'enabled': False,
},
},
'org.openedx.learning.program.certificate.revoked.v1': {
'learning-program-certificate-lifecycle': {
'event_key_field': 'program_certificate.program.uuid',
# .. toggle_name: EVENT_BUS_PRODUCER_CONFIG['org.openedx.learning.program.certificate.revoked.v1']
# ['learning-program-certificate-lifecycle']['enabled']
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: Enables sending PROGRAM_CERTIFICATE_REVOKED events over the event bus from
# edx-platform. Disabled until Credentials IDA is ready to consume these events instead of
# receiving REST API calls.
# .. toggle_use_cases: opt_in
# .. toggle_creation_date: 2026-05-26
'enabled': False,
},
},
})

#### Survey Report ####
Expand Down
44 changes: 44 additions & 0 deletions openedx/core/djangoapps/programs/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
from edx_django_utils.monitoring import set_code_owner_attribute
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from openedx_events.learning.data import ProgramCertificateData, ProgramData, UserData, UserPersonalData
from openedx_events.learning.signals import PROGRAM_CERTIFICATE_AWARDED, PROGRAM_CERTIFICATE_REVOKED
from requests.exceptions import HTTPError

from common.djangoapps.course_modes.models import CourseMode
Expand Down Expand Up @@ -364,6 +366,27 @@ def award_program_certificates(self, username): # pylint: disable=too-many-stat
try:
award_program_certificate(credentials_client, student, program_uuid)
LOGGER.info(f"Awarded program certificate to user {student.id} in program {program_uuid}")
PROGRAM_CERTIFICATE_AWARDED.send_event(
program_certificate=ProgramCertificateData(
user=UserData(
pii=UserPersonalData(
username=student.username,
email=student.email,
name=student.profile.name,
),
id=student.id,
is_active=student.is_active,
),
program=ProgramData(
uuid=program_uuid,
title="",
program_type="",
),
uuid="",
status="awarded",
url="",
)
)
except HTTPError as exc:
if exc.response.status_code == 404:
LOGGER.warning(
Expand Down Expand Up @@ -669,6 +692,27 @@ def revoke_program_certificates(self, username, course_key): # pylint: disable=
try:
revoke_program_certificate(credentials_client, username, program_uuid)
LOGGER.info(f"Revoked program certificate from user {student.id} in program {program_uuid}")
PROGRAM_CERTIFICATE_REVOKED.send_event(
program_certificate=ProgramCertificateData(
user=UserData(
pii=UserPersonalData(
username=student.username,
email=student.email,
name=student.profile.name,
),
id=student.id,
is_active=student.is_active,
),
program=ProgramData(
uuid=program_uuid,
title="",
program_type="",
),
uuid="",
status="revoked",
url="",
)
)
except HTTPError as exc:
if exc.response.status_code == 404:
LOGGER.warning(
Expand Down
Loading