private List <AssessmentClassScoreDetail> GetFinalAssessmentRecordAfterStudentMerging(List <AssessmentClassScoreDetail> existingAssessmentClassScoreDetails, List <StudentAndAssessmentType> allStudentsAssessmentTypesInAllTerms, List <int> studentIdsWithoutAssessmentScoreInCurrentTerm, List <SchoolTermAssessment> schoolTermAssessments)
        {
            studentIdsWithoutAssessmentScoreInCurrentTerm.ForEach(studentId =>
            {
                var student = allStudentsAssessmentTypesInAllTerms.First(s => s.StudentId == studentId);
                var newAssessmentScoreClassDetial = new AssessmentClassScoreDetail
                {
                    LastName         = student.LastName,
                    StudentId        = student.StudentId,
                    StudentName      = student.StudentName,
                    ReportTemplateId = student.ReportTemplateId
                };

                //new student score record should contain all the scoreData columns with empty/null data except gradeLevel
                var maximumAssessmentCount = existingAssessmentClassScoreDetails.Count > 0
                                             ? existingAssessmentClassScoreDetails[0].ScoreDataCollection.Count
                                             : allStudentsAssessmentTypesInAllTerms.Select(x => x.AssessmentTypeId).Distinct().Count();
                for (int i = 0; i < maximumAssessmentCount; i++)
                {
                    //set a default value of the id, code and gradeLevel
                    var referenceScoreData = new ClassScoreData {
                        AssessmentId = 0, AssessmentCode = allStudentsAssessmentTypesInAllTerms[i].AssessmentCode, GradeLevel = allStudentsAssessmentTypesInAllTerms[i].GradeLevel
                    };
                    //incase records already exists, then use id and code from one of the existing record
                    if (existingAssessmentClassScoreDetails.Count > 0)
                    {
                        referenceScoreData.AssessmentId   = existingAssessmentClassScoreDetails[0].ScoreDataCollection[i].AssessmentId;
                        referenceScoreData.AssessmentCode = existingAssessmentClassScoreDetails[0].ScoreDataCollection[i].AssessmentCode;
                        referenceScoreData.ScoreMin       = existingAssessmentClassScoreDetails[0].ScoreDataCollection[i].ScoreMin;
                        referenceScoreData.ScoreMax       = existingAssessmentClassScoreDetails[0].ScoreDataCollection[i].ScoreMax;
                        referenceScoreData.GradeLevel     = existingAssessmentClassScoreDetails[0].ScoreDataCollection[i].GradeLevel;
                    }
                    // if no reord found in existing record, then use assessmentId, ScoreMin and ScoreMax from Assessments found for a searched school term.
                    else if (schoolTermAssessments.Count > 0)
                    {
                        var assessmentExist = schoolTermAssessments.Find(sa => sa.AssessmentTypeId == allStudentsAssessmentTypesInAllTerms[i].AssessmentTypeId);
                        if (assessmentExist != null)
                        {
                            referenceScoreData.AssessmentId = assessmentExist.AssessmentId;
                            referenceScoreData.ScoreMin     = assessmentExist.ScoreMin;
                            referenceScoreData.ScoreMax     = assessmentExist.ScoreMax;
                        }
                    }
                    var newScoreData = new ClassScoreData
                    {
                        Score          = null,
                        Projection     = null,
                        AssessmentId   = referenceScoreData.AssessmentId,
                        AssessmentCode = referenceScoreData.AssessmentCode,
                        StudentId      = student.StudentId,
                        ScoreMin       = referenceScoreData.ScoreMin,
                        ScoreMax       = referenceScoreData.ScoreMax,
                        GradeLevel     = referenceScoreData.GradeLevel
                    };
                    newAssessmentScoreClassDetial.ScoreDataCollection.Add(newScoreData);
                }
                //finally append the new record to existing result
                existingAssessmentClassScoreDetails.Add(newAssessmentScoreClassDetial);
            });
            return(existingAssessmentClassScoreDetails);
        }
        public List <AssessmentClassScoreDetail> GetExistingClassAssessmentScoreData(int districtId, AssessmentClassScoreViewModel model)
        {
            List <AssessmentClassScoreDetail> results = new List <AssessmentClassScoreDetail>();
            SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);

            connection.Open();
            SqlCommand command = new SqlCommand("spGetClassAssessmentScore", connection);

            command.CommandType = System.Data.CommandType.StoredProcedure;
            command.Parameters.Add(new SqlParameter("@AssessmentTypeId", int.Parse(model.AssessmentTypeId)));
            command.Parameters.Add(new SqlParameter("@SubjectId", int.Parse(model.SubjectID)));
            command.Parameters.Add(new SqlParameter("@SchoolYearId", int.Parse(model.SchoolYearId)));
            command.Parameters.Add(new SqlParameter("@ClassID", int.Parse(model.ClassId)));
            command.Parameters.Add(new SqlParameter("@SchoolTermId", int.Parse(model.SchoolTermId)));
            SqlDataReader reader = command.ExecuteReader();
            AssessmentClassScoreDetail tempScoreDetail = null;
            int prevStudent     = -1;
            int assessmentIndex = 0; //its range is [0:4]

            while (reader.Read())
            {
                var currentStudentId = Convert.ToInt32(reader["StudentId"]);
                if (prevStudent != currentStudentId)
                {
                    prevStudent = currentStudentId;
                    if (tempScoreDetail != null)
                    {
                        //creating new row
                        tempScoreDetail.AssessmentCount = assessmentIndex;
                        results.Add(tempScoreDetail);
                        assessmentIndex = 0;
                    }

                    tempScoreDetail                  = new AssessmentClassScoreDetail();
                    tempScoreDetail.StudentId        = currentStudentId;
                    tempScoreDetail.StudentName      = reader["StudentName"].ToString();
                    tempScoreDetail.LastName         = reader["LastName"].ToString();
                    tempScoreDetail.ReportTemplateId = int.Parse(reader["ReportTemplateId"].ToString());
                }

                decimal?score      = null;
                decimal?projection = null;
                int     assessmentId;
                int     assessmentTypeId;
                int     assessmentScoreId;
                string  assessmentDesc = null;
                string  assessmentCode = null;
                int?    scoreMin;
                int?    scoreMax;
                int     schoolTermId;
                int?    gradeLevel;

                SetClassAssessmentScoreData(out score, out projection, out assessmentId, out assessmentTypeId, out assessmentDesc, out assessmentCode, out assessmentScoreId, out scoreMin, out scoreMax, out schoolTermId, out gradeLevel, reader);
                try
                {
                    //for N assessment column, the record will contain N ScoreData objects in the ScoreDatacollection
                    var propertyIndex = assessmentIndex + 1;
                    var scoreData     = new ClassScoreData();
                    tempScoreDetail.ScoreDataCollection.Add(scoreData);

                    scoreData.RoundingType      = HelperService.GetDecimalDisplayFormat(RoundingType.NoDecimalPlace);
                    scoreData.Score             = score;
                    scoreData.Projection        = projection;
                    scoreData.AssessmentDesc    = assessmentDesc;
                    scoreData.AssessmentId      = assessmentId;
                    scoreData.AssessmentTypeId  = assessmentTypeId;
                    scoreData.AssessmentCode    = assessmentCode;
                    scoreData.AssessmentScoreId = assessmentScoreId;
                    scoreData.ScoreMin          = scoreMin;
                    scoreData.ScoreMax          = scoreMax;
                    scoreData.SchoolTermId      = schoolTermId;
                    scoreData.StudentId         = currentStudentId;
                    scoreData.GradeLevel        = gradeLevel;
                }
                catch (Exception ex)
                {
                    throw new Exception("Check if field exists belongs to correct assessment", ex);
                }
                assessmentIndex++;
            }
            if (tempScoreDetail != null)
            {
                tempScoreDetail.AssessmentCount = assessmentIndex;
                results.Add(tempScoreDetail);
            }
            reader.Close();
            connection.Close();
            return(results);
        }
        private List <AssessmentClassScoreDetail> GetFinalAssessmentRecordAfterAssessmentMerging(List <AssessmentClassScoreDetail> existingAssessmentClassScoreDetails, List <StudentAndAssessmentType> allStudentsAssessmentTypesInAllTerms, List <SchoolTermAssessment> schoolTermAssessments)
        {
            try
            {
                //Sort by score data count to get maximum score records on top.
                existingAssessmentClassScoreDetails = existingAssessmentClassScoreDetails.OrderByDescending(sd => sd.ScoreDataCollection.Count()).ToList();

                AssessmentClassScoreDetail previousRecord = null;
                existingAssessmentClassScoreDetails.ForEach(record =>
                {
                    allStudentsAssessmentTypesInAllTerms.ForEach(assessmentType =>
                    {
                        var isAssessmentTypeAlreadyExistInRecord = record.ScoreDataCollection.Exists(sd => sd.AssessmentTypeId == assessmentType.AssessmentTypeId);
                        if (!isAssessmentTypeAlreadyExistInRecord)
                        {
                            var newScoreData = new ClassScoreData();
                            newScoreData.AssessmentTypeId = assessmentType.AssessmentTypeId;
                            newScoreData.AssessmentCode   = assessmentType.AssessmentCode;
                            newScoreData.ScoreMin         = assessmentType.ScoreMin;
                            newScoreData.ScoreMax         = assessmentType.ScoreMax;
                            newScoreData.GradeLevel       = assessmentType.GradeLevel;
                            newScoreData.StudentId        = record.StudentId;
                            newScoreData.AssessmentId     = 0;
                            //For assessment type who don't have score data for all records get assessmentId, ScoreMin and ScoreMax from previous record.
                            if (previousRecord != null)
                            {
                                var previousRecordWithSameAssessmentType = previousRecord.ScoreDataCollection.Find(sd => sd.AssessmentTypeId == assessmentType.AssessmentTypeId);
                                if (previousRecordWithSameAssessmentType != null)
                                {
                                    newScoreData.AssessmentId = previousRecordWithSameAssessmentType.AssessmentId;
                                    newScoreData.ScoreMin     = previousRecordWithSameAssessmentType.ScoreMin;
                                    newScoreData.ScoreMax     = previousRecordWithSameAssessmentType.ScoreMax;
                                }
                            }
                            else if (schoolTermAssessments.Count > 0)
                            {
                                var assessmentExist = schoolTermAssessments.Find(sa => sa.AssessmentTypeId == assessmentType.AssessmentTypeId);
                                if (assessmentExist != null)
                                {
                                    newScoreData.AssessmentId = assessmentExist.AssessmentId;
                                    newScoreData.ScoreMin     = assessmentExist.ScoreMin;
                                    newScoreData.ScoreMax     = assessmentExist.ScoreMax;
                                }
                            }
                            record.ScoreDataCollection.Add(newScoreData);
                        }
                    });
                    previousRecord = record;
                });

                existingAssessmentClassScoreDetails.ForEach(record =>
                {
                    var sortedScoreDataList    = record.ScoreDataCollection.OrderBy(x => x.AssessmentTypeId).ToList();
                    record.ScoreDataCollection = sortedScoreDataList;
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return(existingAssessmentClassScoreDetails);
        }