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

62 lines
2.2 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 unenrollments, used to automatically initiate refunds
when applicable.
"""
if not is_commerce_service_configured():
return
if course_enrollment and course_enrollment.refundable():
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.
return
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,
)
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)