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']))
Exemple #3
0
    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
            })
Exemple #6
0
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)