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);
                }
            }
        }