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");
                }
            }
        }
示例#4
0
        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);
        }