def reg_verbs(self): verb_list = [RegistrationType.get_cached(name='Enrolled', category='student')] if self.use_priority: for i in range(0, self.priority_limit): name = 'Priority/%d' % (i + 1) verb_list.append(RegistrationType.get_map(include=[name], category='student')[name]) # Require that the /Applied bit is in the list, since students cannot enroll # directly in classes with application questions. applied_verb = RegistrationType.get_map(include=['Applied'], category='student')['Applied'] if applied_verb not in verb_list: verb_list.append(applied_verb) return verb_list
def forwards(self, orm): # Save the original verb names original_verb_len = len('V/Flags/Registration/') ## MIT-specific fix: Make sure all SCRMI's actually have regg verbs default_verb = GetNode("V/Flags/Registration/Enrolled") verb_map = {} name_map = {} for item in StudentClassRegModuleInfo.objects.all().values_list('id', 'signup_verb_id'): verb_map[item[0]] = item[1] if item[1] else default_verb.id for key, val in verb_map.iteritems(): name_map[key] = DataTree.objects.get(id=val).get_uri()[original_verb_len:] # Delete the verbs (need to allow null values) db.start_transaction() db.alter_column('modules_studentclassregmoduleinfo', 'signup_verb_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['datatree.DataTree'], null=True)) for item in StudentClassRegModuleInfo.objects.all(): item.signup_verb = None item.save() db.commit_transaction() # Changing field 'StudentClassRegModuleInfo.signup_verb' db.alter_column('modules_studentclassregmoduleinfo', 'signup_verb_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['program.RegistrationType'], null=True)) db.start_transaction() # Change verb IDs to RegistrationTypes for item in StudentClassRegModuleInfo.objects.all(): item.signup_verb = RegistrationType.get_map(include=[name_map[item.id]], category='student')[name_map[item.id]] item.save() db.commit_transaction() db.alter_column('modules_studentclassregmoduleinfo', 'signup_verb_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['program.RegistrationType']))
def reg_verbs(self): verb_list = [self.signup_verb] if self.use_priority: for i in range(0, self.priority_limit): name = 'Priority/%d' % (i + 1) verb_list.append( RegistrationType.get_map(include=[name], category='student')[name]) # Require that the /Applied bit is in the list, since students cannot enroll # directly in classes with application questions. applied_verb = RegistrationType.get_map(include=['Applied'], category='student')['Applied'] if applied_verb not in verb_list: verb_list.append(applied_verb) return verb_list
def select_students(self, request, tl, one, two, module, extra, prog): # Get preregistered and enrolled students try: sec = ClassSection.objects.get(id=extra) except (ValueError, ClassSection.DoesNotExist): raise ESPError( 'Class section not found. If you came from a link on our site, please notify the webmasters.', log=False) students_list = sec.students_prereg() if request.method == 'POST': # Handle form submission # result_strs = [] data = request.POST.copy() sections_dict = {} for key in data: key_dir = key.split('_') if key_dir[0] == 'regstatus' and len(key_dir) == 3: student_id = int(key_dir[1]) sec_id = int(key_dir[2]) if sec_id not in sections_dict: sections_dict[sec_id] = [{ 'id': student_id, 'status': data[key] }] else: sections_dict[sec_id].append({ 'id': student_id, 'status': data[key] }) for sec_id in sections_dict: sec = ClassSection.objects.get(id=sec_id) sec.cache['students'] = None sec.cache['num_students'] = None for item in sections_dict[sec_id]: student = ESPUser.objects.get(id=item['id']) ignore = False value = item['status'] if value == 'enroll': verb_name = 'Enrolled' elif value == 'reject': verb_name = 'Rejected' else: ignore = True if not ignore: rel = RegistrationType.get_map( include=['Enrolled', 'Rejected'], category='student')[verb_name] other_regs = sec.getRegistrations(student).filter( relationship__name__in=['Enrolled', 'Rejected']) found = False for reg in other_regs: if not found and reg.relationship == rel: found = True else: reg.expire() if not found: new_reg = StudentRegistration(user=student, relationship=rel, section=sec) new_reg.save() # Jazz up this information a little #Not having much luck with query count/performance when selecting related parent_class and parent_class__category #Creating a lookup dict instead to strip out duplicate ClassSubject instances student_regs = StudentRegistration.valid_objects().filter(user__in=students_list) \ .order_by('start_date').select_related('section','user','relationship') student_regs = student_regs.filter( section__parent_class__parent_program=self.program) student_sections_dict = defaultdict(set) student_reg_dict = defaultdict(set) #need a unique set of parent_class ids #creating lookup dicts to avoid hitting database(was not solved with #select_related or prefecth_related parent_class_id_set = set() sections = set() for reg in student_regs: student_sections_dict[reg.user].add(reg.section) display_name = reg.relationship.displayName or reg.relationship.name sections.add(reg.section) parent_class_id_set.add(reg.section.parent_class_id) student_reg_dict['%i_%i' % ( reg.user.id, reg.section.id, )].add(display_name) subjects = ClassSubject.objects.filter( id__in=parent_class_id_set).select_related('category') subject_categories_dict = dict([(s.id, (s, s.category)) for s in subjects]) for student in students_list: student.bits = student_reg_dict['%i_%i' % ( student.id, sec.id, )] #this is a bit of a problem because it produces the side affect of application #creation if not found student.app = student.getApplication(self.program, False) student.other_classes = [] for section in student_sections_dict[student]: parent_class, category = subject_categories_dict.get( section.parent_class_id) regtypes = student_reg_dict['%i_%i' % ( student.id, section.id, )] section_row = (section, regtypes, parent_class, category) student.other_classes.append(section_row) preregs = sec.getRegistrations(student).exclude( relationship__name__in=['Enrolled', 'Rejected']) if preregs.count() != 0: student.added_class = preregs[0].start_date if 'Enrolled' in student.bits: student.enrolled = True elif 'Rejected' in student.bits: student.rejected = True # Detect if there is an application module from esp.program.modules.handlers.studentjunctionappmodule import StudentJunctionAppModule has_app_module = False for module in prog.getModules(): if isinstance(module, StudentJunctionAppModule): has_app_module = True return render_to_response( self.baseDir() + 'select_students.html', request, { 'has_app_module': has_app_module, 'prog': prog, 'sec': sec, 'students_list': students_list })
def select_students(self, request, tl, one, two, module, extra, prog): # Get preregistered and enrolled students try: sec = ClassSection.objects.filter(id=extra)[0] except: raise ESPError( False ), 'Class section not found. If you came from a link on our site, please notify the webmasters.' students_list = sec.students_prereg() if request.method == 'POST': # Handle form submission # result_strs = [] data = request.POST.copy() sections_dict = {} for key in data: key_dir = key.split('_') if key_dir[0] == 'regstatus' and len(key_dir) == 3: student_id = int(key_dir[1]) sec_id = int(key_dir[2]) if sec_id not in sections_dict: sections_dict[sec_id] = [{ 'id': student_id, 'status': data[key] }] else: sections_dict[sec_id].append({ 'id': student_id, 'status': data[key] }) for sec_id in sections_dict: sec = ClassSection.objects.get(id=sec_id) sec.cache['students'] = None sec.cache['num_students'] = None for item in sections_dict[sec_id]: student = ESPUser(User.objects.get(id=item['id'])) ignore = False value = item['status'] if value == 'enroll': verb_name = 'Enrolled' elif value == 'reject': verb_name = 'Rejected' else: ignore = True if not ignore: rel = RegistrationType.get_map( include=['Enrolled', 'Rejected'], category='student')[verb_name] other_regs = sec.getRegistrations(student).filter( relationship__name__in=['Enrolled', 'Rejected']) found = False for reg in other_regs: if not found and reg.relationship == rel: found = True else: reg.expire() # result_strs.append('Expired: %s' % bit) if not found: new_reg = StudentRegistration(user=student, relationship=rel, section=sec) new_reg.save() # Jazz up this information a little for student in students_list: student.bits = sec.getRegVerbs(student) student.app = student.getApplication(self.program, False) student.other_classes = [ (sec2, sec2.getRegVerbs(student)) for sec2 in student.getSections(self.program).exclude( id=sec.id) ] preregs = sec.getRegistrations(student).exclude( relationship__name__in=['Enrolled', 'Rejected']) if preregs.count() != 0: student.added_class = preregs[0].start_date if 'Enrolled' in student.bits: student.enrolled = True elif 'Rejected' in student.bits: student.rejected = True # Detect if there is an application module from esp.program.modules.handlers.studentjunctionappmodule import StudentJunctionAppModule has_app_module = False for module in prog.getModules(): if isinstance(module, StudentJunctionAppModule): has_app_module = True return render_to_response( self.baseDir() + 'select_students.html', request, { 'has_app_module': has_app_module, 'prog': prog, 'sec': sec, 'students_list': students_list })
class StudentClassRegModuleInfo(models.Model): """ Define what happens when students add classes to their schedule at registration. """ module = models.ForeignKey(ProgramModuleObj) # Set to true to prevent students from registering from full classes. enforce_max = models.BooleanField( default=True, help_text= 'Check this box to prevent students from signing up for full classes.') # Filter class caps on the fly... y = ax + b # a = class_cap_multiplier # b = class_cap_offset class_cap_multiplier = models.DecimalField( max_digits=3, decimal_places=2, default='1.00', help_text= 'A multiplier for class capacities (set to 0.5 to cap all classes at half their stored capacity).' ) class_cap_offset = models.IntegerField( default=0, help_text= 'Offset for class capacities (this number is added to the original capacity of every class).' ) apply_multiplier_to_room_cap = models.BooleanField( default=False, help_text= 'Apply class cap multipler and offset to room capacity instead of class capacity.)' ) # This points to the tree node that is used for the verb when a student is added to a class. # Only 'Enrolled' actually puts them on the class roster. Other verbs may be used to # represent other statuses ('Applied', 'Rejected', etc.) # Note: When use_priority is True, sub-verbs with integer indices are used # (e.g. 'Priority/1', 'Priority/2', ...) signup_verb = models.ForeignKey( RegistrationType, default=lambda: RegistrationType.get_map( include=['Enrolled'], category='student')['Enrolled'], help_text= 'Which verb to grant a student when they sign up for a class.', null=True) # Whether to use priority use_priority = models.BooleanField( default=False, help_text='Check this box to enable priority registration.') # Number of choices a student can make for each time block (1st choice, 2nd choice, ...Nth choice.) priority_limit = models.IntegerField( default=3, help_text= 'The maximum number of choices a student can make per timeslot when priority registration is enabled.' ) # Set to true to allow classes to be added (via Ajax) using buttons on the catalog register_from_catalog = models.BooleanField( default=False, help_text= 'Check this box to allow students to add classes from the catalog page if they are logged in.' ) # Enrollment visibility visible_enrollments = models.BooleanField( default=True, help_text= 'Uncheck this box to prevent students from seeing enrollments on the catalog.' ) # Meeting times visibility visible_meeting_times = models.BooleanField( default=True, help_text= 'Uncheck this box to prevent students from seeing classes\' meeting times on the catalog.' ) # Show classes that have not yet been scheduled? show_unscheduled_classes = models.BooleanField( default=True, help_text= 'Uncheck this box to prevent people from seeing classes in the catalog before they have been scheduled.' ) # Customize buttons # - Labels confirm_button_text = models.CharField( max_length=80, default='Confirm', help_text='Label for the "confirm" button at the bottom of student reg.' ) view_button_text = models.CharField( max_length=80, default='View Receipt', help_text= 'Label for the "get receipt" button (for already confirmed students) at the bottom of student reg.' ) cancel_button_text = models.CharField( max_length=80, default='Cancel Registration', help_text='Label for the "cancel" button at the bottom of student reg.' ) temporarily_full_text = models.CharField( max_length=255, default='Class temporarily full; please check back later', help_text= 'The text that replaces the "Add class" button when the class has reached its adjusted capacity' ) # - Set to true to make the cancel button remove the student from classes they have registered for cancel_button_dereg = models.BooleanField( default=False, help_text= 'Check this box to remove a student from all of their classes when they cancel their registration.' ) # Choose which appears on student reg for the modules: checkbox list, progress bar, or nothing # ((0, 'None'),(1, 'Checkboxes'), (2, 'Progress Bar')) progress_mode = models.IntegerField( default=1, help_text= 'Select which to use on student reg: 1=checkboxes, 2=progress bar, 0=neither.' ) # Choose whether an e-mail is sent the first time a student confirms registration. send_confirmation = models.BooleanField( default=False, help_text= 'Check this box to send each student an e-mail the first time they confirm their registration. You must define an associated DBReceipt of type "confirmemail".' ) # Choose whether class IDs are shown on catalog. show_emailcodes = models.BooleanField( default=True, help_text= 'Uncheck this box to prevent e-mail codes (i.e. E534, H243) from showing up on catalog and fillslot pages.' ) # Choose whether users have to fill out "required" modules before they can see the main StudentReg page # (They still have to fill them out before confirming their registration, regardless of this setting) force_show_required_modules = models.BooleanField( default=True, help_text= "Check this box to require that users see and fill out \"required\" modules before they can see the main StudentReg page" ) def reg_verbs(self): verb_list = [self.signup_verb] if self.use_priority: for i in range(0, self.priority_limit): name = 'Priority/%d' % (i + 1) verb_list.append( RegistrationType.get_map(include=[name], category='student')[name]) # Require that the /Applied bit is in the list, since students cannot enroll # directly in classes with application questions. applied_verb = RegistrationType.get_map(include=['Applied'], category='student')['Applied'] if applied_verb not in verb_list: verb_list.append(applied_verb) return verb_list def __unicode__(self): return 'Student Class Reg Ext. for %s' % str(self.module)