Esempio n. 1
0
    def __init__(self, program, **kwargs):
        """ Set constant parameters for class changes. """

        assert isinstance(program,(Program,int))
        self.program = program
        if isinstance(program,int):
            self.program = Program.objects.get(id=program)
        print self.program
        iscorrect = raw_input("Is this the correct program (y/[n])? ")
        assert (iscorrect.lower() == 'y' or iscorrect.lower() == 'yes')
        self.now = datetime.now()
        self.options = ClassChangeController.default_options.copy()
        self.options.update(kwargs)
        self.students_not_checked_in = []
        self.deadline = self.now
        if 'deadline' in self.options.keys():
            self.deadline = self.options['deadline']

        self.Q_SR_NOW = nest_Q(StudentRegistration.is_valid_qobject(self.now), 'studentregistration')
        self.Q_SR_PROG = Q(studentregistration__section__parent_class__parent_program=self.program, studentregistration__section__meeting_times__isnull=False) & self.Q_SR_NOW
        self.Q_SR_REQ = Q(studentregistration__relationship__name="Request") & self.Q_SR_PROG
        self.Q_NOW = StudentRegistration.is_valid_qobject(self.now)
        self.Q_PROG = Q(section__parent_class__parent_program=self.program, section__meeting_times__isnull=False) & self.Q_NOW
        self.Q_REQ = Q(relationship__name="Request") & self.Q_PROG

        self.students = ESPUser.objects.filter(self.Q_SR_REQ).order_by('id').distinct()
        if 'students_not_checked_in' in self.options.keys() and isinstance(self.options['students_not_checked_in'],QuerySet):
            self.students_not_checked_in = list(self.options['students_not_checked_in'].values_list('id',flat=True).distinct())
        else:
            self.students_not_checked_in = list(self.students.exclude(id__in=self.program.students()['attended']).values_list('id',flat=True).distinct())

        self.priority_limit = self.program.priorityLimit()
        self._init_Q_objects()
        self.sections = self.program.sections().filter(status__gt=0, parent_class__status__gt=0, meeting_times__isnull=False).order_by('id').select_related('parent_class','parent_class__parent_program').distinct()
        if not self.options['use_closed_classes']:
            self.sections = self.sections.filter(registration_status=0).distinct()
        self.timeslots = self.program.getTimeSlots().order_by('id').distinct()
        self.num_timeslots = len(self.timeslots)
        self.num_students = len(self.students)
        self.num_sections = len(self.sections)






        numpy.random.seed(self.now.microsecond)

        self.initialize()

        if self.options['stats_display']:
            logger.info('Initialized lottery assignment for %d students, %d sections, %d timeslots', self.num_students, self.num_sections, self.num_timeslots)
    def __init__(self, program, **kwargs):
        """ Set constant parameters for class changes. """

        assert isinstance(program,(Program,int))
        self.program = program
        if isinstance(program,int):
            self.program = Program.objects.get(id=program)
        print self.program
        iscorrect = raw_input("Is this the correct program (y/[n])? ")
        assert (iscorrect.lower() == 'y' or iscorrect.lower() == 'yes')
        self.now = datetime.now()
        self.options = ClassChangeController.default_options.copy()
        self.options.update(kwargs)
        self.students_not_checked_in = []
        self.deadline = self.now
        if 'deadline' in self.options.keys():
            self.deadline = self.options['deadline']
        self.Q_SR_NOW = nest_Q(StudentRegistration.is_valid_qobject(self.now), 'studentregistration')
        self.Q_SR_PROG = Q(studentregistration__section__parent_class__parent_program=self.program, studentregistration__section__meeting_times__isnull=False) & self.Q_SR_NOW
        self.Q_SR_REQ = Q(studentregistration__relationship__name="Request") & self.Q_SR_PROG
        self.Q_NOW = StudentRegistration.is_valid_qobject(self.now)
        self.Q_PROG = Q(section__parent_class__parent_program=self.program, section__meeting_times__isnull=False) & self.Q_NOW
        self.Q_REQ = Q(relationship__name="Request") & self.Q_PROG
        self.students = ESPUser.objects.filter(self.Q_SR_REQ).order_by('id').distinct()
        if 'students_not_checked_in' in self.options.keys() and isinstance(self.options['students_not_checked_in'],QuerySet):
            self.students_not_checked_in = list(self.options['students_not_checked_in'].values_list('id',flat=True).distinct())
        else:
            self.students_not_checked_in = list(self.students.exclude(id__in=self.program.students()['attended']).values_list('id',flat=True).distinct())
        self.priority_limit = self.program.priorityLimit()
        self._init_Q_objects()
        self.sections = self.program.sections().filter(status__gt=0, parent_class__status__gt=0, meeting_times__isnull=False).order_by('id').select_related('parent_class','parent_class__parent_program','meeting_times').distinct()
        if not self.options['use_closed_classes']:
            self.sections = self.sections.filter(registration_status=0).distinct()
        self.timeslots = self.program.getTimeSlots().order_by('id').distinct()
        self.num_timeslots = len(self.timeslots)
        self.num_students = len(self.students)
        self.num_sections = len(self.sections)






        numpy.random.seed(self.now.microsecond)

        self.initialize()

        if self.options['stats_display']:
            logger.info('Initialized lottery assignment for %d students, %d sections, %d timeslots', self.num_students, self.num_sections, self.num_timeslots)
Esempio n. 3
0
    def students(self, QObject=False):

        Enrolled = Q(studentregistration__relationship__name='Enrolled')
        Par = Q(studentregistration__section__parent_class__parent_program=self
                .program)
        Unexpired = nest_Q(StudentRegistration.is_valid_qobject(),
                           'studentregistration')

        # Force Django to generate two subqueries without joining SRs to SSIs,
        # as efficiently as possible since it's still a big query.
        sr_ids = StudentRegistration.valid_objects().filter(
            section__parent_class__parent_program=self.program).values(
                'user').distinct()
        ssi_ids = StudentSubjectInterest.valid_objects().filter(
            subject__parent_program=self.program).values('user').distinct()
        any_reg_q = Q(id__in=sr_ids) | Q(id__in=ssi_ids)

        qobjects = {
            'enrolled': Enrolled & Par & Unexpired,
            'classreg': any_reg_q,
        }

        if QObject:
            return qobjects
        else:
            return {
                k: ESPUser.objects.filter(v).distinct()
                for k, v in qobjects.iteritems()
            }
    def students(self, QObject = False):

        Enrolled = Q(studentregistration__relationship__name='Enrolled')
        Par = Q(studentregistration__section__parent_class__parent_program=self.program)
        Unexpired = nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration')

        # Force Django to generate two subqueries without joining SRs to SSIs,
        # as efficiently as possible since it's still a big query.
        sr_ids = StudentRegistration.valid_objects().filter(
            section__parent_class__parent_program=self.program
        ).values('user').distinct()
        ssi_ids = StudentSubjectInterest.valid_objects().filter(
            subject__parent_program=self.program).values('user').distinct()
        any_reg_q = Q(id__in = sr_ids) | Q(id__in = ssi_ids)

        qobjects = {
            'enrolled': Enrolled & Par & Unexpired,
            'classreg': any_reg_q,
        }

        if QObject:
            return qobjects
        else:
            return {k: ESPUser.objects.filter(v).distinct()
                    for k, v in qobjects.iteritems()}
Esempio n. 5
0
    def clear_saved_assignments(self, delete=False):
        """ Expire/delete all previous StudentRegistration enrollments associated with the program. """

        old_registrations = StudentRegistration.objects.filter(section__parent_class__parent_program=self.program, relationship__name='Enrolled')
        if delete:
            old_registrations.delete()
        else:
            old_registrations.filter(StudentRegistration.is_valid_qobject()).update(end_date=datetime.now())
 def students(self, QObject=False):
     q = Q(studentregistration__section__parent_class__parent_program=self.
           program) & nest_Q(StudentRegistration.is_valid_qobject(),
                             'studentregistration')
     if QObject:
         return {'lotteried_students': q}
     else:
         return {'lotteried_students': ESPUser.objects.filter(q).distinct()}
    def classchangerequest(self, request, tl, one, two, module, extra, prog):
        timeslots = prog.getTimeSlots()
        sections = prog.sections().filter(status=10, meeting_times__isnull=False).distinct()

        enrollments = {}
        for timeslot in timeslots:
            try:
                enrollments[timeslot] = ClassSubject.objects.get(nest_Q(StudentRegistration.is_valid_qobject(), 'sections__studentregistration'), sections__studentregistration__relationship__name="Enrolled", sections__studentregistration__user=request.user, sections__meeting_times=timeslot, parent_program=prog)
            except ClassSubject.DoesNotExist:
                enrollments[timeslot] = None

        context = {}
        context['timeslots'] = timeslots
        context['enrollments'] = enrollments
        context['user'] = request.user
        if 'success' in request.GET:
            context['success'] = True
        else:
            context['success'] = False

        if request.user.isStudent():
            sections_by_slot = dict([(timeslot,[(section, 1 == StudentRegistration.valid_objects().filter(user=context['user'], section=section, relationship__name="Request").count()) for section in sections if section.get_meeting_times()[0] == timeslot and section.parent_class.grade_min <= request.user.getGrade(prog) <= section.parent_class.grade_max and section.parent_class not in enrollments.values() and ESPUser.getRankInClass(request.user, section.parent_class) in (5,10)]) for timeslot in timeslots])
        else:
            sections_by_slot = dict([(timeslot,[(section, False) for section in sections if section.get_meeting_times()[0] == timeslot]) for timeslot in timeslots])

        fields = {}
        for i, timeslot in enumerate(sections_by_slot.keys()):
            choices = [('0', "I'm happy with my current enrollment.")]
            initial = '0'
            for section in sections_by_slot[timeslot]:
                choices.append((section[0].emailcode(), section[0].emailcode()+": "+section[0].title()))
                if section[1]:
                    initial = section[0].emailcode()
            fields['timeslot_'+str(i+1)] = forms.ChoiceField(label="Timeslot "+str(i+1)+" ("+timeslot.pretty_time()+")", choices=choices, initial=initial)

        form = type('ClassChangeRequestForm', (forms.Form,), fields)
        context['form'] = form()
        if request.method == "POST":
            old_requests = StudentRegistration.valid_objects().filter(user=context['user'], section__parent_class__parent_program=prog, relationship__name="Request")
            for r in old_requests:
                r.expire()
            form = form(request.POST)
            if form.is_valid():
                for value in form.cleaned_data.values():
                    section = None
                    for s in sections:
                        if s.emailcode() == value:
                            section = s
                            break
                    if not section:
                        continue
                    r = StudentRegistration.valid_objects().get_or_create(user=context['user'], section=section, relationship=RegistrationType.objects.get_or_create(name="Request", category="student")[0])[0]
                    r.save()

                return HttpResponseRedirect(request.path.rstrip('/')+'/?success')
        else:
            return render_to_response(self.baseDir() + 'classchangerequest.html', request, context)
Esempio n. 8
0
 def get_schedule_json(self, request, tl, one, two, module, extra, prog):
     resp = HttpResponse(content_type='application/json')
     result = {'user': None, 'user_grade': 0, 'sections': [], 'messages': []}
     try:
         result['user'] = int(request.GET['user'])
     except:
         result['messages'].append('Error: no user specified.')
     if result['user']:
         result['user_grade'] = ESPUser.objects.get(id=result['user']).getGrade(program=prog)
         result['sections'] = list(ClassSection.objects.filter(nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'), status__gt=0, parent_class__status__gt=0, parent_class__parent_program=prog, studentregistration__relationship__name='Enrolled', studentregistration__user__id=result['user']).values_list('id', flat=True).distinct())
     json.dump(result, resp)
     return resp
 def get_schedule_json(self, request, tl, one, two, module, extra, prog):
     resp = HttpResponse(content_type='application/json')
     result = {'user': None, 'user_grade': 0, 'sections': [], 'messages': []}
     try:
         result['user'] = int(request.GET['user'])
     except:
         result['messages'].append('Error: no user specified.')
     if result['user']:
         result['user_grade'] = ESPUser.objects.get(id=result['user']).getGrade(program=prog)
         result['sections'] = list(ClassSection.objects.filter(nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'), status__gt=0, parent_class__status__gt=0, parent_class__parent_program=prog, studentregistration__relationship__name='Enrolled', studentregistration__user__id=result['user']).values_list('id', flat=True).distinct())
     json.dump(result, resp)
     return resp
    def test_submit(self):
        self.client.login(username='******', password='******')
        r = self.client.get('/onsite/' + self.program.url + '/unenroll_status')
        data = json.loads(r.content)
        enrollment_ids = data['enrollments'].keys()

        r = self.client.post('/onsite/' + self.program.url + '/unenroll_students', {'selected_enrollments': ','.join(enrollment_ids)})
        self.assertContains(r, 'Expired %d student registrations' % len(enrollment_ids))
        self.assertContains(r, ', '.join(enrollment_ids))

        enrollments = StudentRegistration.objects.filter(id__in=enrollment_ids)
        self.assertFalse(enrollments.filter(StudentRegistration.is_valid_qobject()).exists())

        enrollments.update(end_date=None)
Esempio n. 11
0
    def test_submit(self):
        self.client.login(username='******', password='******')
        r = self.client.get('/onsite/' + self.program.url + '/unenroll_status')
        data = json.loads(r.content)
        enrollment_ids = data['enrollments'].keys()

        r = self.client.post(
            '/onsite/' + self.program.url + '/unenroll_students',
            {'selected_enrollments': ','.join(enrollment_ids)})
        self.assertContains(
            r, 'Expired %d student registrations' % len(enrollment_ids))
        self.assertContains(r, ', '.join(enrollment_ids))

        enrollments = StudentRegistration.objects.filter(id__in=enrollment_ids)
        self.assertFalse(
            enrollments.filter(
                StudentRegistration.is_valid_qobject()).exists())

        enrollments.update(end_date=None)
Esempio n. 12
0
 def students(self, QObject=False):
     q_sr = Q(
         studentregistration__section__parent_class__parent_program=self.
         program) & nest_Q(StudentRegistration.is_valid_qobject(),
                           'studentregistration')
     q_ssi = Q(studentsubjectinterest__subject__parent_program=self.program
               ) & nest_Q(StudentSubjectInterest.is_valid_qobject(),
                          'studentsubjectinterest')
     if QObject:
         return {
             'twophase_star_students': q_ssi,
             'twophase_priority_students': q_sr
         }
     else:
         return {
             'twophase_star_students':
             ESPUser.objects.filter(q_ssi).distinct(),
             'twophase_priority_students':
             ESPUser.objects.filter(q_sr).distinct()
         }
    def students(self, QObject=False):
        from django.db.models import Q

        Enrolled = Q(studentregistration__relationship__name='Enrolled')
        Par = Q(studentregistration__section__parent_class__parent_program=self
                .program)
        Unexpired = nest_Q(StudentRegistration.is_valid_qobject(),
                           'studentregistration')

        if QObject:
            retVal = {
                'enrolled': self.getQForUser(Enrolled & Par & Unexpired),
                'classreg': self.getQForUser(Par & Unexpired)
            }
        else:
            retVal = {
                'enrolled':
                ESPUser.objects.filter(Enrolled & Par & Unexpired).distinct(),
                'classreg':
                ESPUser.objects.filter(Par & Unexpired).distinct()
            }

        allowed_student_types = Tag.getTag("allowed_student_types",
                                           target=self.program)
        if allowed_student_types:
            allowed_student_types = allowed_student_types.split(",")
            for stutype in allowed_student_types:
                GroupName = Q(groups__name=stutype)
                if QObject:
                    retVal[stutype] = self.getQForUser(Par & Unexpired & Reg
                                                       & VerbName & VerbParent)
                else:
                    retVal[stutype] = ESPUser.objects.filter(
                        Par & Unexpired & Reg & GroupName).distinct()

        return retVal
Esempio n. 14
0
def classchangerequest(request, tl, one, two):
    from esp.program.models import Program, StudentAppResponse, StudentRegistration, RegistrationType
    from esp.program.models.class_ import ClassSubject
    from urllib import quote
    try:
        prog = Program.by_prog_inst(one, two)  #DataTree.get_by_uri(treeItem)
    except Program.DoesNotExist:
        raise Http404("Program not found.")

    if tl != "learn":
        raise Http404

    if not request.user or not request.user.is_authenticated():
        return HttpResponseRedirect(
            '%s?%s=%s' %
            (LOGIN_URL, REDIRECT_FIELD_NAME, quote(request.get_full_path())))

    if not request.user.isStudent() and not request.user.isAdmin(prog):
        allowed_student_types = Tag.getTag("allowed_student_types",
                                           prog,
                                           default='')
        matching_user_types = any(
            x in request.user.groups.all().values_list("name", flat=True)
            for x in allowed_student_types.split(","))
        if not matching_user_types:
            return render_to_response('errors/program/notastudent.html',
                                      request, {})

    errorpage = 'errors/program/wronggrade.html'

    cur_grade = request.user.getGrade(prog)
    if (not Permission.user_has_perm(
            request.user, 'GradeOverride', program=prog)
            and (cur_grade != 0 and
                 (cur_grade < prog.grade_min or cur_grade > prog.grade_max))):
        return render_to_response(errorpage, request, {})

    setattr(request, "program", prog)
    setattr(request, "tl", tl)
    setattr(request, "module", "classchangerequest")

    from django import forms
    from datetime import datetime
    from esp.utils.scheduling import getRankInClass

    timeslots = prog.getTimeSlots()
    sections = prog.sections().filter(status=10)

    enrollments = {}
    for timeslot in timeslots:
        try:
            enrollments[timeslot] = ClassSubject.objects.get(
                nest_Q(StudentRegistration.is_valid_qobject(),
                       'sections__studentregistration'),
                sections__studentregistration__relationship__name="Enrolled",
                sections__studentregistration__user=request.user,
                sections__meeting_times=timeslot,
                parent_program=prog)
        except ClassSubject.DoesNotExist:
            enrollments[timeslot] = None

    context = {}
    context['timeslots'] = timeslots
    context['enrollments'] = enrollments
    context['user'] = request.user
    if 'success' in request.GET:
        context['success'] = True
    else:
        context['success'] = False

    if request.user.isStudent():
        sections_by_slot = dict([(timeslot, [
            (section, 1 == StudentRegistration.valid_objects().filter(
                user=context['user'],
                section=section,
                relationship__name="Request").count()) for section in sections
            if section.get_meeting_times()[0] == timeslot
            and section.parent_class.grade_min <= request.user.getGrade(
                prog) <= section.parent_class.grade_max
            and section.parent_class not in enrollments.values()
            and getRankInClass(request.user, section) in (5, 10)
        ]) for timeslot in timeslots])
    else:
        sections_by_slot = dict([(timeslot, [
            (section, False) for section in sections
            if section.get_meeting_times()[0] == timeslot
        ]) for timeslot in timeslots])

    fields = {}
    for i, timeslot in enumerate(sections_by_slot.keys()):
        choices = [('0', "I'm happy with my current enrollment.")]
        initial = '0'
        for section in sections_by_slot[timeslot]:
            choices.append(
                (section[0].emailcode(),
                 section[0].emailcode() + ": " + section[0].title()))
            if section[1]:
                initial = section[0].emailcode()
        fields['timeslot_' + str(i + 1)] = forms.ChoiceField(
            label="Timeslot " + str(i + 1) + " (" + timeslot.pretty_time() +
            ")",
            choices=choices,
            initial=initial)

    form = type('ClassChangeRequestForm', (forms.Form, ), fields)
    context['form'] = form()
    if request.method == "POST":
        old_requests = StudentRegistration.valid_objects().filter(
            user=context['user'],
            section__parent_class__parent_program=prog,
            relationship__name="Request")
        for r in old_requests:
            r.expire()
        form = form(request.POST)
        if form.is_valid():
            for value in form.cleaned_data.values():
                section = None
                for s in sections:
                    if s.emailcode() == value:
                        section = s
                        break
                if not section:
                    continue
                r = StudentRegistration.objects.get_or_create(
                    user=context['user'],
                    section=section,
                    relationship=RegistrationType.objects.get_or_create(
                        name="Request", category="student")[0])[0]
                r.end_date = datetime(9999, 1, 1, 0, 0, 0, 0)
                r.save()

            return HttpResponseRedirect(request.path.rstrip('/') + '/?success')
    else:
        return render_to_response('program/classchangerequest.html', request,
                                  context)
 def students(self, QObject = False):
     q = Q(studentregistration__section__parent_class__parent_program=self.program) & nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration')
     if QObject:
         return {'lotteried_students': q}
     else:
         return {'lotteried_students': ESPUser.objects.filter(q).distinct()}
Esempio n. 16
0
    def update_schedule_json(self, request, tl, one, two, module, extra, prog):
        resp = HttpResponse(content_type='application/json')
        result = {'user': None, 'sections': [], 'messages': []}
        try:
            user = ESPUser.objects.get(id=int(request.GET['user']))
        except:
            user = None
            result['messages'].append('Error: could find user %s' % request.GET.get('user', None))
        try:
            desired_sections = json.loads(request.GET['sections'])
        except:
            result['messages'].append('Error: could not parse requested sections %s' % request.GET.get('sections', None))
            desired_sections = None

        #   Check in student, since if they're using this view they must be onsite
        q = Record.objects.filter(user=user, program=prog, event='attended')
        if not q.exists():
            new_rec, created = Record.objects.get_or_create(user=user, program=prog, event='attended')

        if user and desired_sections is not None:
            override_full = (request.GET.get("override", "") == "true")

            current_sections = list(ClassSection.objects.filter(nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'), status__gt=0, parent_class__status__gt=0, parent_class__parent_program=prog, studentregistration__relationship__name='Enrolled', studentregistration__user__id=user.id).values_list('id', flat=True).order_by('id').distinct())
            sections_to_remove = ClassSection.objects.filter(id__in=list(set(current_sections) - set(desired_sections)))
            sections_to_add = ClassSection.objects.filter(id__in=list(set(desired_sections) - set(current_sections)))

            failed_add_sections = []
            for sec in sections_to_add:
                if sec.isFull() and not override_full:
                    result['messages'].append('Failed to add %s (%s) to %s: %s (%s).  Error was: %s' % (user.name(), user.id, sec.emailcode(), sec.title(), sec.id, 'Class is currently full.'))
                    failed_add_sections.append(sec.id)

            if len(failed_add_sections) == 0:
                #   Remove sections the student wants out of
                for sec in sections_to_remove:
                    sec.unpreregister_student(user)
                    result['messages'].append('Removed %s (%s) from %s: %s (%s)' % (user.name(), user.id, sec.emailcode(), sec.title(), sec.id))

                #   Remove sections that conflict with those the student wants into
                sec_times = sections_to_add.select_related('meeting_times__id').values_list('id', 'meeting_times__id').order_by('meeting_times__id').distinct()
                sm = ScheduleMap(user, prog)
                existing_sections = []
                for (sec, ts) in sec_times:
                    if ts and ts in sm.map and len(sm.map[ts]) > 0:
                        #   We found something we need to remove
                        for sm_sec in sm.map[ts]:
                            if sm_sec.id not in sections_to_add:
                                sm_sec.unpreregister_student(user)
                                result['messages'].append('Removed %s (%s) from %s: %s (%s)' % (user.name(), user.id, sm_sec.emailcode(), sm_sec.title(), sm_sec.id))
                            else:
                                existing_sections.append(sm_sec)

                #   Add the sections the student wants
                for sec in sections_to_add:
                    if sec not in existing_sections and sec.id not in failed_add_sections:
                        error = sec.cannotAdd(user, not override_full)
                        if not error:
                            reg_result = sec.preregister_student(user, overridefull=override_full)
                            if not reg_result:
                                error = 'Class is currently full.'
                        else:
                            reg_result = False
                        if reg_result:
                            result['messages'].append('Added %s (%s) to %s: %s (%s)' % (user.name(), user.id, sec.emailcode(), sec.title(), sec.id))
                        else:
                            result['messages'].append('Failed to add %s (%s) to %s: %s (%s).  Error was: %s' % (user.name(), user.id, sec.emailcode(), sec.title(), sec.id, error))

            result['user'] = user.id
            result['sections'] = list(ClassSection.objects.filter(nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'), status__gt=0, parent_class__status__gt=0, parent_class__parent_program=prog, studentregistration__relationship__name='Enrolled', studentregistration__user__id=result['user']).values_list('id', flat=True).distinct())

        json.dump(result, resp)
        return resp
    def update_schedule_json(self, request, tl, one, two, module, extra, prog):
        resp = HttpResponse(content_type='application/json')
        result = {'user': None, 'sections': [], 'messages': []}
        try:
            user = ESPUser.objects.get(id=int(request.GET['user']))
        except:
            user = None
            result['messages'].append('Error: could find user %s' % request.GET.get('user', None))
        try:
            desired_sections = json.loads(request.GET['sections'])
        except:
            result['messages'].append('Error: could not parse requested sections %s' % request.GET.get('sections', None))
            desired_sections = None

        #   Check in student, since if they're using this view they must be onsite
        q = Record.objects.filter(user=user, program=prog, event='attended')
        if not q.exists():
            new_rec, created = Record.objects.get_or_create(user=user, program=prog, event='attended')

        if user and desired_sections is not None:
            override_full = (request.GET.get("override", "") == "true")

            current_sections = list(ClassSection.objects.filter(nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'), status__gt=0, parent_class__status__gt=0, parent_class__parent_program=prog, studentregistration__relationship__name='Enrolled', studentregistration__user__id=user.id).values_list('id', flat=True).order_by('id').distinct())
            sections_to_remove = ClassSection.objects.filter(id__in=list(set(current_sections) - set(desired_sections)))
            sections_to_add = ClassSection.objects.filter(id__in=list(set(desired_sections) - set(current_sections)))

            failed_add_sections = []
            for sec in sections_to_add:
                if sec.isFull() and not override_full:
                    result['messages'].append('Failed to add %s (%s) to %s: %s (%s).  Error was: %s' % (user.name(), user.id, sec.emailcode(), sec.title(), sec.id, 'Class is currently full.'))
                    failed_add_sections.append(sec.id)

            if len(failed_add_sections) == 0:
                #   Remove sections the student wants out of
                for sec in sections_to_remove:
                    sec.unpreregister_student(user)
                    result['messages'].append('Removed %s (%s) from %s: %s (%s)' % (user.name(), user.id, sec.emailcode(), sec.title(), sec.id))

                #   Remove sections that conflict with those the student wants into
                sec_times = sections_to_add.select_related('meeting_times__id').values_list('id', 'meeting_times__id').order_by('meeting_times__id').distinct()
                sm = ScheduleMap(user, prog)
                existing_sections = []
                for (sec, ts) in sec_times:
                    if ts and ts in sm.map and len(sm.map[ts]) > 0:
                        #   We found something we need to remove
                        for sm_sec in sm.map[ts]:
                            if sm_sec.id not in sections_to_add:
                                sm_sec.unpreregister_student(user)
                                result['messages'].append('Removed %s (%s) from %s: %s (%s)' % (user.name(), user.id, sm_sec.emailcode(), sm_sec.title(), sm_sec.id))
                            else:
                                existing_sections.append(sm_sec)

                #   Add the sections the student wants
                for sec in sections_to_add:
                    if sec not in existing_sections and sec.id not in failed_add_sections:
                        error = sec.cannotAdd(user, not override_full)
                        if not error:
                            reg_result = sec.preregister_student(user, overridefull=override_full)
                            if not reg_result:
                                error = 'Class is currently full.'
                        else:
                            reg_result = False
                        if reg_result:
                            result['messages'].append('Added %s (%s) to %s: %s (%s)' % (user.name(), user.id, sec.emailcode(), sec.title(), sec.id))
                        else:
                            result['messages'].append('Failed to add %s (%s) to %s: %s (%s).  Error was: %s' % (user.name(), user.id, sec.emailcode(), sec.title(), sec.id, error))

            result['user'] = user.id
            result['sections'] = list(ClassSection.objects.filter(nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration'), status__gt=0, parent_class__status__gt=0, parent_class__parent_program=prog, studentregistration__relationship__name='Enrolled', studentregistration__user__id=result['user']).values_list('id', flat=True).distinct())

        json.dump(result, resp)
        return resp
 def students(self, QObject = False):
     q_sr = Q(studentregistration__section__parent_class__parent_program=self.program) & nest_Q(StudentRegistration.is_valid_qobject(), 'studentregistration')
     q_ssi = Q(studentsubjectinterest__subject__parent_program=self.program) & nest_Q(StudentSubjectInterest.is_valid_qobject(), 'studentsubjectinterest')
     if QObject:
         return {'twophase_star_students': q_ssi,
                 'twophase_priority_students' : q_sr}
     else:
         return {'twophase_star_students': ESPUser.objects.filter(q_ssi).distinct(),
                 'twophase_priority_students': ESPUser.objects.filter(q_sr).distinct()}
Esempio n. 19
0
    def classchangerequest(self, request, tl, one, two, module, extra, prog):
        timeslots = prog.getTimeSlots()
        sections = prog.sections().filter(
            status=10, meeting_times__isnull=False).distinct()

        enrollments = {}
        for timeslot in timeslots:
            try:
                enrollments[timeslot] = ClassSubject.objects.get(
                    nest_Q(StudentRegistration.is_valid_qobject(),
                           'sections__studentregistration'),
                    sections__studentregistration__relationship__name=
                    "Enrolled",
                    sections__studentregistration__user=request.user,
                    sections__meeting_times=timeslot,
                    parent_program=prog)
            except ClassSubject.DoesNotExist:
                enrollments[timeslot] = None

        context = {}
        context['timeslots'] = timeslots
        context['enrollments'] = enrollments
        context['user'] = request.user
        if 'success' in request.GET:
            context['success'] = True
        else:
            context['success'] = False

        if request.user.isStudent():
            sections_by_slot = dict([(timeslot, [
                (section, 1 == StudentRegistration.valid_objects().filter(
                    user=context['user'],
                    section=section,
                    relationship__name="Request").count())
                for section in sections
                if section.get_meeting_times()[0] == timeslot
                and section.parent_class.grade_min <= request.user.getGrade(
                    prog) <= section.parent_class.grade_max and
                section.parent_class not in enrollments.values() and ESPUser.
                getRankInClass(request.user, section.parent_class) in (5, 10)
            ]) for timeslot in timeslots])
        else:
            sections_by_slot = dict([(timeslot, [
                (section, False) for section in sections
                if section.get_meeting_times()[0] == timeslot
            ]) for timeslot in timeslots])

        fields = {}
        for i, timeslot in enumerate(sections_by_slot.keys()):
            choices = [('0', "I'm happy with my current enrollment.")]
            initial = '0'
            for section in sections_by_slot[timeslot]:
                choices.append(
                    (section[0].emailcode(),
                     section[0].emailcode() + ": " + section[0].title()))
                if section[1]:
                    initial = section[0].emailcode()
            fields['timeslot_' + str(i + 1)] = forms.ChoiceField(
                label="Timeslot " + str(i + 1) + " (" +
                timeslot.pretty_time() + ")",
                choices=choices,
                initial=initial)

        form = type('ClassChangeRequestForm', (forms.Form, ), fields)
        context['form'] = form()
        if request.method == "POST":
            old_requests = StudentRegistration.valid_objects().filter(
                user=context['user'],
                section__parent_class__parent_program=prog,
                relationship__name="Request")
            for r in old_requests:
                r.expire()
            form = form(request.POST)
            if form.is_valid():
                for value in form.cleaned_data.values():
                    section = None
                    for s in sections:
                        if s.emailcode() == value:
                            section = s
                            break
                    if not section:
                        continue
                    r = StudentRegistration.valid_objects().get_or_create(
                        user=context['user'],
                        section=section,
                        relationship=RegistrationType.objects.get_or_create(
                            name="Request", category="student")[0])[0]
                    r.save()

                return HttpResponseRedirect(
                    request.path.rstrip('/') + '/?success')
        else:
            return render_to_response(
                self.baseDir() + 'classchangerequest.html', request, context)