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
            })
Exemple #2
0
    def save_priorities(self, request, tl, one, two, module, extra, prog):
        """
        Saves the priority preferences for student registration phase 2.
        """
        if not 'json_data' in request.POST:
            return HttpResponseBadRequest('JSON data not included in request.')
        try:
            json_data = json.loads(request.POST['json_data'])
        except ValueError:
            return HttpResponseBadRequest('JSON data mis-formatted.')
        try:
            [timeslot_id] = json_data.keys()
        except ValueError:
            return HttpResponseBadRequest('JSON data mis-formatted.')
        if not isinstance(json_data[timeslot_id], dict):
            return HttpResponseBadRequest('JSON data mis-formatted.')

        timeslot = Event.objects.get(pk=timeslot_id)
        priorities = json_data[timeslot_id]
        for rel_index, cls_id in priorities.items():
            rel_name = 'Priority/%s' % rel_index
            rel = RegistrationType.objects.get(name=rel_name,
                                               category='student')

            # Pull up any registrations that exist (including expired ones)
            srs = StudentRegistration.objects.annotate(
                Min('section__meeting_times__start'))
            srs = srs.filter(user=request.user,
                             section__parent_class__parent_program=prog,
                             section__meeting_times__start__min=timeslot.start,
                             relationship=rel)

            if cls_id == '':
                # Blank: nothing selected, expire existing registrations
                for sr in srs:
                    sr.expire()
                continue

            cls_id = int(cls_id)
            sec = ClassSection.objects.annotate(Min('meeting_times__start'))
            try:
                sec = sec.get(parent_class=cls_id,
                              parent_class__parent_program=prog,
                              meeting_times__start__min=timeslot.start)
            except (ClassSection.DoesNotExist,
                    ClassSection.MultipleObjectsReturned):
                # XXX: what if a class has multiple sections in a timeblock?
                logger.warning(
                    "Could not save priority for class %s in "
                    "timeblock %s", cls_id, timeslot_id)
                continue
            # sanity checks
            if (not sec.status > 0 or not sec.parent_class.status > 0):
                logger.warning(
                    "Class '%s' was not approved.  Not letting "
                    "user '%s' register.", sec, request.user)
            if (not sec.parent_class.grade_min <= request.user.getGrade(prog)
                    or not sec.parent_class.grade_max >=
                    request.user.getGrade(prog)):
                logger.warning(
                    "User '%s' not in class grade range; not "
                    "letting them register.", request.user)
                continue

            if not srs.exists():
                # Create a new registration
                sr = StudentRegistration(user=request.user, relationship=rel)
            else:
                # Pull the first StudentRegistration, expire the others
                for sr in srs[1:]:
                    sr.expire()
                sr = srs[0]

            # Modify as needed to ensure the section is correct and
            # expiration date is valid
            if sr.section_id is None or sr.section.parent_class.id != cls_id:
                sr.section = sec
            sr.unexpire(save=False)
            sr.save()

        return self.goToCore(tl)
    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
            })
    def save_priorities(self, request, tl, one, two, module, extra, prog):
        """
        Saves the priority preferences for student registration phase 2.
        """
        if not 'json_data' in request.POST:
            return HttpResponseBadRequest('JSON data not included in request.')
        try:
            json_data = json.loads(request.POST['json_data'])
        except ValueError:
            return HttpResponseBadRequest('JSON data mis-formatted.')
        try:
            [timeslot_id] = json_data.keys()
        except ValueError:
            return HttpResponseBadRequest('JSON data mis-formatted.')
        if not isinstance(json_data[timeslot_id], dict):
            return HttpResponseBadRequest('JSON data mis-formatted.')

        timeslot = Event.objects.get(pk=timeslot_id)
        priorities = json_data[timeslot_id]
        for rel_index, cls_id in priorities.items():
            rel_name = 'Priority/%s' % rel_index
            rel = RegistrationType.objects.get(name=rel_name, category='student')

            # Pull up any registrations that exist (including expired ones)
            srs = StudentRegistration.objects.annotate(
                Min('section__meeting_times__start'))
            srs = srs.filter(
                user=request.user,
                section__parent_class__parent_program=prog,
                section__meeting_times__start__min=timeslot.start,
                relationship=rel)

            if cls_id == '':
                # Blank: nothing selected, expire existing registrations
                for sr in srs:
                    sr.expire()
                continue

            cls_id = int(cls_id)
            sec = ClassSection.objects.annotate(Min('meeting_times__start'))
            try:
                sec = sec.get(parent_class=cls_id,
                              parent_class__parent_program=prog,
                              meeting_times__start__min=timeslot.start)
            except (ClassSection.DoesNotExist,
                    ClassSection.MultipleObjectsReturned):
                # XXX: what if a class has multiple sections in a timeblock?
                logger.warning("Could not save priority for class %s in "
                               "timeblock %s", cls_id, timeslot_id)
                continue
            # sanity checks
            if (not sec.status > 0 or not sec.parent_class.status > 0):
                logger.warning("Class '%s' was not approved.  Not letting "
                               "user '%s' register.", sec, request.user)
            if (not sec.parent_class.grade_min <= request.user.getGrade(prog)
                or not sec.parent_class.grade_max >= request.user.getGrade(prog)):
                logger.warning("User '%s' not in class grade range; not "
                               "letting them register.", request.user)
                continue

            if not srs.exists():
                # Create a new registration
                sr = StudentRegistration(
                    user=request.user,
                    relationship=rel)
            else:
                # Pull the first StudentRegistration, expire the others
                for sr in srs[1:]:
                    sr.expire()
                sr = srs[0]

            # Modify as needed to ensure the section is correct and
            # expiration date is valid
            if sr.section_id is None or sr.section.parent_class.id != cls_id:
                sr.section = sec
            sr.unexpire(save=False)
            sr.save()

        return self.goToCore(tl)