def get_credit_state(self, user_id, course_key_or_id, return_course_info=False): """ Return all information about the user's credit state inside of a given course. ARGS: - user_id: The PK of the User in question - course_key: The course ID (as string or CourseKey) RETURNS: NONE (user not found or is not enrolled or is not credit course) - or - { 'enrollment_mode': the mode that the user is enrolled in the course 'profile_fullname': the name that the student registered under, used for verification 'is_credit_course': if the course has been marked as a credit bearing course 'credit_requirement_status': the user's status in fulfilling those requirements 'course_name': optional display name of the course 'course_end_date': optional end date of the course } """ # This seems to need to be here otherwise we get # circular references when starting up the app from openedx.core.djangoapps.credit.api.eligibility import ( is_credit_course, get_credit_requirement_status, ) # since we have to do name matching during various # verifications, User must have a UserProfile try: user = User.objects.select_related('profile').get(id=user_id) except ObjectDoesNotExist: # bad user_id return None course_key = _get_course_key(course_key_or_id) enrollment = CourseEnrollment.get_enrollment(user, course_key) if not enrollment or not enrollment.is_active: # not enrolled return None result = { 'enrollment_mode': enrollment.mode, 'profile_fullname': user.profile.name, 'student_email': user.email, 'is_credit_course': is_credit_course(course_key), 'credit_requirement_status': get_credit_requirement_status(course_key, user.username) } if return_course_info: course = modulestore().get_course(course_key, depth=0) result.update({ 'course_name': course.display_name, 'course_end_date': course.end, }) return result
def get_credit_state(self, user_id, course_key_or_id, return_course_info=False): """ Return all information about the user's credit state inside of a given course. ARGS: - user_id: The PK of the User in question - course_key: The course ID (as string or CourseKey) RETURNS: NONE (user not found or is not enrolled or is not credit course) - or - { 'enrollment_mode': the mode that the user is enrolled in the course 'profile_fullname': the name that the student registered under, used for verification 'is_credit_course': if the course has been marked as a credit bearing course 'credit_requirement_status': the user's status in fulfilling those requirements 'course_name': optional display name of the course 'course_end_date': optional end date of the course } """ # This seems to need to be here otherwise we get # circular references when starting up the app from openedx.core.djangoapps.credit.api.eligibility import ( is_credit_course, get_credit_requirement_status, ) # since we have to do name matching during various # verifications, User must have a UserProfile try: user = User.objects.select_related('profile').get(id=user_id) except ObjectDoesNotExist: # bad user_id return None course_key = _get_course_key(course_key_or_id) enrollment = CourseEnrollment.get_enrollment(user, course_key) if not enrollment or not enrollment.is_active: # not enrolled return None result = { 'enrollment_mode': enrollment.mode, 'profile_fullname': user.profile.name, 'student_email': user.email, 'is_credit_course': is_credit_course(course_key), 'credit_requirement_status': get_credit_requirement_status(course_key, user.username) } if return_course_info: course = modulestore().get_course(course_key, depth=0) result.update({ 'course_name': course.display_name, 'course_end_date': course.end, }) return result
def get_credit_state(self, user_id, course_key_or_id, return_course_info=False): """ Return all information about the user's credit state inside of a given course. ARGS: - user_id: The PK of the User in question - course_key: The course ID (as string or CourseKey) RETURNS: NONE (user not found or is not enrolled or is not credit course) - or - { 'enrollment_mode': the mode that the user is enrolled in the course 'profile_fullname': the name that the student registered under, used for verification 'is_credit_course': if the course has been marked as a credit bearing course 'credit_requirement_status': the user's status in fulfilling those requirements 'course_name': optional display name of the course 'course_end_date': optional end date of the course } """ # This seems to need to be here otherwise we get # circular references when starting up the app from openedx.core.djangoapps.credit.api.eligibility import ( is_credit_course, get_credit_requirement_status, ) # since we have to do name matching during various # verifications, User must have a UserProfile try: user = User.objects.select_related('profile').get(id=user_id) except ObjectDoesNotExist: # bad user_id return None course_key = _get_course_key(course_key_or_id) enrollment = CourseEnrollment.get_enrollment(user, course_key) if not enrollment or not enrollment.is_active: # not enrolled return None result = { 'enrollment_mode': enrollment.mode, 'profile_fullname': user.profile.name, 'student_email': user.email, 'is_credit_course': is_credit_course(course_key), 'credit_requirement_status': get_credit_requirement_status(course_key, user.username) } if return_course_info: try: course_overview = CourseOverview.get_from_id(course_key) result.update({ 'course_name': course_overview.display_name, 'course_end_date': course_overview.end, }) except CourseOverview.DoesNotExist: # NOTE: Since the caller requested "return_course_info=True" and we don't have course to get that info. # Also, The "get_credit_state" is called from several places directly or indirectly (Mostly from # exams/grades services) which relatively depend upon course end date. # As per the current structure of edX the exam attempts can exist without a course and they can request # credit state so, the safest options would be to send some date/time in the past (One hour in past to # be safe) so that those attempts can be marked or treated as expired/completed instead of any other # status that could be error prone. one_hour_past = datetime.now() - timedelta(hours=1) result.update({ 'course_end_date': one_hour_past, }) log.exception( "Could not get name and end_date for course %s, This happened because we were unable to " "get/create CourseOverview object for the course. It's possible that the Course has been deleted.", str(course_key), ) return result