public static Tuple <Tuple <int, string>[], Enrolment[]> enrol(IEnumerable <Tuple <Student, Subject> > studentSubjects, Enrolment[] enrolments, EnrolmentConfig c,
                                                                       Func <Student, Subject, IEnumerable <Enrolment>, EnrolmentConfig, Tuple <int, string> > isValidEnrolment)
        {
            var es  = new List <Enrolment>(enrolments);
            var log = new List <Tuple <int, string> >();

            foreach (var s in studentSubjects)
            {
                var result = isValidEnrolment(s.Item1, s.Item2, es, c);

                if (result.Item1 == 0)
                {
                    es.Add(new Enrolment()
                    {
                        StudentNumber = s.Item1.StudentNumber, SubjectName = s.Item2.Name
                    });
                    log.Add(new Tuple <int, string>(result.Item1, String.Format("Student with Student number {0} was successfully enroled in subject {1}",
                                                                                s.Item1.StudentNumber, s.Item2.Name)));
                }
                else
                {
                    log.Add(result);
                }
            }

            return(new Tuple <Tuple <int, string>[], Enrolment[]>(log.ToArray(), es.ToArray()));
        }
 public static Tuple <Tuple <int, string>[], Enrolment[]> enrol(IEnumerable <Tuple <Student, Subject> > studentSubjects, Enrolment[] enrolments, EnrolmentConfig c)
 {
     return(enrol(studentSubjects, enrolments, c, EnrolmentValidator.isValidEnrolment));
 }
        public static Tuple <int, string> isValidEnrolment(Student student, Subject subject, IEnumerable <Enrolment> es, EnrolmentConfig c)
        {
            // Validation Rule 1 - Students have an entrance ranking between 0 and 100``
            if (student.Ranking < 0 || student.Ranking > 100)
            {
                return(new Tuple <int, string>(1, string.Format("Student {0} has an invalid entrance ranking, the value must between between 0 and 100)", student.StudentNumber)));
            }

            var enroledStudents = es.Where(e => e.SubjectName == subject.Name).Count();

            // Validation Rule 2 - All subjects must be below the max student size
            if (enroledStudents >= subject.MaxSubjectSize)
            {
                return(new Tuple <int, string>(2, string.Format("Can't enrol {0} because the maximum number of enrolments has been reached, the maximum students for the subject {1} is {2}",
                                                                student.StudentNumber, subject.Name, subject.MaxSubjectSize)));
            }
            var percentageFull = (Convert.ToDouble(enroledStudents) / Convert.ToDouble(subject.MaxSubjectSize)) * 100.0;

            // Validation Rule 3 - When programming subjects reach a given percentage capacity then only students are accepted with certain rankings.
            if (subject.SubjectType == SubjectTypeEnum.Programming && percentageFull >= c.ValidationRule3_PercentageCapacity && student.Ranking < c.ValidationRule3_AcceptedRanking)
            {
                return(new Tuple <int, string>(3, string.Format("Can't enrol {0} because when programming subjects are more than {1}% full, " +
                                                                "the student's entrance ranking must be greater than {2} for them to be accepted.",
                                                                student.StudentNumber, c.ValidationRule3_PercentageCapacity, c.ValidationRule3_AcceptedRanking)));
            }

            // Validation Rule 4 - When design subjects reach a given percentage capacity, only international students will be accepted.
            if (subject.SubjectType == SubjectTypeEnum.Design && percentageFull >= c.ValidationRule4_PercentageCapacity && student.IsInternationalStudent == false)
            {
                return(new Tuple <int, string>(4, String.Format("Can't enrol {0} because when design subjects are more than {1}% full, only international students will be accepted.",
                                                                student.StudentNumber, c.ValidationRule4_PercentageCapacity)));
            }

            // Validation Rule 5 - When literature subjects reach a given percentage capacity, people on scholarships will no longer be accepted``
            if (subject.SubjectType == SubjectTypeEnum.Literature && percentageFull >= c.ValidationRule5_PercentageCapacity && student.HasScholarship == true)
            {
                return(new Tuple <int, string>(5, String.Format("Can't enrol {0} because when design subjects are more than {1}% full, only international students will be accepted.",
                                                                student.StudentNumber, c.ValidationRule5_PercentageCapacity)));
            }

            return(new Tuple <int, string>(0, ""));
        }