Files
edx-platform/lms/djangoapps/commerce/signals.py

76 lines
2.9 KiB
Python

"""
Signal handling functions for use with external commerce service.
"""
import logging
from crum import get_current_request
from django.contrib.auth.models import AnonymousUser
from django.dispatch import receiver
from common.djangoapps.student.signals import REFUND_ORDER
from openedx.core.djangoapps.commerce.utils import is_commerce_service_configured
from .utils import refund_seat
log = logging.getLogger(__name__)
# pylint: disable=unused-argument
@receiver(REFUND_ORDER)
def handle_refund_order(sender, course_enrollment=None, **kwargs):
"""
Signal receiver for un-enrollments, used to automatically initiate refunds
when applicable.
"""
if not is_commerce_service_configured():
log.info("Commerce service not configured, skipping refund")
return
if course_enrollment and course_enrollment.refundable():
log.info("Handling refund for course enrollment %s", course_enrollment.course_id)
try:
request_user = get_request_user() or course_enrollment.user
if isinstance(request_user, AnonymousUser):
# Assume the request was initiated via server-to-server
# API call (presumably Otto). In this case we cannot
# construct a client to call Otto back anyway, because
# the client does not work anonymously, and furthermore,
# there's certainly no need to inform Otto about this request.
log.info(
"Anonymous user attempting to initiate refund for course [%s]",
course_enrollment.course_id,
)
return
log.info("Initiating refund_seat for user [%s] for course enrollment %s",
course_enrollment.user.id, course_enrollment.course_id)
refund_seat(course_enrollment, change_mode=True)
except Exception: # pylint: disable=broad-except
# don't assume the signal was fired with `send_robust`.
# avoid blowing up other signal handlers by gracefully
# trapping the Exception and logging an error.
log.exception(
"Unexpected exception while attempting to initiate refund for user [%s], course [%s]",
course_enrollment.user.id,
course_enrollment.course_id,
)
elif course_enrollment:
log.info(
"Not refunding seat for course enrollment %s, as its not refundable",
course_enrollment.course_id
)
else:
log.info("Not refunding seat for course due to missing course enrollment")
def get_request_user():
"""
Helper to get the authenticated user from the current HTTP request (if
applicable).
If the requester of an unenrollment is not the same person as the student
being unenrolled, we authenticate to the commerce service as the requester.
"""
request = get_current_request()
return getattr(request, 'user', None)