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 inquiry_form(request): """ A place for applicants to inquire for more info Places them in the database as an applicant Public view can be used by anyone """ css = Configuration.get_or_default("admissions_inquiry_form_css").value exclude_years = Configuration.get_or_default("admissions_hide_inquiry_grade").value.split(",") valid_years = GradeLevel.objects.all() if exclude_years: try: valid_years = valid_years.exclude(id__in=exclude_years) except: valid_years = GradeLevel.objects.all() if request.POST: form = InquiryForm(request.POST) if form.is_valid(): data = form.cleaned_data applicant = form.save() applicant.from_online_inquiry = True if data["ethnicity_other"]: applicant.ethnicity = EthnicityChoice.objects.get_or_create(name=data["ethnicity_other"])[0] if data["language_other"]: applicant.family_preferred_language = LanguageChoice.objects.get_or_create(name=data["language_other"])[ 0 ] if data["religion_other"]: applicant.religion = ReligionChoice.objects.get_or_create(name=data["religion_other"])[0] if data["p_lname"] and data["p_fname"]: ec = EmergencyContact.objects.get_or_create( fname=data["p_fname"], lname=data["p_lname"], relationship_to_student=data["p_relationship_to_child"], street=data["p_address"], city=data["p_city"], state=data["p_state"], zip=data["p_zip"], email=data["p_email"], )[0] applicant.parent_guardians.add(ec) if data["p_home"]: EmergencyContactNumber.objects.get_or_create(contact=ec, number=data["p_home"], type="H") if data["p_work"]: ec_number = EmergencyContactNumber.objects.get_or_create( contact=ec, number=data["p_work"], ext=data["p_work_ext"], type="W" ) if data["p_mobile"]: ec_number = EmergencyContactNumber.objects.get_or_create( contact=ec, number=data["p_mobile"], type="C" ) applicant.save() log = ContactLog(applicant=applicant, date=datetime.date.today(), note="Sent online inquiry form") log.save() return HttpResponse("Thank you for submitting an inquiry!") else: form = InquiryForm() form.fields["year"].queryset = valid_years return render_to_response("admissions/inquiry_form.html", {"form": form, "css": css}, RequestContext(request, {}))
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 # 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 'ecwsp.work_study' in settings.INSTALLED_APPS: from ecwsp.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, }
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 'ecwsp.work_study' in settings.INSTALLED_APPS: if not creating_worker and not hasattr(self, 'studentworker'): from ecwsp.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 is_passing(self, student, date_report=None, cache_grade=None, cache_passing=None, cache_letter_passing=None): """ Is student passing course? """ if cache_passing == None: pass_score = float( Configuration.get_or_default("Passing Grade", '70').value) else: pass_score = cache_passing if cache_grade: grade = cache_grade else: 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 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. # No other way to do it see: # https://code.djangoproject.com/ticket/7623 if 'ecwsp.work_study' in settings.INSTALLED_APPS: if not creating_worker and not hasattr(self, 'studentworker'): from ecwsp.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 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 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 'ecwsp.work_study' in settings.INSTALLED_APPS: from ecwsp.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 ajax_get_student_info(request, course_id, student_id): student = get_object_or_404(Student, pk=student_id) course = get_object_or_404(Course, pk=course_id) # TODO: remove TC hard-coding try: Category.objects.get(name='Standards') # are we in TC land? standards_missing = Item.objects.filter(course=course, category__name='Standards', mark__student=student).annotate(best_mark=Max('mark__mark')).filter(best_mark__lt=3) if not standards_missing: standards_missing = ('None',) lists = ({'heading':'Standards Missing for {}'.format(student), 'items':standards_missing},) except Category.DoesNotExist: pass_letters = Configuration.get_or_default("Letter Passing Grade").value.split(',') pass_number = float(Configuration.get_or_default("Passing Grade").value) / 100 # yay, assumptions items_missing = Item.objects.filter(course=course, mark__student=student).annotate(best_mark=Max('mark__normalized_mark')).filter( best_mark__lt=pass_number) text_missing = [] for item in items_missing: if item.mark_set.get(student=student).letter_grade in pass_letters: continue text_missing.append(u'{} / {} ({:.0f}%) {}'.format( item.best_mark * float(item.points_possible), item.points_possible, item.best_mark * 100, unicode(item))) lists = ({'heading':'Items Missing for {}'.format(student), 'items':text_missing},) afterword = '<a onclick="open_grade_detail({}, {})">Create report from current view of gradebook (in new tab)</a>' afterword = afterword.format(course_id, student_id) return render_to_response('sis/generic_list_fragment.html', { 'lists': lists, 'afterword': afterword, }, RequestContext(request, {}),)
def build_schedule(self, student, marking_period, include_asp=False): """ 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() days = [] arr_days = [] for day in CourseMeet.day_choice: if course_meets.filter(day=day[0]).count(): days.append(day[1]) arr_days.append(day) for period in periods: period.days = [] for day in arr_days: if Configuration.get_or_default("Only Active Classes in Schedule", "False").value == "True" \ or Configuration.get_or_default("Only Active Classes in Schedule", "False").value == "true" \ or Configuration.get_or_default("Only Active Classes in Schedule", "False").value == "T": 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]) else: period.days.append(None) CourseMeet.objects.filter(course__courseenrollment__user=student, course__marking_period=marking_period, ).distinct() return days, 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'] context[ 'date_of_report'] = self.date_end # backwards compatibility for templates 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 \ 'ecwsp.benchmark_grade' in settings.INSTALLED_APPS: from ecwsp.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 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 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 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 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: print addr 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( settings.BASE_URL, reverse('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 handle(): """ Emails subscribed volunteer managers daily site submissions """ volunteers = Volunteer.objects.filter( email_queue__isnull=False).exclude(email_queue="") if volunteers: from_email = Configuration.objects.get_or_create( name="From Email Address")[0].value to_emails = Configuration.get_or_default( "Volunteer Track Manager Emails", default="").value msg = "Student(s): \n" subject = "SWORD daily volunteer changes" for volunteer in volunteers: msg += "%s - %s\n\n" % (volunteer, volunteer.email_queue) to_emails = to_emails.split(',') sane_to_emails = [] for email in to_emails: if email and email != " ": sane_to_emails.append(email.strip()) send_mail(subject, msg, from_email, sane_to_emails) for volunteer in volunteers: volunteer.email_queue = "" volunteer.save()
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 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 email student", exc_info=True, extra={"exception": sys.exc_info()[0], "exception2": sys.exc_info()[1]}, )
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( 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 Admin, 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, saved_by_volunteer=False, *args, **kwargs): if not self.secret_key or self.secret_key == "": self.genKey() if saved_by_volunteer: if not self.volunteer.email_queue: self.volunteer.email_queue = "" self.volunteer.email_queue += "Added site %s. " % (unicode(self.site)) self.volunteer.save() if self.id: old_volunteer = VolunteerSite.objects.get(id=self.id) if old_volunteer.site_approval == "Submitted" and self.site_approval == "Accepted": try: from django.core.mail import send_mail from_email = Configuration.get_or_default("From Email Address",default="*****@*****.**").value msg = "Hello %s,\nYour site %s has been approved!" % (self.volunteer, self.site) subject = "Site approval" send_to = self.volunteer.student.get_email send_mail(subject, msg, from_email, [send_to]) except: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] logging.warning( 'Unable to send email to volunteer about site approval! %s' % (self,), exc_info=True, extra={'request': request,'exception':exc_type,'traceback':'%s %s' % (fname,exc_tb.tb_lineno)} ) super(VolunteerSite, self).save(*args, **kwargs)
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 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 ecwsp.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)
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 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 ecwsp.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)
def save(self, saved_by_volunteer=False, *args, **kwargs): if not self.secret_key or self.secret_key == "": self.genKey() if saved_by_volunteer: if not self.volunteer.email_queue: self.volunteer.email_queue = "" self.volunteer.email_queue += "Added site %s. " % (unicode(self.site)) self.volunteer.save() if self.id: old_volunteer = VolunteerSite.objects.get(id=self.id) if old_volunteer.site_approval == "Submitted" and self.site_approval == "Accepted": try: from django.core.mail import send_mail from_email = Configuration.get_or_default("From Email Address",default="*****@*****.**").value msg = "Hello %s,\nYour site %s has been approved!" % (self.volunteer, self.site) subject = "Site approval" send_to = self.volunteer.student.get_email send_mail(subject, msg, from_email, [send_to]) except: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] logging.warning( 'Unable to send email to volunteer about site approval! %s' % (self,), exc_info=True, extra={'request': request,'exception':exc_type,'traceback':'%s %s' % (fname,exc_tb.tb_lineno)} ) super(VolunteerSite, self).save(*args, **kwargs)
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'] context['date_of_report'] = self.date_end # backwards compatibility for templates 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 \ 'ecwsp.benchmark_grade' in settings.INSTALLED_APPS: from ecwsp.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 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=3 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__lte=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 save(self, *args, **kwargs): if not self.id: new = True else: new = False super(ReferralForm, self).save(*args, **kwargs) if new: try: subject = 'New counseling referral for %s.' % (self.student,) msg = '%s has submitted a counseling referral form for %s. Click this link to view \n%s%s' % \ (self.referred_by,self.student,settings.BASE_URL,reverse('admin:counseling_referralform_change',args=(self.id,)),) from_addr = Configuration.get_or_default("From Email Address", "*****@*****.**").value to_addr = Configuration.get_or_default("counseling_referral_notice_email_to", "").value.split(',') if to_addr and to_addr != ['']: send_mail(subject, msg, from_addr, to_addr) except: logging.error('Couldn\'t email counseling referral form', exc_info=True)
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 calculate_final_grade(self, student, date_report=None): """ Calculates final grade. Note that this should match recalc_ytd_grade in gradesheet.js! """ if 'ecwsp.grades' in settings.INSTALLED_APPS: from ecwsp.grades.models import Grade final = Grade.objects.filter(course=self, override_final=True, student=student) if final: if not date_report or final[0].course.marking_period.filter( end_date__lte=date_report).count(): return final[0].get_grade() final = Decimal(0) number = 0 letter_grade = False grades = Grade.objects.filter(student=student, course=self, marking_period__course=self) if date_report: grades = grades.filter( marking_period__end_date__lte=date_report) total_weight = Decimal(0) for grade in grades: total_weight += grade.marking_period.weight for grade in grades: try: final += Decimal(grade.get_grade()) * ( grade.marking_period.weight / total_weight) number += 1 # otherwise it's a letter grade. except: # 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 * (grade.marking_period.weight / total_weight) number += 1 letter_grade = True elif grade.get_grade() == 'F': number += 1 letter_grade = True if number != 0: 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 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 get_context_data(self, **kwargs): context = super(StudentGradesheet, self).get_context_data(**kwargs) context[ 'letter_grade_required_for_pass'] = Configuration.get_or_default( 'letter_grade_required_for_pass', '60').value context['school_years'] = SchoolYear.objects.filter( markingperiod__coursesection__enrollments=self.object).distinct() context['default_school_year'] = context['school_years'].first() return context
def is_passing(self, student, date_report=None, cache_grade=None, cache_passing=None, cache_letter_passing=None): """ Is student passing course? """ if cache_passing == None: pass_score = float(Configuration.get_or_default("Passing Grade", '70').value) else: pass_score = cache_passing if cache_grade: grade = cache_grade else: 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 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 save(self, *args, **kwargs): if Faculty.objects.filter(id=self.id).count(): raise ValidationError('Cannot have someone be a student AND faculty!') self.cache_cohorts() if self.inactive == True 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) user, created = User.objects.get_or_create(username=self.username) if created: user.password = "******" user.save() group, gcreated = Group.objects.get_or_create(name="students") user.groups.add(group)
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 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 email to supervisor! %s" % (self,)
def save(self, *args, **kwargs): if Faculty.objects.filter(id=self.id).count(): raise ValidationError('Cannot have someone be a student AND faculty!') self.cache_cohorts() if self.inactive == True 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) user, created = User.objects.get_or_create(username=self.username) if created: user.password = "******" user.save() group, gcreated = Group.objects.get_or_create(name="students") user.groups.add(group)
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 save(self, *args, **kwargs): if not self.id: new = True else: new = False super(ReferralForm, self).save(*args, **kwargs) if new: try: subject = 'New counseling referral for %s.' % (self.student, ) msg = '%s has submitted a counseling referral form for %s. Click this link to view \n%s%s' % \ (self.referred_by,self.student,settings.BASE_URL,reverse('admin:counseling_referralform_change',args=(self.id,)),) from_addr = Configuration.get_or_default( "From Email Address", "*****@*****.**").value to_addr = Configuration.get_or_default( "counseling_referral_notice_email_to", "").value.split(',') if to_addr: send_mail(subject, msg, from_addr, to_addr) except: logging.error('Couldn\'t email counseling referral form', exc_info=True)
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 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 fte_by_day(request): fileName = "report_fteByDay.xls" 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 = xlsReport(names, titles, fileName, heading="FTE by Day of Week") report.addSheet(student_company_day_report(), heading="Detail") return report.finish()
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 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( settings.BASE_URL, reverse('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.split(','))
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 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: print addr 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( settings.BASE_URL, reverse('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 build_schedule(self, student, marking_period, include_asp=False): """ 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() days = [] arr_days = [] for day in CourseMeet.day_choice: if course_meets.filter(day=day[0]).count(): days.append(day[1]) arr_days.append(day) for period in periods: period.days = [] for day in arr_days: if Configuration.get_or_default("Only Active Classes in Schedule", "False").value == "True" \ or Configuration.get_or_default("Only Active Classes in Schedule", "False").value == "true" \ or Configuration.get_or_default("Only Active Classes in Schedule", "False").value == "T": 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]) else: period.days.append(None) CourseMeet.objects.filter( course__courseenrollment__user=student, course__marking_period=marking_period, ).distinct() return days, periods
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() if date_report: cursor.execute("SELECT (SUM(grade * weight) / sum(weight)) 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 AND schedule_markingperiod.end_date <= %s) and (grade is not null or letter_grade is not null ) ORDER BY `grades_grade`.`override_final` DESC limit 1", (self.course_id, self.user_id, date_report) ) else: cursor.execute("SELECT (SUM(grade * weight) / sum(weight)) AS `ave_grade`, `grades_grade`.`id`, `grades_grade`.`override_final` FROM `grades_grade` left join schedule_markingperiod on schedule_markingperiod.id=marking_period_id WHERE (`grades_grade`.`course_id` = %s AND `grades_grade`.`student_id` = %s ) and (grade is not null or letter_grade is not null ) ORDER BY `grades_grade`.`override_final` DESC limit 1", (self.course_id, self.user_id) ) (ave_grade, grade_id, override_final) = cursor.fetchone() if override_final: course_grades = ecwsp.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: return ave_grade.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) # 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"]: 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 calculate_final_grade(self, student, date_report=None): """ Calculates final grade. Note that this should match recalc_ytd_grade in gradesheet.js! """ if 'ecwsp.grades' in settings.INSTALLED_APPS: from ecwsp.grades.models import Grade final = Grade.objects.filter(course=self, override_final=True, student=student) if final: if not date_report or final[0].course.marking_period.filter(end_date__lte=date_report).count(): return final[0].get_grade() final = Decimal(0) number = 0 letter_grade = False grades = Grade.objects.filter(student=student, course=self, marking_period__course=self) if date_report: grades = grades.filter(marking_period__end_date__lte=date_report) total_weight = Decimal(0) for grade in grades: try: final += Decimal(grade.get_grade()) * grade.marking_period.weight number += 1 total_weight += grade.marking_period.weight # otherwise it's a letter grade. except: # 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 * grade.marking_period.weight number += 1 letter_grade = True total_weight += grade.marking_period.weight elif grade.get_grade() in ['F', 'M']: number += 1 letter_grade = True total_weight += grade.marking_period.weight if final is not None and total_weight: final /= total_weight if number != 0: 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 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 email to supervisor! %s" % ( self, )
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 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 email mentors"
def fte_by_day(request): fileName = "report_fteByDay.xls" 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 = xlsReport(names, titles, fileName, heading="FTE by Day of Week") report.addSheet(student_company_day_report(), heading="Detail") return report.finish()
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 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 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 send_email_approval(self): """ Send email to supervisor for approval """ if not self.site_supervisor or not self.site_supervisor.email: return None try: sendTo = self.site_supervisor.email subject = "Volunteer hours approval for " + unicode(self.student) msg = "Hello " + unicode(self.site_supervisor.name) + ",\nPlease click on the link below to approve the time sheet\n" + \ settings.BASE_URL + "/volunteer_tracker/approve?key=" + str(self.secret_key) from_addr = Configuration.get_or_default("From Email Address", "*****@*****.**").value send_mail(subject, msg, from_addr, [sendTo]) except: logging.warning("Unable to send email to volunteer's supervisor! %s" % (self,), exc_info=True)