public AverageAttendanceRateChartGenerator(string InternalConnectionString, ChartJob Options) { this.Title = "Average attendance rate"; this.SubTitle = Options.StartDate.ToShortDateString() + " to " + Options.EndDate.ToShortDateString(); // Load all schools InternalSchoolRepository _schoolRepo = new InternalSchoolRepository(InternalConnectionString); InternalStudentRepository _studentRepo = new InternalStudentRepository(InternalConnectionString); InternalStudentSchoolEnrolmentRepository _schoolStatusRepo = new InternalStudentSchoolEnrolmentRepository(InternalConnectionString); InternalStudentAttendanceRateRepository _attendanceRateRepo = new InternalStudentAttendanceRateRepository(InternalConnectionString, Options.StartDate, Options.EndDate); InternalSchoolRepository schoolRepo = new InternalSchoolRepository(InternalConnectionString); // Determine limiting schools (if any) List <int> limitediSchoolIDs = new List <int>(); if (Options.LimitSchools.Count > 0) { limitediSchoolIDs = Options.LimitSchools; } else { limitediSchoolIDs = schoolRepo.GetAllKnownSchoolIDs(); } ChartData = new List <BarChartDataSeries>(); // Generate some data points foreach (School school in _schoolRepo.GetAll().Where(x => !_schoolGovIDBlacklist.Contains(x.GovernmentID) && limitediSchoolIDs.Contains(x.iSchoolID))) { // Load school students List <Student> schoolStudents = _studentRepo.Get(_schoolStatusRepo.GetStudentIDsEnrolledOn(Options.StartDate, Options.EndDate, school.iSchoolID, true)); // Skip schools that have no students if (schoolStudents.Count == 0) { continue; } // Calculate each student's attendance rate for the given time period // Throw out rates that are -1, because they are invalid // Keep a running tally of all attendance rates, and of those from first nations students List <decimal> attendanceRatesAllStudents = new List <decimal>(); foreach (Student s in schoolStudents) { StudentAttendanceRate sar = _attendanceRateRepo.GetForStudent(s.iStudentID, Options.StartDate, Options.EndDate); decimal attendanceRate = sar.GetAttendanceRate(Options.StartDate, Options.EndDate); if (attendanceRate != -1) { attendanceRatesAllStudents.Add(attendanceRate); } } if (attendanceRatesAllStudents.Count == 0) { continue; } BarChartDataSeries schoolGraphData = new BarChartDataSeries() { Label = school.ShortName }; if (attendanceRatesAllStudents.Count > 0) { decimal averageAttendanceRate = attendanceRatesAllStudents.Average(); schoolGraphData.DataPoints.Add(new BarChartPercentBar() { Value = averageAttendanceRate, Label = (averageAttendanceRate * 100).ToString("0.##") + "%", ID = 0 }); } if (schoolGraphData.DataPoints.Count > 0) { this.ChartData.Add(schoolGraphData); } } }
public FNMTargetAttendanceRateChartGenerator(string InternalConnectionString, ChartJob Options) { this.Title = "% Students with at least " + ((decimal)Options.TargetAttendanceRate * 100).ToString("0") + "% Attendance Rate"; this.SubTitle = Options.StartDate.ToShortDateString() + " to " + Options.EndDate.ToShortDateString(); // Load all schools InternalSchoolRepository _schoolRepo = new InternalSchoolRepository(InternalConnectionString); InternalStudentRepository _studentRepo = new InternalStudentRepository(InternalConnectionString); InternalStudentSchoolEnrolmentRepository _schoolStatusRepo = new InternalStudentSchoolEnrolmentRepository(InternalConnectionString); InternalStudentAttendanceRateRepository _attendanceRateRepo = new InternalStudentAttendanceRateRepository(InternalConnectionString, Options.StartDate, Options.EndDate); InternalSchoolRepository schoolRepo = new InternalSchoolRepository(InternalConnectionString); // Determine limiting schools (if any) List <int> limitediSchoolIDs = new List <int>(); if (Options.LimitSchools.Count > 0) { limitediSchoolIDs = Options.LimitSchools; } else { limitediSchoolIDs = schoolRepo.GetAllKnownSchoolIDs(); } ChartData = new List <BarChartDataSeries>(); // Set up the legend Legend = new Dictionary <int, string>() { { 0, "Non First-Nations Students" }, { 1, "First-Nations Students" } }; // Generate some data points foreach (School school in _schoolRepo.GetAll().Where(x => !_schoolGovIDBlacklist.Contains(x.GovernmentID))) { // Load school students List <Student> schoolStudents = _studentRepo.Get(_schoolStatusRepo.GetStudentIDsEnrolledOn(Options.StartDate, Options.EndDate, school.iSchoolID, true)); // Skip schools that have no students if (schoolStudents.Count == 0) { continue; } // Calculate each student's attendance rate for the given time period // Throw out rates that are -1, because they are invalid // Keep a running tally of all attendance rates, and of those from first nations students List <decimal> attendanceRatesNonFNM = new List <decimal>(); List <decimal> attendanceRatesFNM = new List <decimal>(); foreach (Student s in schoolStudents) { StudentAttendanceRate sar = _attendanceRateRepo.GetForStudent(s.iStudentID, Options.StartDate, Options.EndDate); decimal attendanceRate = sar.GetAttendanceRate(Options.StartDate, Options.EndDate); if (attendanceRate != -1) { if (s.IsFirstNations) { attendanceRatesFNM.Add(attendanceRate); } else { attendanceRatesNonFNM.Add(attendanceRate); } } } BarChartDataSeries schoolGraphData = new BarChartDataSeries() { Label = school.ShortName }; try { decimal nonFNMAttendanceRate = (decimal)((decimal)attendanceRatesNonFNM.Count(x => x >= Options.TargetAttendanceRate) / (decimal)attendanceRatesNonFNM.Count()); schoolGraphData.DataPoints.Add(new BarChartPercentBar() { Value = nonFNMAttendanceRate, Label = (nonFNMAttendanceRate * 100).ToString("0.##") + "%", ID = 0 }); } catch {/* * schoolGraphData.DataPoints.Add(new BarChartPercentBar() * { * Value = 0, * Label = "Unknown", * ID = 0 * }); */ } try { decimal fnmAttendanceRate = (decimal)((decimal)attendanceRatesFNM.Count(x => x >= Options.TargetAttendanceRate) / (decimal)attendanceRatesFNM.Count()); schoolGraphData.DataPoints.Add(new BarChartPercentBar() { Value = fnmAttendanceRate, Label = (fnmAttendanceRate * 100).ToString("0.##") + "%", ID = 1 }); } catch {/* * schoolGraphData.DataPoints.Add(new BarChartPercentBar() * { * Value = 0, * Label = "Unknown", * ID = 1 * });*/ } if (schoolGraphData.DataPoints.Count > 0) { this.ChartData.Add(schoolGraphData); } } }
public static void Sync(ConfigFile configFile, LogDelegate Log) { ConfigFileSyncPermissionsSection config = configFile.StudentPermissions; Log("========= STUDENTS ========= "); if (!config.AllowSync) { Log("This sync module is disabled in config file - skipping"); return; } SLStudentRepository externalRepository = new SLStudentRepository(configFile.DatabaseConnectionString_SchoolLogic); InternalStudentRepository internalRepository = new InternalStudentRepository(configFile.DatabaseConnectionString_Internal); List <Student> externalObjects = externalRepository.GetAll(); List <Student> previouslyUnknown = new List <Student>(); List <Student> needingUpdate = new List <Student>(); List <Student> noLongerExistsInExternalSystem = new List <Student>(); int doneCount = 0; int totalExternalObjects = externalObjects.Count(); decimal donePercent = 0; decimal doneThresholdPercent = (decimal)0.1; decimal doneThresholdIncrease = (decimal)0.1; foreach (Student externalObject in externalObjects) { // Objects we don't have in the database Student internalObject = internalRepository.Get(externalObject.iStudentID); if (internalObject == null) { previouslyUnknown.Add(externalObject); } // Objects requiring update if (internalObject != null) { UpdateCheck check = internalObject.CheckIfUpdatesAreRequired(externalObject); if ((check == UpdateCheck.UpdatesRequired) || (config.ForceUpdate)) { needingUpdate.Add(externalObject); } } doneCount++; donePercent = (decimal)((decimal)doneCount / (decimal)totalExternalObjects); if (donePercent > doneThresholdPercent) { doneThresholdPercent = doneThresholdPercent + doneThresholdIncrease; Log((int)(donePercent * 100) + "% finished inspecting objects"); } if (doneCount == totalExternalObjects) { Log("100% finished inspecting objects"); } } // Objects in the internal database that aren't in the external database if (config.AllowRemovals) { List <int> foundIDs = externalRepository.GetAllIDs(); foreach (Student internalObject in internalRepository.GetAll()) { if (!foundIDs.Contains(internalObject.iStudentID)) { noLongerExistsInExternalSystem.Add(internalObject); } } } Log("Found " + internalRepository.GetAll().Count() + " students in internal database"); Log("Found " + externalObjects.Count() + " students in external database"); Log("Found " + previouslyUnknown.Count() + " previously unknown"); Log("Found " + needingUpdate.Count() + " with updates"); Log("Found " + noLongerExistsInExternalSystem.Count() + " not in external database"); // Commit these changes to the database if (previouslyUnknown.Count > 0) { if (config.AllowAdds) { Log(" > Adding " + previouslyUnknown.Count() + " new objects"); internalRepository.Add(previouslyUnknown); } else { Log(" > Not allowed to add, skipping " + previouslyUnknown.Count() + " adds"); } } if (needingUpdate.Count > 0) { if (config.AllowUpdates) { Log(" > Updating " + needingUpdate.Count() + " objects"); internalRepository.Update(needingUpdate); } else { Log(" > Not allowed to do updates, skipping " + needingUpdate.Count() + " updates"); } } if (noLongerExistsInExternalSystem.Count > 0) { if (config.AllowRemovals) { Log(" > If removals were implemented, we would remove " + noLongerExistsInExternalSystem.Count() + " objects here"); } else { Log(" > Not allowed to remove, skipping " + noLongerExistsInExternalSystem.Count() + " removals"); } } }
public SchoolYearTargetAttendanceChartGenerator(string InternalConnectionString, ChartJob Options) { this.Title = "% Students with at least " + ((decimal)Options.TargetAttendanceRate * 100).ToString("0") + "% Attendance Rate"; this.SubTitle = Options.StartDate.ToShortDateString() + " to " + Options.EndDate.ToShortDateString(); this.ShowValuesInChart = true; // Labels / Data points will be one for each month this.Lines = new List <LineChartLine>(); // DATA NEEDED FOR THIS REPORT // - Load all enrolled students // - For each month within the specified date range, calculate every student's attendance rate // - Find the final values for each month // This chart is done by the School Year, not arbitrary dates InternalStudentRepository studentRepo = new InternalStudentRepository(InternalConnectionString); InternalStudentSchoolEnrolmentRepository schoolEnrolmentRepo = new InternalStudentSchoolEnrolmentRepository(InternalConnectionString); InternalStudentAttendanceRateRepository attendanceRateRepo = new InternalStudentAttendanceRateRepository(InternalConnectionString, Options.StartDate, Options.EndDate); InternalSchoolRepository schoolRepo = new InternalSchoolRepository(InternalConnectionString); // Determine limiting schools (if any) List <int> limitediSchoolIDs = new List <int>(); if (Options.LimitSchools.Count > 0) { limitediSchoolIDs = Options.LimitSchools; List <string> schoolNames = schoolRepo.Get(limitediSchoolIDs).Select(x => x.Name).ToList <string>(); this.SubSubTitle = this.SubTitle; this.SubTitle = schoolNames.ToCommaSeparatedString(); } else { limitediSchoolIDs = schoolRepo.GetAllKnownSchoolIDs(); } LineChartLine fnmStudentsLine = new LineChartLine() { Label = "FNM Students" }; LineChartLine nonFNMStudentsLine = new LineChartLine() { Label = "Non-FNM Students" }; // Find the school year that the specified dates fit into // If the dates span into two or more school years, use the first one detected // The chart will always start at the beginning of the school year and end at the end of the school year int schoolYear = ReturnLower(Parsers.FindSchoolYear(Options.StartDate), Parsers.FindSchoolYear(Options.EndDate)); List <ChartMonth> schoolYears = new List <ChartMonth>() { new ChartMonth { Label = "AUG", Starts = new DateTime(schoolYear, 8, 1), Ends = new DateTime(schoolYear, 8, DateTime.DaysInMonth(schoolYear, 8)) }, new ChartMonth { Label = "SEP", Starts = new DateTime(schoolYear, 9, 1), Ends = new DateTime(schoolYear, 9, DateTime.DaysInMonth(schoolYear, 9)) }, new ChartMonth { Label = "OCT", Starts = new DateTime(schoolYear, 10, 1), Ends = new DateTime(schoolYear, 10, DateTime.DaysInMonth(schoolYear, 10)) }, new ChartMonth { Label = "NOV", Starts = new DateTime(schoolYear, 11, 1), Ends = new DateTime(schoolYear, 11, DateTime.DaysInMonth(schoolYear, 11)) }, new ChartMonth { Label = "DEC", Starts = new DateTime(schoolYear, 12, 1), Ends = new DateTime(schoolYear, 12, DateTime.DaysInMonth(schoolYear, 12)) }, new ChartMonth { Label = "JAN", Starts = new DateTime(schoolYear + 1, 1, 1), Ends = new DateTime(schoolYear + 1, 1, DateTime.DaysInMonth(schoolYear + 1, 1)) }, new ChartMonth { Label = "FEB", Starts = new DateTime(schoolYear + 1, 2, 1), Ends = new DateTime(schoolYear + 1, 2, DateTime.DaysInMonth(schoolYear + 1, 2)) }, new ChartMonth { Label = "MAR", Starts = new DateTime(schoolYear + 1, 3, 1), Ends = new DateTime(schoolYear + 1, 3, DateTime.DaysInMonth(schoolYear + 1, 3)) }, new ChartMonth { Label = "APR", Starts = new DateTime(schoolYear + 1, 4, 1), Ends = new DateTime(schoolYear + 1, 4, DateTime.DaysInMonth(schoolYear + 1, 4)) }, new ChartMonth { Label = "MAY", Starts = new DateTime(schoolYear + 1, 5, 1), Ends = new DateTime(schoolYear + 1, 5, DateTime.DaysInMonth(schoolYear + 1, 5)) }, new ChartMonth { Label = "JUN", Starts = new DateTime(schoolYear + 1, 6, 1), Ends = new DateTime(schoolYear + 1, 6, DateTime.DaysInMonth(schoolYear + 1, 6)) }, new ChartMonth { Label = "JUL", Starts = new DateTime(schoolYear + 1, 7, 1), Ends = new DateTime(schoolYear + 1, 7, DateTime.DaysInMonth(schoolYear + 1, 7)) }, }; this.Labels = schoolYears.Select(x => x.Label).ToList(); foreach (ChartMonth month in schoolYears) { // Check to see if this month falls within the specified time period // If it doesn't, skip it if (month.Starts > Options.EndDate) { continue; } if (month.Ends < Options.StartDate) { continue; } // Clamp the start and end dates to the start and end dates specified if (month.Starts < Options.StartDate) { month.Starts = Options.StartDate; } if (month.Ends > Options.EndDate) { month.Ends = Options.EndDate; } // If the month is the current month, cap the end date at today, because future data won't exist yet if ((month.Starts.Month == DateTime.Today.Month) && (month.Starts.Year == DateTime.Today.Year)) { if (month.Ends > DateTime.Today) { month.Ends = DateTime.Today; } } decimal dataPointThisMonth_NonFNM = (decimal) - 1.0; decimal dataPointThisMonth_FNM = (decimal) - 1.0; // Now, load all the enrolled students during the start and end of the month // and calculate their average attendances List <Student> enrolledStudentsThisMonth = studentRepo.Get(schoolEnrolmentRepo.GetStudentIDsEnrolledOn(month.Starts, month.Ends, limitediSchoolIDs, true)); if (enrolledStudentsThisMonth.Count == 0) { continue; } List <decimal> attendanceRatesNonFNM = new List <decimal>(); List <decimal> attendanceRatesFNM = new List <decimal>(); foreach (Student s in enrolledStudentsThisMonth) { StudentAttendanceRate sar = attendanceRateRepo.GetForStudent(s.iStudentID, month.Starts, month.Ends); decimal attendanceRate = sar.GetAttendanceRate(month.Starts, month.Ends); if (attendanceRate != -1) { if (s.IsFirstNations) { attendanceRatesFNM.Add(attendanceRate); } else { attendanceRatesNonFNM.Add(attendanceRate); } } } // Now, find the number of the rates that are greater than or equal to the target try { dataPointThisMonth_NonFNM = (decimal)((decimal)attendanceRatesNonFNM.Count(x => x > Options.TargetAttendanceRate) / (decimal)attendanceRatesNonFNM.Count()); } catch { } try { dataPointThisMonth_FNM = (decimal)((decimal)attendanceRatesFNM.Count(x => x > Options.TargetAttendanceRate) / (decimal)attendanceRatesFNM.Count()); } catch { } // Add the data point to the line if (dataPointThisMonth_NonFNM > -1) { nonFNMStudentsLine.LineDataPoints.Add(month.Label, dataPointThisMonth_NonFNM); } if (dataPointThisMonth_FNM > -1) { fnmStudentsLine.LineDataPoints.Add(month.Label, dataPointThisMonth_FNM); } } // Finally, add the lines to the chart this.Lines.Add(nonFNMStudentsLine); this.Lines.Add(fnmStudentsLine); }