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)
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, }
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"
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
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
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
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
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)
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)
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)
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)
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)
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)
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)
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)
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
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()
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
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, )
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
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"
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()
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, {}),)
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, {}), )
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)
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, }
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], })
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, {}), )
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"
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()
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
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)
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)
def get_city(): return Configuration.get_or_default("Default City", "").value
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)
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)
def get_default_three(): return int(Configuration.get_or_default('Discipline Merit Level Three', default=3).value)
def get_default_two(): return int(Configuration.get_or_default('Discipline Merit Level Two', default=1).value)
def get_default_one(): return int(Configuration.get_or_default('Discipline Merit Level One', default=0).value)
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
def get_default_four(): return int(Configuration.get_or_default('Discipline Merit Level Four', default=5).value)