示例#1
0
    def save(self, creating_worker=False, *args, **kwargs):
        self.cache_cohorts()
        if self.is_active == False and (Configuration.get_or_default("Clear Placement for Inactive Students","False").value == "True" \
        or Configuration.get_or_default("Clear Placement for Inactive Students","False").value == "true" \
        or Configuration.get_or_default("Clear Placement for Inactive Students","False").value == "T"):
            try:
                self.studentworker.placement = None
                self.studentworker.save()
            except:
                pass
        # Check year
        self.determine_year()
        super(Student, self).save(*args, **kwargs)

        # Create student worker if the app is installed.
        # https://code.djangoproject.com/ticket/7623
        if 'work_study' in settings.INSTALLED_APPS:
            if not creating_worker and not hasattr(self, 'studentworker'):
                from work_study.models import StudentWorker
                worker = StudentWorker(user_ptr_id=self.user_ptr_id)
                worker.__dict__.update(self.__dict__)
                worker.save(creating_worker=True)

        group, gcreated = Group.objects.get_or_create(name="students")
        self.user_ptr.groups.add(group)
示例#2
0
def global_stuff(request):
    try:
        header_image = Configuration.objects.get_or_create(name="Header Logo")[0].file.url
    except:
        header_image = None
    school_name = Configuration.get_or_default('School Name', default="Unnamed School")
    school_color = Configuration.get_or_default('School Color', default="").value
    google_analytics_code = Configuration.get_or_default('Google Analytics').value
    
    # Only show messages if user just logged in
    user_messages = None
    if not request.session.get('has_seen_message', False) and request.user.is_authenticated():
        today = datetime.date.today()
        if request.user.groups.filter(name='students'):
            user_messages = MessageToStudent.objects.filter(start_date__lte=today, end_date__gte=today)
        if request.user.groups.filter(name='company') and 'work_study' in settings.INSTALLED_APPS:
            from work_study.models import MessageToSupervisor
            user_messages = MessageToSupervisor.objects.filter(start_date__lte=today, end_date__gte=today)
        request.session['has_seen_message'] = True

    return {
        "header_image": header_image,
        "school_name": school_name,
        "settings": settings,
        "school_color": school_color,
        'user_messages':user_messages,
        'google_analytics_code': google_analytics_code,
    }
示例#3
0
def get_active_class_config():
    if Configuration.get_or_default("Only Active Classes in Schedule", None).value == "True" \
    or Configuration.get_or_default("Only Active Classes in Schedule", None).value == "true" \
    or Configuration.get_or_default("Only Active Classes in Schedule", None).value == "T":
        return "True"
    else:
        return "False"
示例#4
0
def get_active_class_config():
    if Configuration.get_or_default("Only Active Classes in Schedule", None).value == "True" \
    or Configuration.get_or_default("Only Active Classes in Schedule", None).value == "true" \
    or Configuration.get_or_default("Only Active Classes in Schedule", None).value == "T":
        return "True"
    else:
        return "False"
示例#5
0
    def build_schedule(self,
                       student,
                       marking_period,
                       include_asp=False,
                       schedule_days=None):
        """
        Returns days ['Monday', 'Tuesday'...] and periods
        """
        periods = Period.objects.filter(
            coursesection__courseenrollment__user=student,
            coursesection__marking_period=marking_period).order_by(
                'start_time').distinct()
        course_meets = CourseMeet.objects.filter(
            course_section__courseenrollment__user=student,
            course_section__marking_period=marking_period).distinct()

        if schedule_days is None:
            day_list = CourseMeet.day_choice
        else:
            # super ugly
            day_choices = dict(CourseMeet.day_choice)
            day_list = []
            for schedule_day in schedule_days:
                day_list.append((schedule_day, day_choices[schedule_day]))
        days = []
        arr_days = []
        for day in day_list:
            if course_meets.filter(day=day[0]).count():
                days.append(day[1])
                arr_days.append(day)

        only_active = Configuration.get_or_default("Only Active Classes in Schedule", "False").value in \
            ['T', 'True', '1', 't', 'true']
        hide_meetingless = Configuration.get_or_default('Hide Empty Periods in Schedule').value in \
            ['T', 'True', '1', 't', 'true']

        useful_periods = []
        for period in periods:
            has_meeting = False
            period.days = []
            for day in arr_days:
                if only_active:
                    course_section = course_meets.filter(
                        day=day[0],
                        period=period,
                        course_section__is_active=True)
                else:
                    course_section = course_meets.filter(day=day[0],
                                                         period=period)
                if course_section.exists():
                    period.days.append(course_section[0])
                    has_meeting = True
                else:
                    period.days.append(None)
            if has_meeting or not hide_meetingless:
                useful_periods.append(period)
        return days, useful_periods
示例#6
0
    def get_appy_context(self):
        context = super(SisReport, self).get_appy_context()
        context['date'] = datetime.date.today()
        students = context['objects']
        template = self.report_context.get('template')
        if template:
            self.date_end = self.report_context['date_end']

            # backwards compatibility for templates
            context['date_of_report'] = self.date_end
            context['school_year'] = self.report_context['school_year']
            context['school_name'] = Configuration.get_or_default(name="School Name")

            if template.transcript:
                self.pass_score = float(Configuration.get_or_default("Passing Grade", '70').value)
                self.pass_letters = Configuration.get_or_default("Letter Passing Grade", 'A,B,C,P').value
                for student in students:
                    self.get_student_transcript_data(student)
            if template.benchmark_report_card and \
                'benchmark_grade' in settings.INSTALLED_APPS:
                from benchmark_grade.report import get_benchmark_report_card_data
                get_benchmark_report_card_data(self.report_context, context, students)
            elif template.report_card:
                self.blank_grade = struct()
                self.blank_grade.comment = ""
                school_year = SchoolYear.objects.filter(start_date__lte=self.report_context['date_end']
                        ).order_by('-start_date').first()
                context['year'] = school_year
                self.marking_periods = MarkingPeriod.objects.filter(
                    school_year=school_year, show_reports=True)
                context['marking_periods'] = self.marking_periods.order_by('start_date')
                for student in students:
                    self.get_student_report_card_data(student)
            if template.general_student:
                cal = Calendar()
                schedule_days = self.report_context.get('schedule_days', None)
                marking_periods = MarkingPeriod.objects.filter(start_date__gte=self.report_context['date_end'],
                    end_date__lte=self.report_context['date_end']).order_by('start_date')
                if not marking_periods.count():
                    marking_periods = MarkingPeriod.objects.filter(start_date__gte=self.report_context['date_begin']).order_by('start_date')
                current_mp = marking_periods[0]
                for student in students:
                    if current_mp:
                        student.schedule_days, student.periods = cal.build_schedule(student, current_mp,
                            schedule_days=schedule_days)
                    #student.discipline_records = student.studentdiscipline_set.filter(date__gte=begin_end_dates[0],
                    #    date__lte=begin_end_dates[1])
                    #for d in student.discipline_records:
                    #    d.date = d.date.strftime('%b %d, %Y')

        context['students'] = students
        return context
示例#7
0
 def is_passing(self, student, date_report=None):
     """Is student passing course? """
     pass_score = float(
         Configuration.get_or_default("Passing Grade", '70').value)
     grade = self.get_final_grade(student, date_report=date_report)
     try:
         if grade >= int(pass_score):
             return True
     except:
         pass_letters = Configuration.get_or_default(
             'Letter Passing Grade', 'A,B,C,P').value
         if grade in pass_letters.split(','):
             return True
     return False
示例#8
0
 def get_email(self):
     """ Returns email address using various configurable methods """
     email_method = Configuration.get_or_default(
         "How to obtain student email",
         default="append",
         help_text="append, user, or student.").value
     if email_method == "append":
         email_end = Configuration.get_or_default("email", default="@change.me").value
         return '%s%s' % (self.student.username, email_end)
     elif email_method == "user":
         if User.objects.filter(username=self.student.username):
             return User.objects.filter(username=self.student.username)[0].email
         return None
     return self.alt_email
示例#9
0
 def add_view(self, request, form_url='', extra_context=None):
     levels = []
     # Attempt to guess next school year
     future_years = SchoolYear.objects.filter(
         start_date__gt=datetime.date.today()).order_by('start_date')
     if future_years:
         override_date = Configuration.get_or_default(
             name="admissions_override_year_start",
             default='',
             help_text="Must be ISO date (ex 2012-10-25) or blank",
         ).value
         if override_date:
             try:
                 override_date = parser.parse(override_date)
                 future_years[0].start_date = override_date
             except:
                 pass
         year = future_years[0]
     else:
         year = None
     for level in AdmissionLevel.objects.all():
         level.checks = []
         level.max = 0
         for check in AdmissionCheck.objects.filter(level=level):
             level.checks.append(check)
             level.max += 1
         levels.append(level)
     my_context = {
         'levels': levels,
         'current_level': None,
         'year': year,
     }
     return super(ApplicantAdmin, self).add_view(request,
                                                 form_url,
                                                 extra_context=my_context)
示例#10
0
 def get_user_excludes(self):
     # get user-configured exclusions at runtime
     allowed_exclude = set(['marking_period', 'assignment_type', 'benchmark', 'date', 'description'])
     from administration.models import Configuration
     exclude = [x.strip() for x in Configuration.get_or_default('Gradebook hide fields').value.lower().split(',')]
     exclude = set(exclude).intersection(allowed_exclude)
     return list(exclude)
示例#11
0
class SchoolYear(models.Model):
    name = models.CharField(max_length=255, unique=True)
    start_date = models.DateField(validators=settings.DATE_VALIDATORS)
    end_date = models.DateField(validators=settings.DATE_VALIDATORS)
    grad_date = models.DateField(blank=True, null=True, validators=settings.DATE_VALIDATORS)
    active_year = models.BooleanField(default=False,
        help_text="DANGER!! This is the current school year. There can only be one and setting this will remove it from other years. " \
                  "If you want to change the active year you almost certainly want to click Management, Change School Year.")
    benchmark_grade = models.BooleanField(default=lambda: str(Configuration.get_or_default("Benchmark-based grading", "False").value).lower() == "true",
                                          help_text="Causes additional information to appear on transcripts. The configuration option \"Benchmark-based grading\" sets the default for this field.")

    class Meta:
        ordering = ('-start_date',)

    def __unicode__(self):
        return self.name

    def get_number_days(self, date=date.today()):
        """ Returns number of active school days in this year, based on
        each marking period of the year.
        date: Defaults to today, date to count towards. Used to get days up to a certain date"""
        mps = self.markingperiod_set.filter(show_reports=True).order_by('start_date')
        day = 0
        for mp in mps:
            day += mp.get_number_days(date)
        return day

    def save(self, *args, **kwargs):
        super(SchoolYear, self).save(*args, **kwargs)
        if self.active_year:
            all = SchoolYear.objects.exclude(id=self.id).update(active_year=False)
示例#12
0
    def save(self, *args, **kwargs):
        try:
            previous = StudentWorker.objects.get(id=self.id)
            if previous.placement != self.placement:
                history = CompanyHistory(student=self,
                                         placement=previous.placement)
                history.save()
                # set primary contact to None if company has changed and p_contact isn't explicitly set
                if previous.primary_contact == self.primary_contact:
                    self.primary_contact = None
        except:
            pass

        if self.primary_contact and self.placement:
            self.placement.contacts.add(self.primary_contact)

        # set pay rates
        if not self.school_pay_rate and not self.student_pay_rate:
            try:
                self.school_pay_rate = Decimal(
                    Configuration.get_or_default("school pay rate per hour",
                                                 default="13.00").value)
                self.student_pay_rate = Decimal(
                    Configuration.objects.get("student pay rate per hour",
                                              default="9").value)
            except:
                pass
        super(StudentWorker, self).save(*args, **kwargs)
示例#13
0
def email_admissions_new_inquiries():
    """ Email Admissions team about new online inquiries
    """
    from_email = Configuration.get_or_default("From Email Address").value
    to_email = Configuration.get_or_default('admissions_notify_email').value
    if not len(to_email):
        # don't complain if no one wants this report, just quit
        return
    # validate the from address
    try:
        validate_email(from_email)
    except ValidationError:
        logging.warning(
            'email_admissions_new_inquiries failed because of invalid From Email Address "{}"'
            .format(from_email),
            exc_info=True)
        return
    # validate the to addresses
    to_email_list = []
    for addr in to_email.split(','):
        try:
            validate_email(addr)
            to_email_list.append(addr)
        except ValidationError:
            logging.warning(
                'email_admissions_new_inquiries omitting invalid address "{}" in admissions_notify_email'
                .format(addr),
                exc_info=True)

    subject = "New online inquiries"
    today = datetime.date.today()

    new_inquiries = Applicant.objects.filter(date_added=today,
                                             from_online_inquiry=True)
    if new_inquiries:
        msg = "The following inquiries were submitted today\n"
        for inquiry in new_inquiries:
            msg += '\n<a href="{0}{1}">{2} {3}</a>\n'.format(
                get_base_url(),
                reverse_lazy('admin:admissions_applicant_change',
                             args=(inquiry.id, )), inquiry.fname,
                inquiry.lname)
            if Applicant.objects.filter(fname=inquiry.fname,
                                        lname=inquiry.lname).count() > 1:
                msg += "(May be duplicate)\n"

        send_mail(subject, msg, from_email, to_email_list)
示例#14
0
    def get_report(self, report_view, context):
        marking_periods = report_view.report.report_context['marking_periods']
        # anticipate str(student.year)
        students = Student.objects.select_related('year__name').filter(
            courseenrollment__course__marking_period__in=marking_periods
        ).distinct()
        titles = ['']
        departments = Department.objects.filter(course__courseenrollment__user__is_active=True).distinct()

        for department in departments:
            titles += [str(department)]
        titles += ['Total', '', 'Username', 'Year','GPA', '', 'Failed courses']

        passing_grade = float(Configuration.get_or_default('Passing Grade','70').value)

        data = []
        iy=2
        for student in students:
            row = [str(student)]
            ix = 1 # letter A
            # query the database once per student, not once per student per department
            # anticipate calling str() on grade.course and grade.marking_period
            student.failed_grades = student.grade_set.select_related(
                'course__department_id',
                'course__fullname',
                'marking_period__name',
            ).filter(
                override_final=False,
                grade__lt=passing_grade,
                marking_period__in=marking_periods
            ).distinct()
            department_counts = {}
            end_of_row = []
            for grade in student.failed_grades:
                # every failing grade gets dumped out at the end of the row
                end_of_row += [
                    str(grade.course),
                    str(grade.marking_period),
                    str(grade.grade)
                ]
                # add one to the failed grade count for this department
                department_counts[grade.course.department_id] = department_counts.get(
                    grade.course.department_id, 0) + 1
            for department in departments:
                row += [department_counts.get(department.pk, 0)]
                ix += 1
            row += [
                '=sum(b{0}:{1}{0})'.format(str(iy),get_column_letter(ix)),
                '',
                student.username,
                str(student.year),
                student.gpa,
                '',
                ]
            row += end_of_row
            data += [row]
            iy += 1

        return report_view.list_to_xlsx_response(data, 'fail_report', header=titles)
示例#15
0
 def update_contacts_from_sugarcrm(self):
     """ Query recently changed contacts in SugarCRM and sync them to django-sis
     """
     modify_date_minutes = int(Configuration.get_or_default("sync sugarcrm minutes",default="30").value)
     modify_date = datetime.datetime.now() - datetime.timedelta(minutes=modify_date_minutes + 1)
     contacts = self.get_recent_sugar_contacts(modify_date)
     for contact in contacts:
         self.set_django_sis_contact(contact)
示例#16
0
 def get_readonly_fields(self, request, obj=None):
     edit_all = Configuration.get_or_default(
         "Edit all Student Worker Fields", "False")
     if edit_all.value == "True":
         return [
             'parent_guardian', 'street', 'city', 'state', 'zip',
             'parent_email', 'alt_email'
         ]
     return super(StudentAdmin, self).get_readonly_fields(request, obj=obj)
示例#17
0
 def build_schedule(self, student, marking_period, include_asp=False, schedule_days=None):
     """
     Returns days ['Monday', 'Tuesday'...] and periods
     """
     periods = Period.objects.filter(course__courseenrollment__user=student, course__marking_period=marking_period).order_by('start_time').distinct()
     course_meets = CourseMeet.objects.filter(course__courseenrollment__user=student, course__marking_period=marking_period).distinct()
     
     if schedule_days is None:
         day_list = CourseMeet.day_choice
     else:
         # super ugly
         day_choices = dict(CourseMeet.day_choice)
         day_list = []
         for schedule_day in schedule_days:
             day_list.append((schedule_day, day_choices[schedule_day]))
     days = []
     arr_days = []
     for day in day_list:
         if course_meets.filter(day=day[0]).count():
             days.append(day[1])
             arr_days.append(day)
             
     only_active = Configuration.get_or_default("Only Active Classes in Schedule", "False").value in \
         ['T', 'True', '1', 't', 'true']
     hide_meetingless = Configuration.get_or_default('Hide Empty Periods in Schedule').value in \
         ['T', 'True', '1', 't', 'true']
     
     useful_periods = []
     for period in periods:
         has_meeting = False
         period.days = []
         for day in arr_days:
             if  only_active:
                 course = course_meets.filter(day=day[0], period=period, course__active=True)
             else:
                 course = course_meets.filter(day=day[0], period=period)
             if course.count():
                 period.days.append(course[0])
                 has_meeting = True
             else:
                 period.days.append(None)
         if has_meeting or not hide_meetingless:
             useful_periods.append(period)
     return days, useful_periods
示例#18
0
def fte_by_day(request):
    cursor = connection.cursor()
    fte = int(Configuration.get_or_default(name="Students per FTE"[0], default=5).value)
    cursor.execute("select day, count(*)/" + str(fte) + \
        " from work_study_studentworker left join work_study_workteam on work_study_workteam.id = "+\
        "work_study_studentworker.placement_id where work_study_workteam.inactive = False group by day;")
    names = cursor.fetchall()
    titles = (["Day", "FTE"])
    report = XlReport(file_name="report_fteByDay")
    report.add_sheet(names, header_row=titles, title="FTE by Day of Week", heading="FTE by Day of Week")
    return report.as_download()
示例#19
0
def get_start_date_default():
    """ Return default date for report. It should be X work days ago. """
    work_days = (0,1,2,3,4) # python day of weeks mon-fri
    # Traverse back these many days
    days_back = int(Configuration.get_or_default('Discipline Merit Default Days', default=14).value)
    default_date = datetime.date.today()
    while days_back > 0:
        while not default_date.weekday() in work_days:
            default_date = default_date - datetime.timedelta(days=1)
        default_date = default_date - datetime.timedelta(days=1)
        days_back -= 1
    return default_date
示例#20
0
    def save(self, *args, **kwargs):
        email = False
        emailStu = False

        if not self.supervisor_key or self.supervisor_key == "":
            # Use previous key if one exists
            if self.id:
                ts = TimeSheet.objects.get(id=self.id)
                self.supervisor_key = ts.supervisor_key
            else:
                self.genKey()
                email = True

        # set hours
        hours = self.time_lunch.hour - self.time_in.hour
        mins = self.time_lunch.minute - self.time_in.minute
        hours += self.time_out.hour - self.time_lunch_return.hour
        mins += self.time_out.minute - self.time_lunch_return.minute
        hours += mins / Decimal(60)
        self.hours = hours

        # set pay rates
        if self.for_pay and not self.school_pay_rate and not self.student_pay_rate:
            try:
                self.school_pay_rate = self.student.school_pay_rate
                self.student_pay_rate = self.student.student_pay_rate
            except:
                print >> sys.stderr, "warning: pay rate for company not set. "

        # set payment net sum
        if self.school_pay_rate:
            self.school_net = self.hours * self.school_pay_rate
        if self.student_pay_rate:
            self.student_net = self.hours * self.student_pay_rate

        super(TimeSheet, self).save(*args, **kwargs)

        self.student = StudentWorker.objects.get(
            id=self.student.id)  # refresh data for p contact
        if email and self.student.primary_contact:
            try:
                sendTo = self.student.primary_contact.email
                subject = "Time Sheet for " + str(self.student)
                msg = "Hello " + unicode(self.student.primary_contact.fname) + ",\nPlease click on the link below to approve the time sheet.\n" + \
                    settings.BASE_URL + "/work_study/approve?key=" + str(self.supervisor_key)
                from_addr = Configuration.get_or_default(
                    "From Email Address", "*****@*****.**").value
                send_mail(subject, msg, from_addr, [sendTo])
            except:
                print >> sys.stderr, "Unable to send e-mail to supervisor! %s" % (
                    self, )
示例#21
0
def get_start_date_default():
    """ Return default date for report. It should be X work days ago. """
    work_days = (0, 1, 2, 3, 4)  # python day of weeks mon-fri
    # Traverse back these many days
    days_back = int(
        Configuration.get_or_default('Discipline Merit Default Days',
                                     default=14).value)
    default_date = datetime.date.today()
    while days_back > 0:
        while not default_date.weekday() in work_days:
            default_date = default_date - datetime.timedelta(days=1)
        default_date = default_date - datetime.timedelta(days=1)
        days_back -= 1
    return default_date
示例#22
0
 def save(self, *args, **kwargs):
     super(ClientVisit, self).save(*args, **kwargs)
     if self.notify_mentors:
         try:
             users = User.objects.filter(groups__name='mentor')
             sendTo = []
             for user in users:
                 sendTo.append(user.email)
             subject = "CRA visit at " + unicode(self.company)
             msg = "A CRA report has been entered for " + unicode(self.company) + " on " + unicode(self.date) + ".\n" + unicode(self.notes)
             from_addr = Configuration.get_or_default("From Email Address", "*****@*****.**").value
             send_mail(subject, msg, from_addr, sendTo)
         except:
             print >> sys.stderr, "warning: could not e-mail mentors"
示例#23
0
def fte_by_ind(request):
    """ FTE by industry
    """
    cursor = connection.cursor()
    fte = int(Configuration.get_or_default(name="Students per FTE"[0], default=5).value)
    cursor.execute("select industry_type, count(*)/" + str(fte) + \
        " from work_study_studentworker left join work_study_workteam on work_study_workteam.id = "+\
        "work_study_studentworker.placement_id where work_study_workteam.inactive = False group by industry_type;")
    names = cursor.fetchall()
    titles = (["Industry", "FTE"])
    report = XlReport(file_name="report_fteByInd")
    report.add_sheet(data=names, header_row=titles, title="Analytics Report", heading="FTE by Industry Type")
    report.add_sheet(data=student_company_day_report(industry_type=True), heading="Detail")
    return report.as_download()
示例#24
0
def applicants_to_students(request, year_id):
    """ Copies all applicants marked as ready for export to sis students
    Does not create copies. Once student is in sis he/she cannot be updated
    from applicant data."""
    imp = Importer()
    school_year = SchoolYear.objects.get(id=year_id)
    msg = ""
    if request.POST:
        imp = Importer()
        applicants = Applicant.objects.filter(ready_for_export=True, sis_student=None, school_year=school_year)
        for appl in applicants:
            student = Student(
                first_name=appl.fname,
                mname=appl.mname,
                last_name=appl.lname,
                sex=appl.sex,
                ssn=appl.ssn,
                bday=appl.bday,
                unique_id=appl.unique_id,
                email=appl.email,
                year=appl.year,
                pic=appl.pic,
                family_preferred_language=appl.family_preferred_language,
            )
            if not student.username:
                student.username = imp.gen_username(student.first_name, student.last_name)
            student.save()

            add_worker = Configuration.get_or_default("Admissions to student also makes student worker", "False")
            if add_worker.value == "True":
                student.promote_to_worker()

            appl.sis_student = student
            appl.save()
            for sib in appl.siblings.all():
                student.siblings.add()
            for par in appl.parent_guardians.all():
                student.emergency_contacts.add(par)
            student.save()
            for contact in student.emergency_contacts.filter(primary_contact=True):
                contact.cache_student_addresses()
            msg += "Imported <a href='/admin/sis/student/%s'>%s</a>, %s<br/>" % (student.id, unicode(student), student.username)
        msg += "<br/>Maybe you want to save this list to add students to Active Directory or Google Apps?<br/><br/>"

    num = Applicant.objects.filter(ready_for_export=True, sis_student=None, school_year=school_year).count()
    msg += "There are currently %s applicants marked as ready for export. This is not a reversable process! Note usernames will be generated, you may change them later.<br/>" % str(num)
    return render_to_response('admissions/applicants_to_students.html',
                              {'msg': msg},
                              RequestContext(request, {}),)
示例#25
0
def student_gradesheet(request, id, year_id=None):
    student = get_object_or_404(Student, id=id)
    if request.POST:
        handle_grade_save(request)
    courses = student.course_set.filter(graded=True)
    school_years = SchoolYear.objects.filter(
        markingperiod__course__enrollments__student=student).distinct()
    if year_id:
        school_year = SchoolYear.objects.get(id=year_id)
    else:
        school_year = SchoolYear.objects.get(active_year=True)
    courses = courses.filter(
        marking_period__school_year=school_year).distinct()

    for course in courses:
        for mp in school_year.markingperiod_set.all():
            grade, created = Grade.objects.get_or_create(student=student,
                                                         course=course,
                                                         marking_period=mp)
        course.grades = student.grade_set.filter(course=course,
                                                 override_final=False)

        try:
            override_grade = course.grade_set.get(student=student,
                                                  override_final=True)
            course.final = unicode(override_grade.get_grade())
            course.final_override = True  # effects CSS
        except:
            course.final = course.calculate_final_grade(student)

    marking_periods = MarkingPeriod.objects.filter(
        course__in=courses).distinct().order_by('start_date')

    letter_grade_required_for_pass = Configuration.get_or_default(
        'letter_grade_required_for_pass', '60').value

    return render_to_response(
        'grades/student_gradesheet.html',
        {
            'request': request,
            'student': student,
            'courses': courses,
            'marking_periods': marking_periods,
            'school_year': school_year,
            'school_years': school_years,
            'letter_grade_required_for_pass': letter_grade_required_for_pass,
        },
        RequestContext(request, {}),
    )
示例#26
0
    def save(self, creating_worker=False, *args, **kwargs):
        # self.cache_cohorts()
        if self.is_active == False and (Configuration.get_or_default("Clear Placement for Inactive Students","False").value == "True" \
        or Configuration.get_or_default("Clear Placement for Inactive Students","False").value == "true" \
        or Configuration.get_or_default("Clear Placement for Inactive Students","False").value == "T"):
            try:
                self.studentworker.placement = None
            except: pass
        # Check year
        self.determine_year()

        super(Student, self).save(*args, **kwargs)

        # Create student worker if the app is installed.
        # https://code.djangoproject.com/ticket/7623
        if 'work_study' in settings.INSTALLED_APPS:
            if not creating_worker and not hasattr(self, 'studentworker'):
                from work_study.models import StudentWorker
                worker = StudentWorker(user_ptr_id=self.user_ptr_id)
                worker.__dict__.update(self.__dict__)
                worker.save(creating_worker=True)

        group, gcreated = Group.objects.get_or_create(name="students")
        self.user_ptr.groups.add(group)
示例#27
0
def global_stuff(request):
    try:
        header_image = Configuration.objects.get_or_create(
            name="Header Logo")[0].file.url
    except:
        header_image = None
    school_name = Configuration.get_or_default('School Name',
                                               default="Unnamed School")
    school_color = Configuration.get_or_default('School Color',
                                                default="").value
    google_analytics_code = Configuration.get_or_default(
        'Google Analytics').value

    # Only show messages if user just logged in
    user_messages = None
    if not request.session.get('has_seen_message',
                               False) and request.user.is_authenticated():
        today = datetime.date.today()
        if request.user.groups.filter(name='students'):
            user_messages = MessageToStudent.objects.filter(
                start_date__lte=today, end_date__gte=today)
        if request.user.groups.filter(
                name='company') and 'work_study' in settings.INSTALLED_APPS:
            from work_study.models import MessageToSupervisor
            user_messages = MessageToSupervisor.objects.filter(
                start_date__lte=today, end_date__gte=today)
        request.session['has_seen_message'] = True

    return {
        "header_image": header_image,
        "school_name": school_name,
        "settings": settings,
        "school_color": school_color,
        'user_messages': user_messages,
        'google_analytics_code': google_analytics_code,
    }
示例#28
0
 def emailStudent(self, show_comment=True):
     try:
         sendTo = self.student.get_email
         subject = "Time sheet approved for " + unicode(self.student)
         if show_comment:
             msg = "Hello " + unicode(self.student) + ",\nYour time card for " + self.date.strftime("%x") + " was approved. Your rating was " + unicode(self.performance) + " \nYour supervisor's comment was \"" \
                 + unicode(self.supervisor_comment) + "\""
         else:
             msg = "Hello " + unicode(self.student) + ",\nYour time card for " + self.date.strftime("%x") + " was approved."
         from_addr = Configuration.get_or_default("From Email Address", "*****@*****.**").value
         send_mail(subject, msg, from_addr, [str(sendTo)])
     except:
         logging.warning('Could not e-mail student', exc_info=True, extra={
             'exception': sys.exc_info()[0],
             'exception2': sys.exc_info()[1],
         })
示例#29
0
def select_grade_method(request):
    """ Select a per user preferred grading method
    Forward to previously requested page after
    """
    pref = UserPreference.objects.get_or_create(user=request.user)[0]
    if request.POST and 'choice' in request.POST:
        pref.gradebook_preference = request.POST['choice']
        pref.save()
    options = []
    if 'benchmark_grade' in settings.INSTALLED_APPS:
        options += ['O']
    if 'engrade_sync' in settings.INSTALLED_APPS:
        options += ['E']
    allow_spreadsheet = Configuration.get_or_default(
        'grades_allow_spreadsheet_import').value
    if allow_spreadsheet == 'True':
        options += ['S']
    else:
        allow_spreadsheet = False
    if request.user.has_perm('grades.change_own_grade'
                             ) or request.user.has_pem('grades.change_grade'):
        options += ['M']
        allow_manual = True

    if not pref.gradebook_preference and len(options) == 1:
        pref.gradebook_preference = options[0]
        pref.save()

    if pref.gradebook_preference and (not 'override' in request.GET
                                      or request.POST):
        if 'next' in request.GET:
            next_page = request.GET['next']
            if next_page == "teacher_grade":
                return redirect('grades.views.teacher_grade')

    return render_to_response(
        'grades/select_grade_method.html',
        {
            'request': request,
            'allow_spreadsheet': allow_spreadsheet,
            'allow_manual': allow_manual
        },
        RequestContext(request, {}),
    )
示例#30
0
 def save(self, *args, **kwargs):
     if not self.id: new = True
     else: new = False
     super(StudentInteraction, self).save(*args, **kwargs)
     #email if needed
     if self.student.count() >= 1 and new:
         try:
             stu = self.student.all()[0]
             subject = unicode(self)
             msg = "Hello CRA " + unicode(stu.placement.cra.name.first_name) + ",\n"
             for aStudent in self.student.all():
                 msg += unicode(aStudent.fname) + " " + unicode(aStudent.lname) + ", "
             msg = msg[:-2] + " had a mentor meeting on " + unicode(self.date) + "\n" + unicode(self.comments) + "\n"
             for com in self.preset_comment.all():
                 msg += unicode(com) + "\n"
             from_addr = Configuration.get_or_default("From Email Address", "*****@*****.**").value
             send_mail(subject, msg, from_addr, [unicode(stu.placement.cra.name.email)])
         except:
             print >> sys.stderr, "warning: could not e-mail CRA"
示例#31
0
def fte_by_pay(request):
    report = XlReport(file_name="report_fteByPay")
    student_fte = int(Configuration.get_or_default(name="Students per FTE"[0], default=5).value)

    cursor = connection.cursor()
    cursor.execute("select paying, count(*)/" + str(student_fte) + \
                   " from work_study_studentworker left join work_study_workteam on work_study_workteam.id = "+\
        "work_study_studentworker.placement_id where work_study_workteam.inactive = False group by paying;")
    totals = cursor.fetchall()

    cursor = connection.cursor()
    cursor.execute("select team_name, paying, count(*)/" + str(student_fte) + ", funded_by as fte from work_study_studentworker left join work_study_workteam on "+\
        "work_study_workteam.id = work_study_studentworker.placement_id group by team_name order by paying, team_name;")
    company = cursor.fetchall()

    titles = (["Paying?","FTE"])
    report.add_sheet(totals, header_row=titles, title="Totals")
    titles = (["WorkTeam", "Paying?","FTE", "Funded by"])
    report.add_sheet(company, header_row=titles, title="Companies")
    report.add_sheet(student_company_day_report(paying=True), heading="Detail")
    return report.as_download()
示例#32
0
    def calculate_final_grade(self, student, date_report=None):
        """Calculates final grade. Does not take into account overrides.
		Note that this should math recalc_ytd_grade in gradesheet.js! """
        from SMS.grades.models import Grade
        final = Decimal(0)
        number = 0
        letter_grade = False
        grades = Grade.objects.filter(student=student, course=self)
        if date_report:
            grades = grades.filter(marking_period__end_date__lte=date_report)
        for grade in grades:
            try:
                final += grade.get_grade()
                number += 1
            # otherwise it's a letter grade.
            except TypeError:
                # I (Incomplete) results in the final grade being I
                if grade.get_grade() == "I":
                    return "I"
                elif grade.get_grade() in ["P", "HP", "LP"]:
                    final += 100
                    number += 1
                    letter_grade = True
                elif grade.get_grade() == 'F':
                    number += 1
                    letter_grade = True

        if number != 0:
            final = final / number
            final = Decimal(final).quantize(Decimal("0.01"), ROUND_HALF_UP)
            if letter_grade == True:
                if final > int(
                        Configuration.get_or_default(
                            'letter_grade_required_for_pass', '60').value):
                    return "P"
                else:
                    return "F"
        else:
            final = None
        return final
示例#33
0
def post_save_attendance_handler(sender, instance, **kwargs):
    """ Check for any triggers we should run """
    if True:
        try:
            # Create work study attendance if student's workday is today
            if ('ecwsp.work_study' in settings.INSTALLED_APPS and
                Configuration.get_or_default("attendance_create_work_attendance", "False").value == "True" and
                instance.date == datetime.date.today() and
                instance.status.absent and
                hasattr(instance.student, 'studentworker') and
                instance.student.studentworker and
                datetime.date.today().isoweekday() == instance.student.studentworker.get_day_as_iso_date()
               ):
                from ecwsp.work_study.models import Attendance
                attn, created = Attendance.objects.get_or_create(
                    student=instance.student.studentworker,
                    absence_date = datetime.date.today(),
                )
                if created:
                    attn.sis_attendance = instance
                    attn.save()
        except:
            logging.error('Attendance trigger error', exc_info=True)
示例#34
0
def post_save_attendance_handler(sender, instance, **kwargs):
    """ Check for any triggers we should run """
    if True:
        try:
            # Create work study attendance if student's workday is today
            if ('ecwsp.work_study' in settings.INSTALLED_APPS
                    and Configuration.get_or_default(
                        "attendance_create_work_attendance", "False").value
                    == "True" and instance.date == datetime.date.today()
                    and instance.status.absent
                    and hasattr(instance.student, 'studentworker')
                    and instance.student.studentworker
                    and datetime.date.today().isoweekday()
                    == instance.student.studentworker.get_day_as_iso_date()):
                from ecwsp.work_study.models import Attendance
                attn, created = Attendance.objects.get_or_create(
                    student=instance.student.studentworker,
                    absence_date=datetime.date.today(),
                )
                if created:
                    attn.sis_attendance = instance
                    attn.save()
        except:
            logging.error('Attendance trigger error', exc_info=True)
示例#35
0
def get_city():
    return Configuration.get_or_default("Default City", "").value
示例#36
0
def grade_comment_length_validator(value):
    max_length = int(
        Configuration.get_or_default('Grade comment length limit').value)
    validator = MaxLengthValidator(max_length)
    return validator(value)
示例#37
0
def grade_comment_length_validator(value):
    max_length = int(Configuration.get_or_default('Grade comment length limit').value)
    validator = MaxLengthValidator(max_length)
    return validator(value)
示例#38
0
def get_default_three():
    return int(Configuration.get_or_default('Discipline Merit Level Three', default=3).value)
示例#39
0
def get_default_two():
    return int(Configuration.get_or_default('Discipline Merit Level Two', default=1).value)
示例#40
0
def get_default_one():
    return int(Configuration.get_or_default('Discipline Merit Level One', default=0).value)
示例#41
0
    def calculate_grade_real(self, date_report=None, ignore_letter=False):
        """ Calculate the final grade for a course
        ignore_letter can be useful when computing averages
        when you don't care about letter grades
        """
        cursor = connection.cursor()

        # postgres requires a over () to run
        # http://stackoverflow.com/questions/19271646/how-to-make-a-sum-without-group-by
        sql_string = '''
        SELECT ( Sum(grade * weight) {over} / Sum(weight) {over} ) AS ave_grade,
               grades_grade.id,
               grades_grade.override_final
        FROM   grades_grade
               LEFT JOIN schedule_markingperiod
                      ON schedule_markingperiod.id = grades_grade.marking_period_id
        WHERE  ( grades_grade.course_id = %s
                 AND grades_grade.student_id = %s {extra_where} )
               AND ( grade IS NOT NULL
                      OR letter_grade IS NOT NULL )
        ORDER  BY grades_grade.override_final DESC limit 1'''

        if date_report:
            if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql_psycopg2':
                cursor.execute(sql_string.format(
                    over='over ()', extra_where='AND (schedule_markingperiod.end_date <= %s OR override_final = 1)'),
                               (self.course_id, self.user_id, date_report))
            else:
                cursor.execute(sql_string.format(
                    over='', extra_where='AND (schedule_markingperiod.end_date <= %s OR grades_grade.override_final = 1)'),
                               (self.course_id, self.user_id, date_report))

        else:
            if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql_psycopg2':
                cursor.execute(sql_string.format(
                    over='over ()', extra_where=''),
                               (self.course_id, self.user_id))
            else:
                cursor.execute(sql_string.format(
                    over='', extra_where=''),
                               (self.course_id, self.user_id))

        result = cursor.fetchone()
        if result:
            (ave_grade, grade_id, override_final) = result
        else: # No grades at all. The average of no grades is None
            return None

        if override_final:
            course_grades = grades.models.Grade.objects.get(id=grade_id)
            grade = course_grades.get_grade()
            if ignore_letter and not isinstance(grade, (int, Decimal, float)):
                return None
            return grade

        if ave_grade:
            # database math always comes out as a float :(
            return Decimal(ave_grade)

        # about 0.5 s
        # Letter Grade
        if ignore_letter == False:
            final = 0.0
            grades = self.course.grade_set.filter(student=self.user)
            if date_report:
                grades = grades.filter(marking_period__end_date__lte=date_report)
            if grades:
                total_weight = Decimal(0)
                for grade in grades:
                    get_grade =  grade.get_grade()
                    if get_grade in ["I", "IN", "YT"]:
                        return get_grade
                    elif get_grade in ["P","HP","LP"]:
                        if grade.marking_period:
                            final += float(100 * grade.marking_period.weight)
                            total_weight += grade.marking_period.weight
                    elif get_grade in ['F', 'M']:
                        if grade.marking_period:
                            total_weight += grade.marking_period.weight
                    elif get_grade:
                        final += get_grade
                if total_weight:
                    final /= float(total_weight)
                    final = Decimal(final).quantize(Decimal("0.01"), ROUND_HALF_UP)
                    if final > int(Configuration.get_or_default('letter_grade_required_for_pass').value):
                        return "P"
                    else:
                        return "F"
        return None
示例#42
0
def get_default_four():
    return int(Configuration.get_or_default('Discipline Merit Level Four', default=5).value)