diff --git a/common/djangoapps/student/management/commands/pearson_dump.py b/common/djangoapps/student/management/commands/pearson_dump.py new file mode 100644 index 0000000000..28931dc468 --- /dev/null +++ b/common/djangoapps/student/management/commands/pearson_dump.py @@ -0,0 +1,76 @@ +from optparse import make_option +from json import dump + +from django.core.management.base import BaseCommand, CommandError + +from student.models import TestCenterRegistration + + +class Command(BaseCommand): + + args = '' + help = """ + Dump information as JSON from TestCenterRegistration tables, including username and status. + """ + + option_list = BaseCommand.option_list + ( + make_option('--course_id', + action='store', + dest='course_id', + help='Specify a particular course.'), + make_option('--exam_series_code', + action='store', + dest='exam_series_code', + default=None, + help='Specify a particular exam, using the Pearson code'), + make_option('--accommodation_pending', + action='store_true', + dest='accommodation_pending', + default=False, + ), + ) + + def handle(self, *args, **options): + if len(args) < 1: + raise CommandError("Missing single argument: output JSON file") + + # get output location: + outputfile = args[0] + + # construct the query object to dump: + registrations = TestCenterRegistration.objects.all() + if 'course_id' in options and options['course_id']: + registrations = registrations.filter(course_id=options['course_id']) + if 'exam_series_code' in options and options['exam_series_code']: + registrations = registrations.filter(exam_series_code=options['exam_series_code']) + + # collect output: + output = [] + for registration in registrations: + if 'accommodation_pending' in options and options['accommodation_pending'] and not registration.accommodation_is_pending: + continue + record = {'username' : registration.testcenter_user.user.username, + 'email' : registration.testcenter_user.email, + 'first_name' : registration.testcenter_user.first_name, + 'last_name' : registration.testcenter_user.last_name, + 'client_candidate_id' : registration.client_candidate_id, + 'client_authorization_id' : registration.client_authorization_id, + 'course_id' : registration.course_id, + 'exam_series_code' : registration.exam_series_code, + 'accommodation_request' : registration.accommodation_request, + 'accommodation_code' : registration.accommodation_code, + 'registration_status' : registration.registration_status(), + 'demographics_status' : registration.demographics_status(), + 'accommodation_status' : registration.accommodation_status(), + } + if len(registration.upload_error_message) > 0: + record['registration_error'] = registration.upload_error_message + if registration.needs_uploading: + record['needs_uploading'] = True + + output.append(record) + + # dump output: + with open(outputfile, 'w') as outfile: + dump(output, outfile) + diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py index 44b947c045..d35045ed39 100644 --- a/common/djangoapps/student/models.py +++ b/common/djangoapps/student/models.py @@ -387,6 +387,12 @@ class TestCenterRegistration(models.Model): return 'Update' elif self.uploaded_at is None: return 'Add' + elif self.registration_is_rejected: + # Assume that if the registration was rejected before, + # it is more likely this is the (first) correction + # than a second correction in flight before the first was + # processed. + return 'Add' else: # TODO: decide what to send when we have uploaded an initial version, # but have not received confirmation back from that upload. If the @@ -400,7 +406,8 @@ class TestCenterRegistration(models.Model): @property def exam_authorization_count(self): - # TODO: figure out if this should really go in the database (with a default value). + # Someday this could go in the database (with a default value). But at present, + # we do not expect anyone to be authorized to take an exam more than once. return 1 @property @@ -499,6 +506,33 @@ class TestCenterRegistration(models.Model): def registration_signup_url(self): return settings.PEARSONVUE_SIGNINPAGE_URL + def demographics_status(self): + if self.demographics_is_accepted: + return "Accepted" + elif self.demographics_is_rejected: + return "Rejected" + else: + return "Pending" + + def accommodation_status(self): + if self.accommodation_is_skipped: + return "Skipped" + elif self.accommodation_is_accepted: + return "Accepted" + elif self.accommodation_is_rejected: + return "Rejected" + else: + return "Pending" + + def registration_status(self): + if self.registration_is_accepted: + return "Accepted" + elif self.registration_is_rejected: + return "Rejected" + else: + return "Pending" + + class TestCenterRegistrationForm(ModelForm): class Meta: model = TestCenterRegistration