Ejemplo n.º 1
0
    def testGradeChange(self):
        # Create the admin user
        adminUser, c1 = ESPUser.objects.get_or_create(username='******')
        adminUser.set_password('password')
        adminUser.makeAdmin()
        # Create the student user
        studentUser, c2 = ESPUser.objects.get_or_create(username='******')
        # Make it a student
        studentUser.makeRole("Student")
        # Give it a starting grade
        student_studentinfo = StudentInfo(user=studentUser, graduation_year=ESPUser.YOGFromGrade(9))
        student_studentinfo.save()
        student_regprofile = RegistrationProfile(user=studentUser, student_info=student_studentinfo, most_recent_profile=True)
        student_regprofile.save()
        # Check that the grade starts at 9
        self.assertTrue(studentUser.getGrade() == 9)

        # Login the admin
        self.assertTrue(self.client.login(username="******", password="******"))

        testGrade = 11
        curYear = ESPUser.current_schoolyear()
        gradYear = curYear + (12 - testGrade)
        self.client.get("/manage/userview?username=student&graduation_year="+str(gradYear))
        self.assertTrue(studentUser.getGrade() == testGrade, "Grades don't match: %s %s" % (studentUser.getGrade(), testGrade))

        # Clean up
        if (c1):
            adminUser.delete()
        if (c2):
            studentUser.delete()
Ejemplo n.º 2
0
    def testGradeChange(self):
        # Create the admin user
        adminUser, c1 = ESPUser.objects.get_or_create(username='******')
        adminUser.set_password('password')
        make_user_admin(adminUser)
        # Create the student user
        studentUser, c2 = ESPUser.objects.get_or_create(username='******')
        # Make it a student
        role_bit, created = UserBit.objects.get_or_create(user=studentUser, qsc=GetNode('Q'), verb=GetNode('V/Flags/UserRole/Student'), recursive=False)
        # Give it a starting grade
        student_studentinfo = StudentInfo(user=studentUser, graduation_year=ESPUser.YOGFromGrade(9))
        student_studentinfo.save()
        student_regprofile = RegistrationProfile(user=studentUser, student_info=student_studentinfo, most_recent_profile=True)
        student_regprofile.save()
        # Check that the grade starts at 9
        self.failUnless(studentUser.getGrade() == 9)

        # Login the admin
        self.failUnless(self.client.login(username="******", password="******"))

        testGrade = 11
        curYear = ESPUser.current_schoolyear()
        gradYear = curYear + (12 - testGrade)
        self.client.get("/manage/userview?username=student&graduation_year="+str(gradYear))
        self.failUnless(studentUser.getGrade() == testGrade, "Grades don't match: %s %s" % (studentUser.getGrade(), testGrade))

        # Clean up
        if (c1):
            adminUser.delete()
        if (c2):
            studentUser.delete()
Ejemplo n.º 3
0
def userview(request):
    """ Render a template displaying all the information about the specified user """
    try:
        user = ESPUser.objects.get(username=request.GET['username'])
    except:
        raise ESPError(False), "Sorry, can't find anyone with that username."

    teacherbio = TeacherBio.getLastBio(user)
    if not teacherbio.picture:
        teacherbio.picture = 'images/not-available.jpg'
    
    from esp.users.forms.user_profile import StudentInfoForm
    
    if 'graduation_year' in request.GET:
        student_info = user.getLastProfile().student_info
        student_info.graduation_year = int(request.GET['graduation_year'])
        student_info.save()
    
    change_grade_form = StudentInfoForm(user=user)
    if 'disabled' in change_grade_form.fields['graduation_year'].widget.attrs:
        del change_grade_form.fields['graduation_year'].widget.attrs['disabled']
    change_grade_form.fields['graduation_year'].initial = ESPUser.YOGFromGrade(user.getGrade())
    change_grade_form.fields['graduation_year'].choices = filter(lambda choice: bool(choice[0]), change_grade_form.fields['graduation_year'].choices)
    
    context = {
        'user': user,
        'taught_classes' : user.getTaughtClasses().order_by('parent_program', 'id'),
        'enrolled_classes' : user.getEnrolledSections().order_by('parent_class__parent_program', 'id'),
        'taken_classes' : user.getSections().order_by('parent_class__parent_program', 'id'),
        'teacherbio': teacherbio,
        'domain': settings.SITE_INFO[1],
        'change_grade_form': change_grade_form,
    }
    return render_to_response("users/userview.html", request, context )
Ejemplo n.º 4
0
    def __init__(self, user=None, *args, **kwargs):
        from esp.users.models import ESPUser
        super(StudentInfoForm, self).__init__(user, *args, **kwargs)

        self.allow_change_grade_level = Tag.getTag('allow_change_grade_level')

        ## All of these Tags may someday want to be made per-program somehow.
        ## We don't know the current program right now, though...
        show_studentrep_application = Tag.getTag('show_studentrep_application')
        if not show_studentrep_application:
            ## Only enable the Student Rep form optionally.
            del self.fields['studentrep']
        if (not show_studentrep_application
            ) or show_studentrep_application == "no_expl":
            del self.fields['studentrep_expl']

        if not Tag.getTag('show_student_tshirt_size_options'):
            del self.fields['shirt_size']
            del self.fields['shirt_type']
        elif Tag.getTag('studentinfo_shirt_type_selection') == 'False':
            del self.fields['shirt_type']

        if not Tag.getTag('show_student_vegetarianism_options'):
            del self.fields['food_preference']

        #   Allow grade range of students to be customized by a Tag (default is 7-12)
        self.fields['graduation_year'].choices = [('', '')] + [(str(
            ESPUser.YOGFromGrade(x)), str(x)) for x in ESPUser.grade_options()]

        #   Add user's current grade if it is out of range and they have already filled out the profile.
        if user and user.registrationprofile_set.count() > 0:
            user_grade = user.getGrade()
            grade_tup = (str(ESPUser.YOGFromGrade(user_grade)),
                         str(user_grade))
            if grade_tup not in self.fields['graduation_year'].choices:
                self.fields['graduation_year'].choices.insert(0, grade_tup)

        #   Honor several possible Tags for customizing the fields that are displayed.
        if Tag.getTag('show_student_graduation_years_not_grades'):
            current_grad_year = self.ESPUser.current_schoolyear()
            new_choices = []
            for x in self.fields['graduation_year'].choices:
                if len(x[0]) > 0:
                    new_choices.append(
                        (str(x[0]), "%s (%sth grade)" % (x[0], x[1])))
                else:
                    new_choices.append(x)
            self.fields['graduation_year'].choices = new_choices

        if not Tag.getBooleanTag('student_profile_gender_field'):
            del self.fields['gender']

        if not Tag.getTag('ask_student_about_transportation_to_program'):
            del self.fields['transportation']

        if not Tag.getTag('allow_change_grade_level'):
            if 'initial' in kwargs:
                initial_data = kwargs['initial']

                # Disable the age and grade fields if they already exist.
                if 'graduation_year' in initial_data and 'dob' in initial_data:
                    self.fields['graduation_year'].widget.attrs[
                        'disabled'] = "true"
                    self.fields['graduation_year'].required = False
                    self.fields['dob'].widget.attrs['disabled'] = "true"
                    self.fields['dob'].required = False

        #   Add field asking about medical needs if directed by the Tag
        if Tag.getTag('student_medical_needs'):
            self.fields['medical_needs'].widget = forms.Textarea(attrs={
                'cols': 40,
                'rows': 3
            })
        else:
            del self.fields['medical_needs']

        #   The unmatched_school field is for students to opt out of selecting a K12School.
        #   If we don't require a K12School to be selected, don't bother showing that field.
        if not Tag.getBooleanTag('require_school_field', default=False):
            del self.fields['unmatched_school']

        self._user = user
Ejemplo n.º 5
0
class StudentInfoForm(FormUnrestrictedOtherUser):
    """ Extra student-specific information """
    from esp.users.models import ESPUser
    from esp.users.models import shirt_sizes, shirt_types, food_choices

    gender = forms.ChoiceField(choices=[('', ''), ('M', 'Male'),
                                        ('F', 'Female')],
                               required=False)
    graduation_year = forms.ChoiceField(choices=[('', '')] +
                                        [(str(ESPUser.YOGFromGrade(x)), str(x))
                                         for x in range(7, 13)])
    k12school = AjaxForeignKeyNewformField(key_type=K12School,
                                           field_name='k12school',
                                           shadow_field_name='school',
                                           required=False,
                                           label='School')
    unmatched_school = forms.BooleanField(required=False)
    school = forms.CharField(max_length=128, required=False)
    dob = forms.DateField(widget=SplitDateWidget(min_year=datetime.now().year -
                                                 20))
    studentrep = forms.BooleanField(required=False)
    studentrep_expl = forms.CharField(required=False)
    heard_about = DropdownOtherField(
        required=False,
        widget=DropdownOtherWidget(
            choices=zip(HeardAboutESPChoices, HeardAboutESPChoices
                        )))  #forms.CharField(required=False)
    shirt_size = forms.ChoiceField(choices=([('', '')] + list(shirt_sizes)),
                                   required=False)
    shirt_type = forms.ChoiceField(choices=([('', '')] + list(shirt_types)),
                                   required=False)
    food_preference = forms.ChoiceField(choices=([('', '')] +
                                                 list(food_choices)),
                                        required=False)

    medical_needs = forms.CharField(required=False)

    transportation = DropdownOtherField(
        required=False,
        widget=DropdownOtherWidget(
            choices=zip(HowToGetToProgram, HowToGetToProgram)))

    studentrep_error = True

    def __init__(self, user=None, *args, **kwargs):
        from esp.users.models import ESPUser
        super(StudentInfoForm, self).__init__(user, *args, **kwargs)

        self.allow_change_grade_level = Tag.getTag('allow_change_grade_level')

        ## All of these Tags may someday want to be made per-program somehow.
        ## We don't know the current program right now, though...
        show_studentrep_application = Tag.getTag('show_studentrep_application')
        if not show_studentrep_application:
            ## Only enable the Student Rep form optionally.
            del self.fields['studentrep']
        if (not show_studentrep_application
            ) or show_studentrep_application == "no_expl":
            del self.fields['studentrep_expl']

        if not Tag.getTag('show_student_tshirt_size_options'):
            del self.fields['shirt_size']
            del self.fields['shirt_type']
        elif Tag.getTag('studentinfo_shirt_type_selection') == 'False':
            del self.fields['shirt_type']

        if not Tag.getTag('show_student_vegetarianism_options'):
            del self.fields['food_preference']

        #   Allow grade range of students to be customized by a Tag (default is 7-12)
        self.fields['graduation_year'].choices = [('', '')] + [(str(
            ESPUser.YOGFromGrade(x)), str(x)) for x in ESPUser.grade_options()]

        #   Add user's current grade if it is out of range and they have already filled out the profile.
        if user and user.registrationprofile_set.count() > 0:
            user_grade = user.getGrade()
            grade_tup = (str(ESPUser.YOGFromGrade(user_grade)),
                         str(user_grade))
            if grade_tup not in self.fields['graduation_year'].choices:
                self.fields['graduation_year'].choices.insert(0, grade_tup)

        #   Honor several possible Tags for customizing the fields that are displayed.
        if Tag.getTag('show_student_graduation_years_not_grades'):
            current_grad_year = self.ESPUser.current_schoolyear()
            new_choices = []
            for x in self.fields['graduation_year'].choices:
                if len(x[0]) > 0:
                    new_choices.append(
                        (str(x[0]), "%s (%sth grade)" % (x[0], x[1])))
                else:
                    new_choices.append(x)
            self.fields['graduation_year'].choices = new_choices

        if not Tag.getBooleanTag('student_profile_gender_field'):
            del self.fields['gender']

        if not Tag.getTag('ask_student_about_transportation_to_program'):
            del self.fields['transportation']

        if not Tag.getTag('allow_change_grade_level'):
            if 'initial' in kwargs:
                initial_data = kwargs['initial']

                # Disable the age and grade fields if they already exist.
                if 'graduation_year' in initial_data and 'dob' in initial_data:
                    self.fields['graduation_year'].widget.attrs[
                        'disabled'] = "true"
                    self.fields['graduation_year'].required = False
                    self.fields['dob'].widget.attrs['disabled'] = "true"
                    self.fields['dob'].required = False

        #   Add field asking about medical needs if directed by the Tag
        if Tag.getTag('student_medical_needs'):
            self.fields['medical_needs'].widget = forms.Textarea(attrs={
                'cols': 40,
                'rows': 3
            })
        else:
            del self.fields['medical_needs']

        #   The unmatched_school field is for students to opt out of selecting a K12School.
        #   If we don't require a K12School to be selected, don't bother showing that field.
        if not Tag.getBooleanTag('require_school_field', default=False):
            del self.fields['unmatched_school']

        self._user = user

    def repress_studentrep_expl_error(self):
        self.studentrep_error = False

    def clean_graduation_year(self):
        gy = self.cleaned_data['graduation_year'].strip()
        try:
            gy = str(abs(int(gy)))
        except:
            if gy != 'G':
                gy = 'N/A'
        return gy

    def clean_heard_about(self):
        if self.cleaned_data['heard_about'] == 'Other...:':
            raise forms.ValidationError(
                "If 'Other...', please provide details")
        return self.cleaned_data['heard_about']

    def clean_transportation(self):
        if self.cleaned_data['transportation'] == 'Other...:':
            raise forms.ValidationError(
                "If 'Other...', please provide details")
        return self.cleaned_data['transportation']

    def clean(self):
        super(StudentInfoForm, self).clean()

        cleaned_data = self.cleaned_data

        show_studentrep_application = Tag.getTag('show_studentrep_application')
        if show_studentrep_application and show_studentrep_application != "no_expl":
            expl = self.cleaned_data['studentrep_expl'].strip()
            if self.studentrep_error and self.cleaned_data[
                    'studentrep'] and expl == '':
                raise forms.ValidationError(
                    "Please enter an explanation if you would like to become a student rep."
                )

        if not Tag.getTag('allow_change_grade_level'):
            user = self._user

            orig_prof = RegistrationProfile.getLastProfile(user)

            # If graduation year and dob were disabled, get old data.
            if (orig_prof.id is not None) and (orig_prof.student_info
                                               is not None):

                if not 'graduation_year' in cleaned_data:
                    # Get rid of the error saying this is missing
                    del self.errors['graduation_year']

                if not 'dob' in cleaned_data:
                    del self.errors['dob']

                # Always use the old birthdate if it exists, so that people can't
                # use something like Firebug to change their age/grade
                cleaned_data[
                    'graduation_year'] = orig_prof.student_info.graduation_year
                cleaned_data['dob'] = orig_prof.student_info.dob

        if Tag.getBooleanTag('require_school_field'):
            if not cleaned_data['k12school'] and not cleaned_data[
                    'unmatched_school']:
                raise forms.ValidationError(
                    "Please select your school from the dropdown list that appears as you type its name.  You will need to click on an entry to select it.  If you cannot find your school, please type in its full name and check the box below; we will do our best to add it to our database."
                )

        return cleaned_data
Ejemplo n.º 6
0
    def onsite_create(self, request, tl, one, two, module, extra, prog):
        if request.method == 'POST':
            form = OnSiteRegForm(request.POST)

            if form.is_valid():
                new_data = form.cleaned_data
                username = ESPUser.get_unused_username(new_data['first_name'],
                                                       new_data['last_name'])
                new_user = ESPUser.objects.create_user(
                    username=username,
                    first_name=new_data['first_name'],
                    last_name=new_data['last_name'],
                    email=new_data['email'])

                self.student = new_user

                regProf = RegistrationProfile.getLastForProgram(
                    new_user, self.program)
                contact_user = ContactInfo(first_name=new_user.first_name,
                                           last_name=new_user.last_name,
                                           e_mail=new_user.email,
                                           user=new_user)
                contact_user.save()
                regProf.contact_user = contact_user

                student_info = StudentInfo(
                    user=new_user,
                    graduation_year=ESPUser.YOGFromGrade(
                        new_data['grade'],
                        ESPUser.program_schoolyear(self.program)))

                try:
                    if isinstance(new_data['k12school'], K12School):
                        student_info.k12school = new_data['k12school']
                    else:
                        if isinstance(new_data['k12school'], int):
                            student_info.k12school = K12School.objects.get(
                                id=int(new_data['k12school']))
                        else:
                            student_info.k12school = K12School.objects.filter(
                                name__icontains=new_data['k12school'])[0]
                except:
                    student_info.k12school = None
                student_info.school = new_data[
                    'school'] if not student_info.k12school else student_info.k12school.name

                student_info.save()
                regProf.student_info = student_info

                regProf.save()

                if new_data['paid']:
                    self.createBit('paid')
                    self.updatePaid(True)
                else:
                    self.updatePaid(False)

                self.createBit('Attended')

                if new_data['medical']:
                    self.createBit('Med')

                if new_data['liability']:
                    self.createBit('Liab')

                self.createBit('OnSite')

                new_user.groups.add(Group.objects.get(name="Student"))

                new_user.recoverPassword()

                return render_to_response(
                    self.baseDir() + 'reg_success.html', request, {
                        'student':
                        new_user,
                        'retUrl':
                        '/onsite/%s/classchange_grid?student_id=%s' %
                        (self.program.getUrlBase(), new_user.id)
                    })

        else:
            form = OnSiteRegForm()

        return render_to_response(self.baseDir() + 'reg_info.html', request,
                                  {'form': form})
Ejemplo n.º 7
0
    def __init__(self, user=None, *args, **kwargs):
        from esp.users.models import ESPUser
        super(StudentInfoForm, self).__init__(user, *args, **kwargs)

        self.allow_change_grade_level = Tag.getTag('allow_change_grade_level')

        ## All of these Tags may someday want to be made per-program somehow.
        ## We don't know the current program right now, though...
        show_studentrep_application = Tag.getTag('show_studentrep_application')
        if not show_studentrep_application:
            ## Only enable the Student Rep form optionally.
            del self.fields['studentrep']
        if (not show_studentrep_application) or show_studentrep_application == "no_expl":
            del self.fields['studentrep_expl']

        if not Tag.getTag('show_student_tshirt_size_options'):
            del self.fields['shirt_size']
            del self.fields['shirt_type']

        if not Tag.getTag('show_student_vegetarianism_options'):
            del self.fields['food_preference']

        #   Allow grade range of students to be customized by a Tag (default is 7-12)
        custom_grade_options = Tag.getTag('student_grade_options')
        if custom_grade_options:
            custom_grade_options = json.loads(custom_grade_options)
            self.fields['graduation_year'].choices = [('','')]+[(str(ESPUser.YOGFromGrade(x)), str(x)) for x in custom_grade_options]
            
        #   Add user's current grade if it is out of range and they have already filled out the profile.
        if user and user.registrationprofile_set.count() > 0:
            user_grade = user.getGrade()
            grade_tup = (str(ESPUser.YOGFromGrade(user_grade)), str(user_grade))
            if grade_tup not in self.fields['graduation_year'].choices:
                self.fields['graduation_year'].choices.insert(0, grade_tup)

        if Tag.getTag('show_student_graduation_years_not_grades'):            
            current_grad_year = self.ESPUser.current_schoolyear()
            new_choices = []
            for x in self.fields['graduation_year'].choices:
                if len(x[0]) > 0:
                    new_choices.append((str(x[0]), "%s (%sth grade)" % (x[0], x[1])))
                else:
                    new_choices.append(x)
            self.fields['graduation_year'].choices = new_choices

        if not Tag.getTag('ask_student_about_post_hs_plans'):
            del self.fields['post_hs']

        if not Tag.getTag('ask_student_about_transportation_to_program'):
            del self.fields['transportation']

        if not Tag.getTag('allow_change_grade_level'):
            if kwargs.has_key('initial'):
                initial_data = kwargs['initial']

                # Disable the age and grade fields if they already exist.
                if initial_data.has_key('graduation_year') and initial_data.has_key('dob'):
                    self.fields['graduation_year'].widget.attrs['disabled'] = "true"
                    self.fields['graduation_year'].required = False
                    self.fields['dob'].widget.attrs['disabled'] = "true"
                    self.fields['dob'].required = False
                    

        #   Add schoolsystem fields if directed by the Tag
        if Tag.getTag('schoolsystem'):
            sysinfo = json.loads(str(Tag.getTag('schoolsystem')))
            for key in ['label', 'required', 'help_text']:
                if key in sysinfo:
                    setattr(self.fields['schoolsystem_id'], key, sysinfo[key])
            if 'use_checkbox' in sysinfo and sysinfo['use_checkbox']:
                if 'label' in sysinfo:
                    self.fields['schoolsystem_optout'].help_text = '<span style="font-size: 0.8em;">Check this box if you don\'t have a %s</span>' % sysinfo['label']
                else:
                    self.fields['schoolsystem_optout'].help_text = '<span style="font-size: 0.8em;">Check this box if you don\'t have an ID number</span>'
            else:
                del self.fields['schoolsystem_optout']
        else:
            del self.fields['schoolsystem_id']
            del self.fields['schoolsystem_optout']

        #   Add field asking about medical needs if directed by the Tag
        if Tag.getTag('student_medical_needs'):
            self.fields['medical_needs'].widget = forms.Textarea(attrs={'cols': 40, 'rows': 3})
        else:
            del self.fields['medical_needs']
            
        #   Make the schoolsystem_id field non-required if schoolsystem_optout is checked
        if self.data and 'schoolsystem_optout' in self.data and 'schoolsystem_id' in self.data:
            self.data = self.data.copy()
            if self.data['schoolsystem_optout']:
                self.fields['schoolsystem_id'].required = False
                self.data['schoolsystem_id'] = ''
                
        #   The unmatched_school field is for students to opt out of selecting a K12School.
        #   If we don't require a K12School to be selected, don't bother showing that field.
        if not Tag.getTag('require_school_field', default=False):
            del self.fields['unmatched_school']
        
        self._user = user
Ejemplo n.º 8
0
class StudentInfoForm(FormUnrestrictedOtherUser):
    """ Extra student-specific information """
    from esp.users.models import ESPUser
    from esp.users.models import shirt_sizes, shirt_types, food_choices

    graduation_year = forms.ChoiceField(choices=[('', '')]+[(str(ESPUser.YOGFromGrade(x)), str(x)) for x in range(7,13)])
    k12school = AjaxForeignKeyNewformField(key_type=K12School, field_name='k12school', shadow_field_name='school', required=False, label='School')
    unmatched_school = forms.BooleanField(required=False)
    school = forms.CharField(max_length=128, required=False)
    dob = forms.DateField(widget=SplitDateWidget(min_year=datetime.now().year-20))
    studentrep = forms.BooleanField(required=False)
    studentrep_expl = forms.CharField(required=False)
    heard_about = DropdownOtherField(required=False, widget=DropdownOtherWidget(choices=zip(HeardAboutESPChoices, HeardAboutESPChoices)))#forms.CharField(required=False)
    shirt_size = forms.ChoiceField(choices=([('','')]+list(shirt_sizes)), required=False)
    shirt_type = forms.ChoiceField(choices=([('','')]+list(shirt_types)), required=False)
    food_preference = forms.ChoiceField(choices=([('','')]+list(food_choices)), required=False)

    medical_needs = forms.CharField(required=False)

    post_hs = DropdownOtherField(required=False, widget=DropdownOtherWidget(choices=zip(WhatToDoAfterHS, WhatToDoAfterHS)))
    transportation = DropdownOtherField(required=False, widget=DropdownOtherWidget(choices=zip(HowToGetToProgram, HowToGetToProgram)))
    schoolsystem_id = forms.CharField(max_length=32, required=False)
    schoolsystem_optout = forms.BooleanField(required=False)

    studentrep_error = True

    def __init__(self, user=None, *args, **kwargs):
        from esp.users.models import ESPUser
        super(StudentInfoForm, self).__init__(user, *args, **kwargs)

        self.allow_change_grade_level = Tag.getTag('allow_change_grade_level')

        ## All of these Tags may someday want to be made per-program somehow.
        ## We don't know the current program right now, though...
        show_studentrep_application = Tag.getTag('show_studentrep_application')
        if not show_studentrep_application:
            ## Only enable the Student Rep form optionally.
            del self.fields['studentrep']
        if (not show_studentrep_application) or show_studentrep_application == "no_expl":
            del self.fields['studentrep_expl']

        if not Tag.getTag('show_student_tshirt_size_options'):
            del self.fields['shirt_size']
            del self.fields['shirt_type']

        if not Tag.getTag('show_student_vegetarianism_options'):
            del self.fields['food_preference']

        #   Allow grade range of students to be customized by a Tag (default is 7-12)
        custom_grade_options = Tag.getTag('student_grade_options')
        if custom_grade_options:
            custom_grade_options = json.loads(custom_grade_options)
            self.fields['graduation_year'].choices = [('','')]+[(str(ESPUser.YOGFromGrade(x)), str(x)) for x in custom_grade_options]
            
        #   Add user's current grade if it is out of range and they have already filled out the profile.
        if user and user.registrationprofile_set.count() > 0:
            user_grade = user.getGrade()
            grade_tup = (str(ESPUser.YOGFromGrade(user_grade)), str(user_grade))
            if grade_tup not in self.fields['graduation_year'].choices:
                self.fields['graduation_year'].choices.insert(0, grade_tup)

        if Tag.getTag('show_student_graduation_years_not_grades'):            
            current_grad_year = self.ESPUser.current_schoolyear()
            new_choices = []
            for x in self.fields['graduation_year'].choices:
                if len(x[0]) > 0:
                    new_choices.append((str(x[0]), "%s (%sth grade)" % (x[0], x[1])))
                else:
                    new_choices.append(x)
            self.fields['graduation_year'].choices = new_choices

        if not Tag.getTag('ask_student_about_post_hs_plans'):
            del self.fields['post_hs']

        if not Tag.getTag('ask_student_about_transportation_to_program'):
            del self.fields['transportation']

        if not Tag.getTag('allow_change_grade_level'):
            if kwargs.has_key('initial'):
                initial_data = kwargs['initial']

                # Disable the age and grade fields if they already exist.
                if initial_data.has_key('graduation_year') and initial_data.has_key('dob'):
                    self.fields['graduation_year'].widget.attrs['disabled'] = "true"
                    self.fields['graduation_year'].required = False
                    self.fields['dob'].widget.attrs['disabled'] = "true"
                    self.fields['dob'].required = False
                    

        #   Add schoolsystem fields if directed by the Tag
        if Tag.getTag('schoolsystem'):
            sysinfo = json.loads(str(Tag.getTag('schoolsystem')))
            for key in ['label', 'required', 'help_text']:
                if key in sysinfo:
                    setattr(self.fields['schoolsystem_id'], key, sysinfo[key])
            if 'use_checkbox' in sysinfo and sysinfo['use_checkbox']:
                if 'label' in sysinfo:
                    self.fields['schoolsystem_optout'].help_text = '<span style="font-size: 0.8em;">Check this box if you don\'t have a %s</span>' % sysinfo['label']
                else:
                    self.fields['schoolsystem_optout'].help_text = '<span style="font-size: 0.8em;">Check this box if you don\'t have an ID number</span>'
            else:
                del self.fields['schoolsystem_optout']
        else:
            del self.fields['schoolsystem_id']
            del self.fields['schoolsystem_optout']

        #   Add field asking about medical needs if directed by the Tag
        if Tag.getTag('student_medical_needs'):
            self.fields['medical_needs'].widget = forms.Textarea(attrs={'cols': 40, 'rows': 3})
        else:
            del self.fields['medical_needs']
            
        #   Make the schoolsystem_id field non-required if schoolsystem_optout is checked
        if self.data and 'schoolsystem_optout' in self.data and 'schoolsystem_id' in self.data:
            self.data = self.data.copy()
            if self.data['schoolsystem_optout']:
                self.fields['schoolsystem_id'].required = False
                self.data['schoolsystem_id'] = ''
                
        #   The unmatched_school field is for students to opt out of selecting a K12School.
        #   If we don't require a K12School to be selected, don't bother showing that field.
        if not Tag.getTag('require_school_field', default=False):
            del self.fields['unmatched_school']
        
        self._user = user

    def repress_studentrep_expl_error(self):
        self.studentrep_error = False

    def clean_graduation_year(self):
        gy = self.cleaned_data['graduation_year'].strip()
        try:
            gy = str(abs(int(gy)))
        except:
            if gy != 'G':
                gy = 'N/A'
        return gy

    def clean_heard_about(self):
        if self.cleaned_data['heard_about'] == 'Other...:':
            raise forms.ValidationError("If 'Other...', please provide details")
        return self.cleaned_data['heard_about']

    def clean_post_hs(self):
        if self.cleaned_data['post_hs'] == 'Other...:':
            raise forms.ValidationError("If 'Other...', please provide details")
        return self.cleaned_data['post_hs']

    def clean_transportation(self):
        if self.cleaned_data['transportation'] == 'Other...:':
            raise forms.ValidationError("If 'Other...', please provide details")
        return self.cleaned_data['transportation']

    def clean_schoolsystem_id(self):
        if Tag.getTag('schoolsystem'):
            sysinfo = json.loads(str(Tag.getTag('schoolsystem')))
            if 'num_digits' in sysinfo:
                input_str = self.cleaned_data['schoolsystem_id'].strip()
                if len(input_str) > 0:
                    if len(input_str) != int(sysinfo['num_digits']) or not input_str.isdigit():
                        raise forms.ValidationError("Please enter a unique %d-digit number." % int(sysinfo['num_digits']))
            if 'check_unique' in sysinfo and sysinfo['check_unique']:
                if StudentInfo.objects.filter(schoolsystem_id=input_str).exclude(user=self._user).exists():
                    if len(input_str.strip('0')) != 0:
                        raise forms.ValidationError("Someone else has already entered CPS ID number '%s'." % input_str)
        return self.cleaned_data['schoolsystem_id']

    def clean(self):
        super(StudentInfoForm, self).clean()

        cleaned_data = self.cleaned_data

        show_studentrep_application = Tag.getTag('show_studentrep_application')
        if show_studentrep_application and show_studentrep_application != "no_expl":
            expl = self.cleaned_data['studentrep_expl'].strip()
            if self.studentrep_error and self.cleaned_data['studentrep'] and expl == '':
                raise forms.ValidationError("Please enter an explanation if you would like to become a student rep.")

        if not Tag.getTag('allow_change_grade_level'):
            user = self._user

            orig_prof = RegistrationProfile.getLastProfile(user)

            # If graduation year and dob were disabled, get old data.
            if (orig_prof.id is not None) and (orig_prof.student_info is not None):

                if not cleaned_data.has_key('graduation_year'):
                    # Get rid of the error saying this is missing
                    del self.errors['graduation_year']

                if not cleaned_data.has_key('dob'):
                    del self.errors['dob']

                # Always use the old birthdate if it exists, so that people can't
                # use something like Firebug to change their age/grade
                cleaned_data['graduation_year'] = orig_prof.student_info.graduation_year
                cleaned_data['dob'] = orig_prof.student_info.dob

        
        if Tag.getTag('require_school_field'):
            if not cleaned_data['k12school'] and not cleaned_data['unmatched_school']:
                raise forms.ValidationError("Please select your school from the dropdown list that appears as you type its name.  You will need to click on an entry to select it.  If you cannot find your school, please type in its full name and check the box below; we will do our best to add it to our database.")

        return cleaned_data
Ejemplo n.º 9
0
    def stats(prog):
        # Create a dictionary to assemble the output
        dictOut = {"stats": []}

        classes = prog.classes().select_related()
        vitals = {'id': 'vitals'}

        class_num_list = []
        class_num_list.append(
            ("Total # of Classes", classes.distinct().count()))
        class_num_list.append(
            ("Total # of Class Sections",
             prog.sections().select_related().distinct().count()))
        class_num_list.append(
            ("Total # of Lunch Classes",
             classes.filter(category__category="Lunch").filter(
                 status=10).distinct().count()))
        class_num_list.append(
            ("Total # of Classes <span style='color: #00C;'>Unreviewed</span>",
             classes.filter(status=0).distinct().count()))
        class_num_list.append(
            ("Total # of Classes <span style='color: #0C0;'>Accepted</span>",
             classes.filter(status=10).distinct().count()))
        class_num_list.append(
            ("Total # of Classes <span style='color: #C00;'>Rejected</span>",
             classes.filter(status=-10).distinct().count()))
        class_num_list.append(
            ("Total # of Classes <span style='color: #990;'>Cancelled</span>",
             classes.filter(status=-20).distinct().count()))
        for ft in ClassFlagType.get_flag_types(prog):
            class_num_list.append(
                ('Total # of Classes with the "%s" flag' % ft.name,
                 classes.filter(flags__flag_type=ft).distinct().count()))
        vitals['classnum'] = class_num_list

        #   Display pretty labels for teacher and student numbers
        teacher_labels_dict = {}
        for module in prog.getModules():
            teacher_labels_dict.update(module.teacherDesc())
        vitals['teachernum'] = []

        ## Ew, queries in a for loop...
        ## Not much to be done about it, though;
        ## the loop is iterating over a list of independent queries and running each.
        teachers = prog.teachers()
        for key in teachers.keys():
            if key in teacher_labels_dict:
                vitals['teachernum'].append((
                    teacher_labels_dict[key],  ## Unfortunately,
                    teachers[key].filter(is_active=True).distinct().count()))
            else:
                vitals['teachernum'].append(
                    (key,
                     teachers[key].filter(is_active=True).distinct().count()))

        student_labels_dict = {}
        for module in prog.getModules():
            student_labels_dict.update(module.studentDesc())
        vitals['studentnum'] = []

        ## Ew, another set of queries in a for loop...
        ## Same justification, though.
        students = prog.students()
        for key in students.keys():
            if key in student_labels_dict:
                vitals['studentnum'].append(
                    (student_labels_dict[key],
                     students[key].filter(is_active=True).distinct().count()))
            else:
                vitals['studentnum'].append(
                    (key,
                     students[key].filter(is_active=True).distinct().count()))

        timeslots = prog.getTimeSlots()
        vitals['timeslots'] = []

        shours = 0.0
        chours = 0.0
        crhours = 0.0
        ## Write this as a 'for' loop because PostgreSQL can't do it in
        ## one go without a subquery or duplicated logic, and Django
        ## doesn't have enough power to expose either approach directly.
        ## At least there aren't any queries in the for loop...
        ## (In MySQL, this could I believe be done with a minimally-painful extra() clause.)
        ## Also, since we're iterating over a big data set, use .values()
        ## minimize the number of objects that we're creating.
        ## One dict and two Decimals per row, as opposed to
        ## an Object per field and all kinds of stuff...
        for cls in prog.classes().exclude(category__category='Lunch').annotate(
                num_sections=Count('sections'),
                subject_duration=Sum('sections__duration'),
                subject_students=Sum('sections__enrolled_students')).values(
                    'num_sections', 'subject_duration', 'subject_students',
                    'class_size_max'):
            if cls['subject_duration']:
                chours += float(cls['subject_duration'])
                shours += float(cls['subject_duration']) * (float(
                    cls['class_size_max']) if cls['class_size_max'] else 0)
                crhours += float(cls['subject_duration']) * float(
                    cls['subject_students']) / float(cls['num_sections'])
        vitals["hournum"] = []
        vitals["hournum"].append(("Total # of Class-Hours", chours))
        vitals["hournum"].append(
            ("Total # of Class-Student-Hours (capacity)", shours))
        vitals["hournum"].append(
            ("Total # of Class-Student-Hours (registered)", crhours))

        ## Prefetch enough data that get_meeting_times() and num_students() don't have to hit the db
        curclasses = ClassSection.prefetch_catalog_data(
            ClassSection.objects.filter(
                parent_class__parent_program=prog).select_related(
                    'parent_class', 'parent_class__category'))

        ## Is it really faster to do this logic in Python?
        ## It'd be even faster to just write a raw SQL query to do it.
        ## But this is probably good enough.
        timeslot_dict = defaultdict(list)
        timeslot_set = set(timeslots)
        for section in curclasses:
            for timeslot in set.intersection(timeslot_set,
                                             section.get_meeting_times()):
                timeslot_dict[timeslot].append(section)

        for timeslot in timeslots:
            curTimeslot = {'slotname': timeslot.short_description}

            curTimeslot['classcount'] = len(timeslot_dict[timeslot])

            def student_count(clslist):
                lst = [0] + [
                    x.num_students()
                    for x in clslist if x.category.category != 'Lunch'
                ]
                return reduce(operator.add, lst)

            def student_max_count(clslist):
                lst = [0] + [
                    x.capacity
                    for x in clslist if x.category.category != 'Lunch'
                ]
                return reduce(operator.add, lst)

            curTimeslot['studentcount'] = {
                'count': student_count(timeslot_dict[timeslot]),
                'max_count': student_max_count(timeslot_dict[timeslot])
            }

            vitals['timeslots'].append(curTimeslot)

        dictOut["stats"].append(vitals)

        shirt_data = {
            "id": "shirtnum"
        }
        adminvitals_shirt = prog.getShirtInfo()
        shirt_data["sizes"] = adminvitals_shirt['shirt_sizes']
        shirt_data["types"] = adminvitals_shirt['shirt_types']
        shirt_data["data"] = adminvitals_shirt['shirts']
        dictOut["stats"].append(shirt_data)

        Q_categories = Q(program=prog)
        crmi = prog.classregmoduleinfo
        if crmi.open_class_registration:
            Q_categories |= Q(pk=prog.open_class_category.pk)
        #   Introduce a separate query to get valid categories, since the single query seemed to introduce duplicates
        program_categories = ClassCategories.objects.filter(
            Q_categories).distinct().values_list('id', flat=True)
        annotated_categories = ClassCategories.objects.filter(
            cls__parent_program=prog, cls__status__gte=0).annotate(
                num_subjects=Count('cls', distinct=True),
                num_sections=Count('cls__sections'),
                num_class_hours=Sum('cls__sections__duration')).order_by(
                    '-num_subjects').values('id', 'num_sections',
                                            'num_subjects', 'num_class_hours',
                                            'category').distinct()
        #   Convert Decimal values to float for serialization
        for i in range(len(annotated_categories)):
            annotated_categories[i]['num_class_hours'] = float(
                annotated_categories[i]['num_class_hours'])
        dictOut["stats"].append({
            "id":
            "categories",
            "data":
            filter(lambda x: x['id'] in program_categories,
                   annotated_categories)
        })

        ## Calculate the grade data:
        grades = [i for i in range(prog.grade_min, prog.grade_max + 1)]
        # We can't perfectly trust most_recent_profile, but it's good enough for stats
        students_grades = students['enrolled'].filter(
            registrationprofile__most_recent_profile=True)
        students_grades = students_grades.values_list(
            'registrationprofile__student_info__graduation_year')
        students_grades = students_grades.annotate(Count('id', distinct=True))
        grades_dict = {result[0]: result[1] for result in students_grades}
        grades_results = []
        for g in grades:
            year = ESPUser.YOGFromGrade(g, ESPUser.program_schoolyear(prog))
            grade_classes = classes.filter(status__gte=0,
                                           grade_min__lte=g,
                                           grade_max__gte=g)
            grade_sections = prog.sections().filter(
                status__gte=0, parent_class__in=grade_classes)
            grades_results.append({
                'grade':
                g,
                'num_subjects':
                grade_classes.count(),
                'num_sections':
                grade_sections.count(),
                'num_students':
                grades_dict[year] if year in grades_dict else 0
            })
        dictOut["stats"].append({"id": "grades", "data": grades_results})

        #   Add SplashInfo statistics if our program has them
        splashinfo_data = {}
        splashinfo_modules = filter(lambda x: isinstance(x, SplashInfoModule),
                                    prog.getModules('learn'))
        if len(splashinfo_modules) > 0:
            splashinfo_module = splashinfo_modules[0]
            tag_data = Tag.getProgramTag('splashinfo_choices', prog)
            if tag_data:
                splashinfo_choices = json.loads(tag_data)
            else:
                splashinfo_choices = {
                    'lunchsat': SplashInfoForm.default_choices,
                    'lunchsun': SplashInfoForm.default_choices
                }
            for key in splashinfo_choices:
                counts = {}
                for item in splashinfo_choices[key]:
                    filter_kwargs = {'program': prog}
                    filter_kwargs[key] = item[0]
                    counts[item[1]] = SplashInfo.objects.filter(
                        **filter_kwargs).distinct().count()
                splashinfo_data[key] = counts
            splashinfo_data['siblings'] = {
                'yes':
                SplashInfo.objects.filter(
                    program=prog, siblingdiscount=True).distinct().count(),
                'no':
                SplashInfo.objects.filter(program=prog).exclude(
                    siblingdiscount=True).distinct().count()
            }
            dictOut["stats"].append({
                "id": "splashinfo",
                "data": splashinfo_data
            })

        #   Add accounting stats
        pac = ProgramAccountingController(prog)
        (num_payments, total_payment) = pac.payments_summary()
        accounting_data = {
            'num_payments': num_payments,
            # We need to convert to a float in order for json to serialize it.
            # Since we're not doing any computation client-side with these
            # numbers, this doesn't cause accuracy issues.  If the
            # total_payment is None, just coerce it to zero for display
            # purposes.
            'total_payments': float(total_payment or 0),
        }
        dictOut["stats"].append({"id": "accounting", "data": accounting_data})

        return dictOut
Ejemplo n.º 10
0
    def query_from_criteria(self, user_type, criteria):
        """ Get the "base list" consisting of all the users of a specific type. """
        if user_type.lower() == 'any':
            Q_base = Q()
        else:
            if user_type not in ESPUser.getTypes():
                raise ESPUser(), 'user_type must be one of ' + str(
                    ESPUser.getTypes())
            Q_base = ESPUser.getAllOfType(user_type, True)

        Q_include = Q()
        Q_exclude = Q()
        """ Apply the specified criteria to filter the list of users. """
        if criteria.has_key('userid') and len(criteria['userid'].strip()) > 0:

            ##  Select users based on their IDs only
            userid = []
            for digit in criteria['userid'].split(','):
                try:
                    userid.append(int(digit))
                except:
                    raise ESPError(
                        False
                    ), 'User id invalid, please enter a number or comma-separated list of numbers.'

            if criteria.has_key('userid__not'):
                Q_exclude &= Q(id__in=userid)
            else:
                Q_include &= Q(id__in=userid)
            self.updated = True

        else:

            ##  Select users based on all other criteria that was entered
            for field in ['username', 'last_name', 'first_name', 'email']:
                if criteria.has_key(field) and len(
                        criteria[field].strip()) > 0:
                    #   Check that it's a valid regular expression
                    try:
                        rc = re.compile(criteria[field])
                    except:
                        raise ESPError(
                            False
                        ), 'Invalid search expression, please check your syntax: %s' % criteria[
                            field]
                    filter_dict = {'%s__iregex' % field: criteria[field]}
                    if criteria.has_key('%s__not' % field):
                        Q_exclude &= Q(**filter_dict)
                    else:
                        Q_include &= Q(**filter_dict)
                    self.updated = True

            if criteria.has_key('zipcode') and criteria.has_key('zipdistance') and \
                len(criteria['zipcode'].strip()) > 0 and len(criteria['zipdistance'].strip()) > 0:
                try:
                    zipc = ZipCode.objects.get(zip_code=criteria['zipcode'])
                except:
                    raise ESPError(
                        False
                    ), 'Zip code not found.  This may be because you didn\'t enter a valid US zipcode.  Tried: "%s"' % criteria[
                        'zipcode']
                zipcodes = zipc.close_zipcodes(criteria['zipdistance'])
                # Excludes zipcodes within a certain radius, giving an annulus; can fail to exclude people who used to live outside the radius.
                # This may have something to do with the Q_include line below taking more than just the most recent profile. -ageng, 2008-01-15
                if criteria.has_key('zipdistance_exclude') and len(
                        criteria['zipdistance_exclude'].strip()) > 0:
                    zipcodes_exclude = zipc.close_zipcodes(
                        criteria['zipdistance_exclude'])
                    zipcodes = [
                        zipcode for zipcode in zipcodes
                        if zipcode not in zipcodes_exclude
                    ]
                if len(zipcodes) > 0:
                    Q_include &= Q(
                        registrationprofile__contact_user__address_zip__in=
                        zipcodes,
                        registrationprofile__most_recent_profile=True)
                    self.updated = True

            if criteria.has_key('states') and len(
                    criteria['states'].strip()) > 0:
                state_codes = criteria['states'].strip().upper().split(',')
                if criteria.has_key('states__not'):
                    Q_exclude &= Q(
                        registrationprofile__contact_user__address_state__in=
                        state_codes,
                        registrationprofile__most_recent_profile=True)
                else:
                    Q_include &= Q(
                        registrationprofile__contact_user__address_state__in=
                        state_codes,
                        registrationprofile__most_recent_profile=True)
                self.updated = True

            if criteria.has_key('grade_min'):
                yog = ESPUser.YOGFromGrade(criteria['grade_min'])
                if yog != 0:
                    Q_include &= Q(
                        registrationprofile__student_info__graduation_year__lte
                        =yog,
                        registrationprofile__most_recent_profile=True)
                    self.updated = True

            if criteria.has_key('grade_max'):
                yog = ESPUser.YOGFromGrade(criteria['grade_max'])
                if yog != 0:
                    Q_include &= Q(
                        registrationprofile__student_info__graduation_year__gte
                        =yog,
                        registrationprofile__most_recent_profile=True)
                    self.updated = True

            if criteria.has_key('school'):
                school = criteria['school']
                if school:
                    Q_include &= (
                        Q(studentinfo__school__icontains=school)
                        | Q(studentinfo__k12school__name__icontains=school))
                    self.updated = True

            #   Filter by graduation years if specifically looking for teachers.
            possible_gradyears = range(1920, 2020)
            if criteria.has_key('gradyear_min') and len(
                    criteria['gradyear_min'].strip()) > 0:
                try:
                    gradyear_min = int(criteria['gradyear_min'])
                except:
                    raise ESPError(
                        False
                    ), 'Please enter a 4-digit integer for graduation year limits.'
                possible_gradyears = filter(lambda x: x >= gradyear_min,
                                            possible_gradyears)
            if criteria.has_key('gradyear_max') and len(
                    criteria['gradyear_min'].strip()) > 0:
                try:
                    gradyear_max = int(criteria['gradyear_max'])
                except:
                    raise ESPError(
                        False
                    ), 'Please enter a 4-digit integer for graduation year limits.'
                possible_gradyears = filter(lambda x: x <= gradyear_max,
                                            possible_gradyears)
            if criteria.get('gradyear_min', None) or criteria.get(
                    'gradyear_max', None):
                Q_include &= Q(
                    registrationprofile__teacher_info__graduation_year__in=map(
                        str, possible_gradyears),
                    registrationprofile__most_recent_profile=True)
                self.updated = True

        return Q_base & (Q_include & ~Q_exclude)
Ejemplo n.º 11
0
    def onsite_create(self, request, tl, one, two, module, extra, prog):
        if request.method == 'POST':
            form = OnSiteRegForm(request.POST)
            
            if form.is_valid():
                new_data = form.cleaned_data
                username = ESPUser.get_unused_username(new_data['first_name'], new_data['last_name'])
                new_user = ESPUser(username = username,
                                first_name = new_data['first_name'],
                                last_name  = new_data['last_name'],
                                email      = new_data['email'],
                                is_staff   = False,
                                is_superuser = False)
                new_user.save()

                self.student = new_user

                regProf = RegistrationProfile.getLastForProgram(new_user,
                                                                self.program)
                contact_user = ContactInfo(first_name = new_user.first_name,
                                           last_name  = new_user.last_name,
                                           e_mail     = new_user.email,
                                           user       = new_user)
                contact_user.save()
                regProf.contact_user = contact_user

                student_info = StudentInfo(user = new_user, graduation_year = ESPUser.YOGFromGrade(new_data['grade']))
                student_info.save()
                regProf.student_info = student_info

                regProf.save()
                
                if new_data['paid']:
                    self.createBit('Paid')
                    self.updatePaid(True)
                else:
                    self.updatePaid(False)

                self.createBit('Attended')

                if new_data['medical']:
                    self.createBit('MedicalFiled')

                if new_data['liability']:
                    self.createBit('LiabilityFiled')

                self.createBit('OnSite')

                v = GetNode( 'V/Flags/UserRole/Student')
                ub = UserBit()
                ub.user = new_user
                ub.recursive = False
                ub.qsc = GetNode('Q')
                ub.verb = v
                ub.save()

                new_user.recoverPassword()
                
                return render_to_response(self.baseDir()+'reg_success.html', request, (prog, tl), {
                    'student': new_user, 
                    'retUrl': '/onsite/%s/classchange_grid?student_id=%s' % (self.program.getUrlBase(), new_user.id)
                    })

        else:
            form = OnSiteRegForm()

	return render_to_response(self.baseDir()+'reg_info.html', request, (prog, tl), {'form':form, 'current_year':ESPUser.current_schoolyear()})