using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using Bowin.Common.Linq;
using Bowin.Common.Linq.Entity;
using EMIS.ViewModel.DQPSystem;
using EMIS.ViewModel;
using EMIS.DataLogic.DQPSystem;
using EMIS.Entities;
using System.Transactions;
using EMIS.Utility.FormValidate;
using EMIS.CommonLogic.SystemServices;
using EMIS.DataLogic.Common.Students;
using EMIS.ViewModel.Students;
using EMIS.ViewModel.SystemView;
using EMIS.DataLogic.SystemDAL;
using EMIS.Utility;

namespace EMIS.CommonLogic.DQPSystem
{
    public class SOCDetailScoreServices : BaseServices, ISOCDetailScoreServices, IFileUploadServices
    {
        public SOCDetailScoreDAL SOCDetailScoreDAL { get; set; }
        public StudentsDAL StudentsDAL { get; set; }
        public AnnouncementDAL AnnouncementDAL { get; set; }
        public IRoleServices RoleServices { get; set; }

        public IGridResultSet<SOCDetailStudentScoreView> GetSOCDetailStudentScoreViewList(ConfiguretView studentScoreConditionView, Guid? schoolyearID,
            Guid? collegeID, int? year, int? standardID, Guid? classmajorID, Guid? coursematerialID, int? recordStatus, int? pageIndex, int? pageSize)
        {
            var userID = CustomPrincipal.Current.UserID;
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE); 
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true); 
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);

            if (schoolyearID.HasValue)
            {
                socExp = socExp.And(x => x.SchoolyearID == schoolyearID);
            }
            if (collegeID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.CollegeID == collegeID);
            }
            if (year.HasValue)
            {
                gradeExp = gradeExp.And(x => x.GradeID == year);
            }
            if (standardID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.StandardID == standardID);
            }
            if (classmajorID.HasValue)
            {
                classExp = classExp.And(x => x.ClassmajorID == classmajorID);
            }
            if (coursematerialID.HasValue)
            {
                socExp = socExp.And(x => x.CoursematerialID == coursematerialID);
            }

            var query = SOCDetailScoreDAL.GetSOCDetailStudentScoreView(userID, socExp, facultyExp, gradeExp, classExp);

            if (recordStatus.HasValue)
            {
                query = query.Where(x => x.RecordStatus == recordStatus);
            }

            if (!string.IsNullOrEmpty(studentScoreConditionView.ConditionValue) && !string.IsNullOrEmpty(studentScoreConditionView.Attribute))
                query = query.DynamicWhere(studentScoreConditionView.Attribute, studentScoreConditionView.Condition, studentScoreConditionView.ConditionValue);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.LoginID);

            return query.ToGridResultSet(pageIndex, pageSize);
        }

        public IGridResultSet<SOCDetailStudentScoreView> GetSOCDetailStudentScoreViewByIDList(ConfiguretView configuretView, Guid? socDetailID, Guid? userID, int? pageIndex, int? pageSize)
        {
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true);
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);

            var query = SOCDetailScoreDAL.GetSOCDetailStudentScoreView(userID.Value, socExp, facultyExp, gradeExp, classExp);

            if (socDetailID.HasValue)
            {
                query = query.Where(x => x.SOCDetailID == socDetailID);
            }

            if (!string.IsNullOrEmpty(configuretView.ConditionValue) && !string.IsNullOrEmpty(configuretView.Attribute))
                query = query.DynamicWhere(configuretView.Attribute, configuretView.Condition, configuretView.ConditionValue);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.LoginID);

            return query.ToGridResultSet(pageIndex, pageSize);
        }

        public List<SOCDetailStudentScoreView> GetSOCDetailStudentScoreViewList(ConfiguretView studentScoreConditionView, Guid? schoolyearID,
            Guid? collegeID, int? year, int? standardID, Guid? classmajorID, Guid? coursematerialID, int? recordStatus)
        {
            var userID = CustomPrincipal.Current.UserID;
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE); 
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true); 
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);

            if (schoolyearID.HasValue)
            {
                socExp = socExp.And(x => x.SchoolyearID == schoolyearID);
            }
            if (collegeID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.CollegeID == collegeID);
            }
            if (year.HasValue)
            {
                gradeExp = gradeExp.And(x => x.GradeID == year);
            }
            if (standardID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.StandardID == standardID);
            }
            if (classmajorID.HasValue)
            {
                classExp = classExp.And(x => x.ClassmajorID == classmajorID);
            }
            if (coursematerialID.HasValue)
            {
                socExp = socExp.And(x => x.CoursematerialID == coursematerialID);
            }

            var query = SOCDetailScoreDAL.GetSOCDetailStudentScoreView(userID, socExp, facultyExp, gradeExp, classExp);

            if (recordStatus.HasValue)
            {
                query = query.Where(x => x.RecordStatus == recordStatus);
            }

            if (!string.IsNullOrEmpty(studentScoreConditionView.ConditionValue) && !string.IsNullOrEmpty(studentScoreConditionView.Attribute))
                query = query.DynamicWhere(studentScoreConditionView.Attribute, studentScoreConditionView.Condition, studentScoreConditionView.ConditionValue);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.ClassmajorNo.Length).ThenBy(x => x.ClassmajorNo)
                .ThenBy(x => x.LoginID);

            return query.ToList();
        }

        public List<SOCDetailStudentScoreView> GetSOCDetailStudentScoreViewList(ConfiguretView studentScoreConditionView, Guid? socDetailID, Guid? userID)
        {
            //var userID = CustomPrincipal.Current.UserID;
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true);
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);


            var query = SOCDetailScoreDAL.GetSOCDetailStudentScoreView(userID.Value, socExp, facultyExp, gradeExp, classExp);

            if (socDetailID.HasValue)
            {
                query = query.Where(x => x.SOCDetailID == socDetailID);
            }

            if (!string.IsNullOrEmpty(studentScoreConditionView.ConditionValue) && !string.IsNullOrEmpty(studentScoreConditionView.Attribute))
                query = query.DynamicWhere(studentScoreConditionView.Attribute, studentScoreConditionView.Condition, studentScoreConditionView.ConditionValue);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.LoginID);

            return query.ToList();
        }

        public void StudentSave(IList<SOCDetailStudentScoreView> socDetailStudentScoreViewList)
        {
            var creUser = CustomPrincipal.Current;
            var detailUserIDList = socDetailStudentScoreViewList.Select(x => new { x.SOCDetailID, x.UserID }).ToList();
            //DQP_SOCDetailStudent表的数据在上传成果时插入的,这个时候一定会有。
            var detailStudentList = SOCDetailScoreDAL.SOCDetailStudentRepository.Entities.SelectByKeys(detailUserIDList);
            var studentScoreList = SOCDetailScoreDAL.SOCDetailStudentScoreRepository.Entities.SelectByKeys(detailUserIDList);

            var detailStudentHasScoreUpdateList = (from student in detailStudentList
                                           from score in socDetailStudentScoreViewList.Where(x => x.SOCDetailID == student.SOCDetailID && x.UserID == student.UserID)
                                           where score.Score.HasValue
                                           select student).ToList();
            detailStudentHasScoreUpdateList.ForEach(x => x.RecordStatus = (int)DQP_SOCDetailSubmitStatus.HasScore);
            var detailStudentHasNotScoreUpdateList = (from student in detailStudentList
                                                   from score in socDetailStudentScoreViewList.Where(x => x.SOCDetailID == student.SOCDetailID && x.UserID == student.UserID)
                                                   where !score.Score.HasValue
                                                   select student).ToList();
            detailStudentHasNotScoreUpdateList.ForEach(x => x.RecordStatus = (int)DQP_SOCDetailSubmitStatus.Submited);
            var detailStudentUpdateList = detailStudentHasScoreUpdateList.Concat(detailStudentHasNotScoreUpdateList).ToList();
            #region 要使用批量更新,需要用EF读出来一次,不用理他……
            var detailStudentEntityIDList = detailStudentUpdateList.Select(x => x.SOCDetailStudentID).ToList();
            var detailStudentEntityList = SOCDetailScoreDAL.SOCDetailStudentRepository.GetList(x => detailStudentEntityIDList.Contains(x.SOCDetailStudentID)).ToList();
            #endregion

            var insertList = socDetailStudentScoreViewList
                .Where(x => x.Score.HasValue)
                .Select(x => new DQP_SOCDetailStudentScore 
                {
                    SOCDetailStudentScoreID = Guid.NewGuid(),
                    SOCDetailID = x.SOCDetailID,
                    UserID = x.UserID,
                    Score = x.Score,
                    Credit = (x.Score >= 60 ? x.SOCDetailCredit : 0),
                    CreateTime = DateTime.Now,
                    CreateUserID = creUser.UserID
                }).ToList();

            insertList.ForEach(x => this.SetNewStatus(x));

            using (var scope = new TransactionScope(TransactionScopeOption.Required))
            {
                UnitOfWork.Delete<DQP_SOCDetailStudentScore>(studentScoreList);
                UnitOfWork.BulkInsert(insertList);
                UnitOfWork.BatchUpdate(detailStudentUpdateList);

                scope.Complete();
            }
        }

        public IGridResultSet<FileUploadView> GetSOCDetailStudentAttachmentViewList(ConfiguretView studentAttachmentConditionView, Guid? socDetailID, Guid? userID, int? pageIndex, int? pageSize)
        {
            if (!socDetailID.HasValue || !userID.HasValue)
            {
                return new GridResultSet<FileUploadView>();
            }

            Expression<Func<DQP_SOCDetailStudent, bool>> exp = (x => (x.RecordStatus == (int)DQP_SOCDetailSubmitStatus.Submited || x.RecordStatus == (int)DQP_SOCDetailSubmitStatus.HasScore)
                && x.SOCDetailID == socDetailID && x.UserID == userID);

            var query = SOCDetailScoreDAL.GetSOCDetailStudentAttachmentView(exp);

            return query.ToGridResultSet(pageIndex, pageSize);
        }


        public IGridResultSet<SOCDetailGroupScoreView> GetSOCDetailGroupScoreViewList(ConfiguretView groupScoreConditionView, Guid? schoolyearID, Guid? collegeID,
            int? year, int? standardID, Guid? classmajorID, Guid? coursematerialID, int? recordStatus, int? pageIndex, int? pageSize)
        {
            var userID = CustomPrincipal.Current.UserID;
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true);
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);

            if (schoolyearID.HasValue)
            {
                socExp = socExp.And(x => x.SchoolyearID == schoolyearID);
            }
            if (collegeID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.CollegeID == collegeID);
            }
            if (year.HasValue)
            {
                gradeExp = gradeExp.And(x => x.GradeID == year);
            }
            if (standardID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.StandardID == standardID);
            }
            if (classmajorID.HasValue)
            {
                classExp = classExp.And(x => x.ClassmajorID == classmajorID);
            }
            if (coursematerialID.HasValue)
            {
                socExp = socExp.And(x => x.CoursematerialID == coursematerialID);
            }

            var query = SOCDetailScoreDAL.GetSOCDetailGroupScoreView(userID, socExp, facultyExp, gradeExp, classExp);

            if (recordStatus.HasValue)
            {
                query = query.Where(x => x.RecordStatus == recordStatus);
            }

            if (!string.IsNullOrEmpty(groupScoreConditionView.ConditionValue) && !string.IsNullOrEmpty(groupScoreConditionView.Attribute))
                query = query.DynamicWhere(groupScoreConditionView.Attribute, groupScoreConditionView.Condition, groupScoreConditionView.ConditionValue);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x=>x.EducationMissionName)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.No);

            return query.ToGridResultSet(pageIndex, pageSize);
        }

        public IGridResultSet<SOCDetailGroupScoreView> GetSOCDetailGroupScoreViewByIDList(ConfiguretView groupScoreConditionView, Guid? socDetailID, Guid? userID, int? pageIndex, int? pageSize)
        {
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true);
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);


            var query = SOCDetailScoreDAL.GetSOCDetailGroupScoreView(userID.Value, socExp, facultyExp, gradeExp, classExp);

            if (socDetailID.HasValue)
            {
                query = query.Where(x => x.SOCDetailID == socDetailID);
            }

            if (!string.IsNullOrEmpty(groupScoreConditionView.ConditionValue) && !string.IsNullOrEmpty(groupScoreConditionView.Attribute))
                query = query.DynamicWhere(groupScoreConditionView.Attribute, groupScoreConditionView.Condition, groupScoreConditionView.ConditionValue);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.EducationMissionName)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.No);

            return query.ToGridResultSet(pageIndex, pageSize);
        }

        public List<SOCDetailGroupScoreView> GetSOCDetailGroupScoreViewList(ConfiguretView groupScoreConditionView, Guid? schoolyearID, Guid? collegeID,
            int? year, int? standardID, Guid? classmajorID, Guid? coursematerialID, int? recordStatus)
        {
            var userID = CustomPrincipal.Current.UserID;
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true);
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);

            if (schoolyearID.HasValue)
            {
                socExp = socExp.And(x => x.SchoolyearID == schoolyearID);
            }
            if (collegeID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.CollegeID == collegeID);
            }
            if (year.HasValue)
            {
                gradeExp = gradeExp.And(x => x.GradeID == year);
            }
            if (standardID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.StandardID == standardID);
            }
            if (classmajorID.HasValue)
            {
                classExp = classExp.And(x => x.ClassmajorID == classmajorID);
            }
            if (coursematerialID.HasValue)
            {
                socExp = socExp.And(x => x.CoursematerialID == coursematerialID);
            }

            var query = SOCDetailScoreDAL.GetSOCDetailGroupScoreView(userID, socExp, facultyExp, gradeExp, classExp);

            if (recordStatus.HasValue)
            {
                query = query.Where(x => x.RecordStatus == recordStatus);
            }

            if (!string.IsNullOrEmpty(groupScoreConditionView.ConditionValue) && !string.IsNullOrEmpty(groupScoreConditionView.Attribute))
                query = query.DynamicWhere(groupScoreConditionView.Attribute, groupScoreConditionView.Condition, groupScoreConditionView.ConditionValue);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.No);

            return query.ToList();
        }

        public List<SOCDetailGroupScoreView> GetSOCDetailGroupScoreViewByIDList(ConfiguretView groupScoreConditionView, Guid? socDetailID, Guid? userID)
        {
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true);
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);

            var query = SOCDetailScoreDAL.GetSOCDetailGroupScoreView(userID.Value, socExp, facultyExp, gradeExp, classExp);

            if (socDetailID.HasValue)
            {
                query = query.Where(x => x.SOCDetailID == socDetailID);
            }

            if (!string.IsNullOrEmpty(groupScoreConditionView.ConditionValue) && !string.IsNullOrEmpty(groupScoreConditionView.Attribute))
                query = query.DynamicWhere(groupScoreConditionView.Attribute, groupScoreConditionView.Condition, groupScoreConditionView.ConditionValue);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.No);

            return query.ToList();
        }

        [Obsolete]
        public void GroupSave(IList<SOCDetailGroupScoreView> socDetailGroupScoreViewList)
        {
            var userID = CustomPrincipal.Current.UserID;
            var groupIDList = socDetailGroupScoreViewList.Select(x => x.SOCDetailGroupID).ToList();
            var studentGroupList = SOCDetailScoreDAL.SOCDetailGroupRepository.GetList(x => groupIDList.Contains(x.SOCDetailGroupID), (x => x.CF_Student)).ToList();
            var detailUserList = (from studentGroup in studentGroupList
                                  from student in studentGroup.CF_Student
                                  select new { studentGroup.SOCDetailID, student.UserID }).ToList();
            var studentScoreList = SOCDetailScoreDAL.SOCDetailStudentScoreRepository.Entities.SelectByKeys(detailUserList);
            
            studentGroupList.ForEach(x =>
            {
                var socDetailGroupScoreView = socDetailGroupScoreViewList.FirstOrDefault(w => w.SOCDetailGroupID == x.SOCDetailGroupID);
                if (socDetailGroupScoreView != null)
                {
                    x.Score = socDetailGroupScoreView.Score;
                    this.SetModifyStatus(x);
                    if (socDetailGroupScoreView.Score.HasValue)
                    {
                        x.RecordStatus = (int)DQP_SOCDetailSubmitStatus.HasScore;
                    }
                    else
                    {
                        x.RecordStatus = (int)DQP_SOCDetailSubmitStatus.Submited;
                    }
                }
            });

            var insertList = (from studentGroup in studentGroupList 
                              join view in socDetailGroupScoreViewList on studentGroup.SOCDetailGroupID equals view.SOCDetailGroupID 
                              from student in studentGroup.CF_Student 
                              where studentGroup.Score.HasValue 
                              select new DQP_SOCDetailStudentScore
                              {
                                  SOCDetailStudentScoreID = Guid.NewGuid(),
                                  SOCDetailID = studentGroup.SOCDetailID,
                                  UserID = student.UserID,
                                  Score = studentGroup.Score,
                                  Credit = (studentGroup.Score >= 60 ? view.SOCDetailCredit : 0),
                                  CreateTime = DateTime.Now,
                                  CreateUserID = userID,
                              }).ToList();

            using (var scope = new TransactionScope(TransactionScopeOption.Required))
            {
                UnitOfWork.BatchUpdate(studentGroupList);
                UnitOfWork.Delete(studentScoreList);
                UnitOfWork.BulkInsert(insertList);

                scope.Complete();
            }
        }

        public IGridResultSet<FileUploadView> GetSOCDetailGroupAttachmentViewList(ConfiguretView studentAttachmentConditionView, Guid? socDetailID, Guid? socDetailGroupID, int? pageIndex, int? pageSize)
        {
            if (!socDetailID.HasValue || !socDetailGroupID.HasValue)
            {
                return new GridResultSet<FileUploadView>();
            }

            Expression<Func<DQP_SOCDetailGroup, bool>> exp = (x => (x.RecordStatus == (int)DQP_SOCDetailSubmitStatus.Submited || x.RecordStatus == (int)DQP_SOCDetailSubmitStatus.HasScore)
                && x.SOCDetailID == socDetailID && x.SOCDetailGroupID == socDetailGroupID);

            var query = SOCDetailScoreDAL.GetSOCDetailGroupAttachmentView(exp);

            return query.ToGridResultSet(pageIndex, pageSize);
        }

        public IGridResultSet<BaseStudentView> GetSOCDetailGroupStudentViewList(ConfiguretView studentAttachmentConditionView,
            Guid? socDetailGroupID, int? pageIndex, int? pageSize)
        {
            if (!socDetailGroupID.HasValue)
            {
                return new GridResultSet<BaseStudentView>();
            }

            Expression<Func<DQP_SOCDetailGroup, bool>> exp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE
                && x.SOCDetailGroupID == socDetailGroupID);

            var query = SOCDetailScoreDAL.GetSOCDetailGroupStudentView(exp);

            return query.OrderBy(x => x.ClassmajorCode).ToGridResultSet(pageIndex, pageSize);
        }

        public IGridResultSet<BaseStudentView> GetSOCDetailGroupStudentViewList(ConfiguretView studentAttachmentConditionView,
            Guid socDetailID, Guid userID, int? pageIndex, int? pageSize)
        {
            Expression<Func<DQP_SOCDetailGroup, bool>> exp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE
                && x.SOCDetailID == socDetailID && x.CF_Student.Any(w => w.UserID == userID));

            var query = SOCDetailScoreDAL.GetSOCDetailGroupStudentView(exp);

            return query.OrderBy(x => x.ClassmajorCode).ToGridResultSet(pageIndex, pageSize);
        }

        public IGridResultSet<SOCDetailRawScoreView> GetSOCDetailRawScoreViewList(ConfiguretView studentScoreConditionView, Guid? schoolyearID, Guid? collegeID, int? year, int? standardID, Guid? classmajorID, Guid? coursematerialID, int? pageIndex, int? pageSize)
        {
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true);
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);
            Expression<Func<Sys_User, bool>> userExp = (x => true);
            Expression<Func<DQP_SOCDetail, bool>> detailExp = (x => true);

            if (schoolyearID.HasValue)
            {
                socExp = socExp.And(x => x.SchoolyearID == schoolyearID);
            }
            if (collegeID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.CollegeID == collegeID);
            }
            if (year.HasValue)
            {
                gradeExp = gradeExp.And(x => x.GradeID == year);
            }
            if (standardID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.StandardID == standardID);
            }
            if (classmajorID.HasValue)
            {
                classExp = classExp.And(x => x.ClassmajorID == classmajorID);
            }
            if (coursematerialID.HasValue)
            {
                socExp = socExp.And(x => x.CoursematerialID == coursematerialID);
            }
            var curUser = EMIS.Utility.FormValidate.CustomPrincipal.Current;

            var role = RoleServices.GetEnabledTeacherRoleViewList();
            var teacherRole = role.Where(x => x.RoleName == "教师");
            if (curUser.RoleID == teacherRole.FirstOrDefault().RoleID)
            {
                detailExp = detailExp.And(x => x.CreateUserID == curUser.UserID);
            }
            var query = SOCDetailScoreDAL.GetSOCDetailRawScoreView(socExp, detailExp, facultyExp, gradeExp, classExp, userExp);
            if (!string.IsNullOrEmpty(studentScoreConditionView.ConditionValue) && !string.IsNullOrEmpty(studentScoreConditionView.Attribute))
                query = query.DynamicWhere(studentScoreConditionView.Attribute, studentScoreConditionView.Condition, studentScoreConditionView.ConditionValue);

            query = this.GetQueryByDataRangeByDepartment(query);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.ClassmajorNo.Length).ThenBy(x => x.ClassmajorNo)
                .ThenBy(x => x.LoginID);

            return query.ToGridResultSet(pageIndex, pageSize);
        }

        public List<SOCDetailRawScoreView> GetSOCDetailRawScoreViewList(ConfiguretView studentScoreConditionView, Guid? schoolyearID, Guid? collegeID, int? year, int? standardID, Guid? classmajorID, Guid? coursematerialID)
        {
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true);
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);
            Expression<Func<Sys_User, bool>> userExp = (x => true);

            Expression<Func<DQP_SOCDetail, bool>> detailExp = (x => true);

            if (schoolyearID.HasValue)
            {
                socExp = socExp.And(x => x.SchoolyearID == schoolyearID);
            }
            if (collegeID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.CollegeID == collegeID);
            }
            if (year.HasValue)
            {
                gradeExp = gradeExp.And(x => x.GradeID == year);
            }
            if (standardID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.StandardID == standardID);
            }
            if (classmajorID.HasValue)
            {
                classExp = classExp.And(x => x.ClassmajorID == classmajorID);
            }
            if (coursematerialID.HasValue)
            {
                socExp = socExp.And(x => x.CoursematerialID == coursematerialID);
            }
            var curUser = EMIS.Utility.FormValidate.CustomPrincipal.Current;

            var role = RoleServices.GetEnabledTeacherRoleViewList();
            var teacherRole = role.Where(x => x.RoleName == "教师");
            if (curUser.RoleID == teacherRole.FirstOrDefault().RoleID)
            {
                detailExp = detailExp.And(x => x.CreateUserID == curUser.UserID);
            }
            var query = SOCDetailScoreDAL.GetSOCDetailRawScoreView(socExp, detailExp, facultyExp, gradeExp, classExp, userExp);

            if (!string.IsNullOrEmpty(studentScoreConditionView.ConditionValue) && !string.IsNullOrEmpty(studentScoreConditionView.Attribute))
                query = query.DynamicWhere(studentScoreConditionView.Attribute, studentScoreConditionView.Condition, studentScoreConditionView.ConditionValue);

            query = this.GetQueryByDataRangeByDepartment(query);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.ClassmajorNo.Length).ThenBy(x => x.ClassmajorNo)
                .ThenBy(x => x.LoginID);

            return query.ToList();
        }

        public void StudentSubmit(Guid userID, IList<SOCDetailStudentKeyView> socDetailStudentKeyViewList)
        {
            var nowTime = DateTime.Now;
            var studentSubmitList = socDetailStudentKeyViewList.Where(x => !x.SOCDetailGroupID.HasValue).Select(x => x.SOCDetailID).ToList();
            var groupSubmitList = socDetailStudentKeyViewList.Where(x => x.SOCDetailGroupID.HasValue).Select(x => x.SOCDetailGroupID).ToList();

            var studentDetailList = SOCDetailScoreDAL.SOCDetailRepository.GetList(x => studentSubmitList.Contains(x.SOCDetailID), 
                (x => x.DQP_SOC.EM_Coursematerial),
                (x => x.DQP_SOCDetailStudent),
                (x => x.DQP_SOCDetailStudent.Select(w => w.DQP_SOCDetailStudentAttachment))).ToList();
            var groupDetailList = SOCDetailScoreDAL.SOCDetailGroupRepository.GetList(x => groupSubmitList.Contains(x.SOCDetailGroupID),
                (x => x.DQP_SOCDetail.DQP_SOC.EM_Coursematerial),
                (x => x.CF_Student),
                (x => x.DQP_SOCDetailStudentAttachment)).ToList();
            var noAttachmentList = studentDetailList.Where(x => !x.DQP_SOCDetailStudent.Any(w => w.UserID == userID && w.DQP_SOCDetailStudentAttachment.Count > 0))
                .Concat(groupDetailList.Where(x => x.CF_Student.Any(w => w.UserID == userID) && x.DQP_SOCDetailStudentAttachment.Count == 0)
                .Select(x => x.DQP_SOCDetail)).ToList();

            if (noAttachmentList.Count > 0)
            {
                throw new Exception(string.Join("、", noAttachmentList.Select(x => x.DQP_SOC.EM_Coursematerial.CourseName + "的" + x.Name).ToList())
                    + "没有上传附件,不能提交。");
            }
            var errorStatusList = studentDetailList.Where(x => x.DQP_SOCDetailStudent.Where(w => w.UserID == userID)
                                                            .Any(w => w.RecordStatus != (int)DQP_SOCDetailSubmitStatus.NotSubmit
                                                                && w.RecordStatus != (int)DQP_SOCDetailSubmitStatus.Canceled))
                                  .Concat(groupDetailList.Where(x => x.RecordStatus != (int)DQP_SOCDetailSubmitStatus.NotSubmit
                                    && x.RecordStatus != (int)DQP_SOCDetailSubmitStatus.Canceled)
                                    .Select(x => x.DQP_SOCDetail)).ToList();
            if (errorStatusList.Count > 0)
            {
                throw new Exception(string.Join("、", errorStatusList.Select(x => x.DQP_SOC.EM_Coursematerial.CourseName + "的" + x.Name).ToList())
                    + "已经提交,不能再次提交。");
            }

            if (studentSubmitList.Count > 0)
            {
                this.UnitOfWork.Update<DQP_SOCDetailStudent>((x => new DQP_SOCDetailStudent
                {
                    RecordStatus = (int)DQP_SOCDetailSubmitStatus.Submited,
                    ModifyUserID = userID,
                    ModifyTime = nowTime
                }),
                (x => studentSubmitList.Contains(x.SOCDetailID) && x.UserID == userID));
            }

            if (groupSubmitList.Count > 0)
            {
                this.UnitOfWork.Update<DQP_SOCDetailGroup>((x => new DQP_SOCDetailGroup
                {
                    RecordStatus = (int)DQP_SOCDetailSubmitStatus.Submited,
                    ModifyUserID = userID,
                    ModifyTime = nowTime
                }),
                (x => groupSubmitList.Contains(x.SOCDetailGroupID)));
            }
        }

        public List<FileUploadView> GetFileList(Guid? formID)
        {
            var socDetailGroup = this.SOCDetailScoreDAL.SOCDetailGroupRepository.GetSingle(x => x.SOCDetailGroupID == formID);
            if (socDetailGroup != null)
            {
                return SOCDetailScoreDAL.GetSOCDetailGroupAttachmentView(x => x.SOCDetailGroupID == formID).ToList();
            }
            else
            {
                var userID = CustomPrincipal.Current.UserID;
                return SOCDetailScoreDAL.GetSOCDetailStudentAttachmentView(x => x.SOCDetailID == formID && x.UserID == userID).ToList();
            }
        }

        public void SaveFile(Guid userID, SOCDetailStudentKeyView socDetailStudentKeyView, IList<FileUploadView> fileList)
        {
            var socDetailGroup = this.SOCDetailScoreDAL.SOCDetailGroupRepository.GetSingle(x => x.SOCDetailGroupID == socDetailStudentKeyView.SOCDetailGroupID);
            if (socDetailGroup != null)
            {
                var insertList = fileList.Select(x => new DQP_SOCDetailStudentAttachment
                {
                    SOCDetailStudentAttachmentID = Guid.NewGuid(),
                    SOCDetailGroupID = socDetailStudentKeyView.SOCDetailGroupID,
                    Name = x.FileName,
                    Url = x.FileUrl
                }).ToList();

                insertList.ForEach(x => this.SetNewStatus(x));

                using (var scope = new TransactionScope())
                {
                    UnitOfWork.Delete<DQP_SOCDetailStudentAttachment>(x => x.SOCDetailGroupID == socDetailStudentKeyView.SOCDetailGroupID);
                    UnitOfWork.BulkInsert(insertList);

                    scope.Complete();
                }
            }
            else
            {
                bool hasDetailStudent = true;
                var socDetailStudent = this.SOCDetailScoreDAL.SOCDetailStudentRepository.GetSingle(x => x.SOCDetailID == socDetailStudentKeyView.SOCDetailID && x.UserID == userID);
                if (socDetailStudent == null)
                {
                    hasDetailStudent = false;
                    socDetailStudent = new DQP_SOCDetailStudent() 
                    {
                        SOCDetailStudentID = Guid.NewGuid(),
                        SOCDetailID = socDetailStudentKeyView.SOCDetailID,
                        UserID = userID
                    };

                    this.SetNewStatus(socDetailStudent);
                }
                var insertList = fileList.Select(x => new DQP_SOCDetailStudentAttachment
                {
                    SOCDetailStudentAttachmentID = Guid.NewGuid(),
                    SOCDetailStudentID = socDetailStudent.SOCDetailStudentID,
                    Name = x.FileName,
                    Url = x.FileUrl
                }).ToList();

                insertList.ForEach(x => this.SetNewStatus(x));

                using (var scope = new TransactionScope())
                {
                    if (!hasDetailStudent)
                    {
                        UnitOfWork.BulkInsert(new List<DQP_SOCDetailStudent> { socDetailStudent });
                    }
                    else
                    {
                        UnitOfWork.Delete<DQP_SOCDetailStudentAttachment>(x => x.SOCDetailStudentID == socDetailStudent.SOCDetailStudentID);
                    }
                    UnitOfWork.BulkInsert(insertList);

                    scope.Complete();
                }
            }
        }

        public IList<SOCStudentScoreItemView> GetStudentScoreItemViewList(Guid userID)
        {
            return this.SOCDetailScoreDAL.GetSOCStudentScoreItemViewQueryable(userID);
        }

        /// <summary>
        /// 获取学生个人成绩预览信息
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public SOCStudentScoreTotalView GetStudentScoreTotalView(Guid userID)
        {
            var student = this.SOCDetailScoreDAL.GetSOCStudentScoreItemView(userID);
            return student;
        }

        public ReturnMessage IsStudentCanUpload(Guid userID, SOCDetailStudentKeyView socDetailStudentKeyView)
        {
            var nowDate = DateTime.Today;
            var socDetailGroup = this.SOCDetailScoreDAL.SOCDetailGroupRepository.GetSingle(x => x.SOCDetailGroupID == socDetailStudentKeyView.SOCDetailGroupID, (x => x.DQP_SOCDetail));
            if (socDetailGroup != null)
            {
                if (socDetailGroup.RecordStatus != (int)DQP_SOCDetailSubmitStatus.NotSubmit && socDetailGroup.RecordStatus != (int)DQP_SOCDetailSubmitStatus.Canceled)
                {
                    return new ReturnMessage { IsSuccess = false, Message = "成果已提交,无法上传。" };
                }

                if (!(socDetailGroup.DQP_SOCDetail.StartTime <= nowDate && socDetailGroup.DQP_SOCDetail.EndTime >= nowDate))
                {
                    return new ReturnMessage { IsSuccess = false, Message = "现在不是成果上传的时间,暂时无法上传。" };
                }
            }
            else
            {
                var socDetail = this.SOCDetailScoreDAL.SOCDetailRepository.GetSingle(x => x.SOCDetailID == socDetailStudentKeyView.SOCDetailID, (x => x.DQP_SOCDetailStudent));
                if (socDetail != null)
                {
                    if (socDetail.DQP_SOCDetailStudent.Any(w => w.UserID == userID && w.RecordStatus != (int)DQP_SOCDetailSubmitStatus.NotSubmit && w.RecordStatus != (int)DQP_SOCDetailSubmitStatus.Canceled))
                    {
                        return new ReturnMessage { IsSuccess = false, Message = "成果已提交,无法上传。" };
                    }

                    if (!(socDetail.StartTime <= nowDate && socDetail.EndTime >= nowDate))
                    {
                        return new ReturnMessage { IsSuccess = false, Message = "现在不是成果上传的时间,暂时无法上传。" };
                    }
                }
                else
                {
                    return new ReturnMessage { IsSuccess = false, Message = "现在不是成果上传的时间,暂时无法上传。" };
                }
            }

            return new ReturnMessage { IsSuccess = true };
        }

        public IGridResultSet<SOCDetailRawScoreView> GetSOCDetailRawScoreViewList(Guid? coursematerialID, int? startTermID, Guid userID)
        {
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true);
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);
            Expression<Func<Sys_User, bool>> userExp = (x => true);

            Expression<Func<DQP_SOCDetail, bool>> detailExp = (x => true);

            if (coursematerialID.HasValue)
            {
                socExp = socExp.And(x => x.CoursematerialID == coursematerialID);
            }
            if (startTermID.HasValue)
            {
                var student = SOCDetailScoreDAL.StudentRepository.GetSingle(x => x.UserID == userID, (x => x.CF_Classmajor.CF_Grademajor));
                var schoolyear = SOCDetailScoreDAL.SchoolyearRepository.GetSingle(x => x.Years == student.CF_Classmajor.CF_Grademajor.GradeID && x.SchoolcodeID == student.CF_Classmajor.CF_Grademajor.SemesterID);
                var newSchoolyearValue = schoolyear.Value + startTermID.Value - 1;
                var newSchoolyear = SOCDetailScoreDAL.SchoolyearRepository.GetSingle(x => x.Value == newSchoolyearValue);

                socExp = socExp.And(x => x.SchoolyearID == newSchoolyear.SchoolyearID);
            }
            userExp = userExp.And(x => x.UserID == userID);

            var query = SOCDetailScoreDAL.GetSOCDetailRawScoreView(socExp, detailExp, facultyExp, gradeExp, classExp, userExp);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.ClassmajorNo.Length).ThenBy(x => x.ClassmajorNo)
                .ThenBy(x => x.LoginID);

            return query.ToGridResultSet();
        }

        public void StudentCancel(IList<Guid> socDetailStudentIDList, string remark)
        {
            var detailStudentUpdateList = SOCDetailScoreDAL.SOCDetailStudentRepository.GetList(x => socDetailStudentIDList.Contains(x.SOCDetailStudentID)).ToList();
            var detailStudentScoreList = SOCDetailScoreDAL.GetStudentScoreBySOCDetailStudent(x => socDetailStudentIDList.Contains(x.SOCDetailStudentID)).ToList();

            detailStudentUpdateList.ForEach(x => {
                this.SetModifyStatus(x);
                x.Remark = remark;
                x.RecordStatus = (int)DQP_SOCDetailSubmitStatus.Canceled;
            });

            using (var scope = new TransactionScope())
            {
                UnitOfWork.BatchUpdate(detailStudentUpdateList);
                UnitOfWork.Delete(detailStudentScoreList);

                scope.Complete();
            }
        }

        public void GroupCancel(IList<Guid> socDetailGroupIDList, string remark)
        {
            var studentGroupList = SOCDetailScoreDAL.SOCDetailGroupRepository.GetList(x => socDetailGroupIDList.Contains(x.SOCDetailGroupID), (x => x.CF_Student)).ToList();
            var detailStudentScoreList = SOCDetailScoreDAL.GetStudentScoreBySOCDetailGroup(x => socDetailGroupIDList.Contains(x.SOCDetailGroupID)).ToList();

            studentGroupList.ForEach(x =>
            {
                x.Score = null;
                this.SetModifyStatus(x);
                x.Remark = remark;
                x.RecordStatus = (int)DQP_SOCDetailSubmitStatus.Canceled;
            });

            using (var scope = new TransactionScope())
            {
                UnitOfWork.BatchUpdate(studentGroupList);
                UnitOfWork.Delete(detailStudentScoreList);

                scope.Complete();
            }
        }

        public void SendMessage(List<Guid> userIDList, AnnouncementView announcement)
        {
            var announcementEntity = AnnouncementDAL.AnnouncementRepository.GetSingle
                (x => x.AnnouncementID == announcement.AnnouncementID, (x => x.Sys_User));
            if (announcementEntity != null)
            {
                announcementEntity.AnnouncementTypeID = announcement.AnnouncementTypeID;
                announcementEntity.Title = announcement.Title;
                announcementEntity.Content = announcement.Content;
                announcementEntity.StartTime = announcement.StartTime;
                announcementEntity.EndTime = announcement.EndTime;

                this.SetModifyStatus(announcementEntity);
            }
            else
            {
                announcementEntity = new Sys_Announcement();
                announcementEntity.AnnouncementID = Guid.NewGuid();
                announcementEntity.AnnouncementTypeID = announcement.AnnouncementTypeID;
                announcementEntity.Title = announcement.Title;
                announcementEntity.Content = announcement.Content;
                announcementEntity.StartTime = announcement.StartTime;
                announcementEntity.EndTime = announcement.EndTime;
                this.SetNewStatus(announcementEntity);
                UnitOfWork.Add(announcementEntity);
            }

            var userList = StudentsDAL.UserRepository.GetList(x => userIDList.Contains(x.UserID)).ToList();
            announcementEntity.Sys_User = new HashSet<Sys_User>();
            userList.ForEach(x => announcementEntity.Sys_User.Add(x));

            UnitOfWork.Commit();
        }

        public IGridResultSet<SOCDetailRawScoreView> GetSOCDetailGroupRawScoreViewList(ConfiguretView studentScoreConditionView, 
            Guid socDetailGroupID, int? pageIndex, int? pageSize)
        {
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true);
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);
            Expression<Func<Sys_User, bool>> userExp = (x => x.CF_Student.DQP_SOCDetailGroup.Any(w => w.SOCDetailGroupID == socDetailGroupID));

            Expression<Func<DQP_SOCDetail, bool>> detailExp = (x => x.DQP_SOCDetailGroup.Any(w => w.SOCDetailGroupID == socDetailGroupID));

            var query = SOCDetailScoreDAL.GetSOCDetailRawScoreView(socExp, detailExp, facultyExp, gradeExp, classExp, userExp);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.ClassmajorNo.Length).ThenBy(x => x.ClassmajorNo)
                .ThenBy(x => x.LoginID);

            return query.ToGridResultSet();
        }


        public void GroupScoreSave(Guid socDetailGroupID, IList<SOCDetailRawScoreView> socDetailRawScoreViewList)
        {
            var userID = CustomPrincipal.Current.UserID;
            var studentGroup = SOCDetailScoreDAL.SOCDetailGroupRepository.GetSingle(x => x.SOCDetailGroupID == socDetailGroupID, (x => x.CF_Student));
            var detailUserList = (from student in studentGroup.CF_Student
                                  select new { studentGroup.SOCDetailID, student.UserID }).ToList();
            var studentScoreList = SOCDetailScoreDAL.SOCDetailStudentScoreRepository.Entities.SelectByKeys(detailUserList);

            if (!socDetailRawScoreViewList.Any(x => !x.Score.HasValue))
            {
                studentGroup.RecordStatus = (int)DQP_SOCDetailSubmitStatus.HasScore;
            }
            else
            {
                studentGroup.RecordStatus = (int)DQP_SOCDetailSubmitStatus.Submited;
            }
            this.SetModifyStatus(studentGroup);
            var updateGroupList = new List<DQP_SOCDetailGroup>() { studentGroup };

            var insertList = (from view in socDetailRawScoreViewList
                              where view.Score.HasValue 
                              select new DQP_SOCDetailStudentScore
                              {
                                  SOCDetailStudentScoreID = Guid.NewGuid(),
                                  SOCDetailID = studentGroup.SOCDetailID,
                                  UserID = view.UserID,
                                  Score = view.Score,
                                  Credit = (view.Score >= 60 ? view.SOCDetailCredit : 0),
                                  CreateTime = DateTime.Now,
                                  CreateUserID = userID,
                              }).ToList();

            using (var scope = new TransactionScope(TransactionScopeOption.Required))
            {
                UnitOfWork.BatchUpdate(updateGroupList);
                UnitOfWork.Delete(studentScoreList);
                UnitOfWork.BulkInsert(insertList);

                scope.Complete();
            }
        }
        public SOCDetailStudentScoreView GetSOCDetialView(Guid? SOCDetailID)
        {
            Expression<Func<DQP_SOCDetail, bool>> socExp = (x => x.SOCDetailID==SOCDetailID); 
            var userID = CustomPrincipal.Current.UserID;
            var q = SOCDetailScoreDAL.GetSOCDetailView(socExp, userID);
            return q.FirstOrDefault();

        }
        public List<SOCDetailStudentScoreView> Download(ConfiguretView studentScoreConditionView, Guid? schoolyearID,
            Guid? collegeID, int? year, int? standardID, Guid? classmajorID, Guid? coursematerialID, int? recordStatus,List<Guid?> IDList)
        {
            var userID = CustomPrincipal.Current.UserID;
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true);
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);
            if (schoolyearID.HasValue)
            {
                socExp = socExp.And(x => x.SchoolyearID == schoolyearID);
            }
            if (collegeID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.CollegeID == collegeID);
            }
            if (year.HasValue)
            {
                gradeExp = gradeExp.And(x => x.GradeID == year);
            }
            if (standardID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.StandardID == standardID);
            }
            if (classmajorID.HasValue)
            {
                classExp = classExp.And(x => x.ClassmajorID == classmajorID);
            }
            if (coursematerialID.HasValue)
            {
                socExp = socExp.And(x => x.CoursematerialID == coursematerialID);
            }

            var query = SOCDetailScoreDAL.GetSOCDetailView(userID, socExp, facultyExp, gradeExp, classExp);
            if (IDList != null)
            {
                query = query.Where(x => IDList.Contains(x.UserID));
            }
            if (recordStatus.HasValue)
            {
                query = query.Where(x => x.RecordStatus == recordStatus);
            }

            if (!string.IsNullOrEmpty(studentScoreConditionView.ConditionValue) && !string.IsNullOrEmpty(studentScoreConditionView.Attribute))
                query = query.DynamicWhere(studentScoreConditionView.Attribute, studentScoreConditionView.Condition, studentScoreConditionView.ConditionValue);

            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.SOCDetailName)
                .ThenBy(x => x.LoginID);
            var socDetailList= query.ToList();
            return socDetailList;
        }
        public List<SOCDetailStudentScoreView> GroupListDownload(ConfiguretView studentScoreConditionView,
            Guid? schoolyearID, Guid? collegeID, int? year, int? standardID, Guid? classmajorID, Guid? coursematerialID, int? recordStatus,List<Guid?> IDList)
        {
            var userID = CustomPrincipal.Current.UserID;
            List<SOCDetailStudentScoreView> DetailList = new List<SOCDetailStudentScoreView>();
            Expression<Func<DQP_SOC, bool>> socExp = (x => x.RecordStatus > (int)SYS_STATUS.UNUSABLE);
            Expression<Func<CF_Facultymajor, bool>> facultyExp = (x => true);
            Expression<Func<CF_Grademajor, bool>> gradeExp = (x => true);
            Expression<Func<CF_Classmajor, bool>> classExp = (x => true);
            if (schoolyearID.HasValue)
            {
                socExp = socExp.And(x => x.SchoolyearID == schoolyearID);
            }
            if (collegeID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.CollegeID == collegeID);
            }
            if (year.HasValue)
            {
                gradeExp = gradeExp.And(x => x.GradeID == year);
            }
            if (standardID.HasValue)
            {
                facultyExp = facultyExp.And(x => x.StandardID == standardID);
            }
            if (classmajorID.HasValue)
            {
                classExp = classExp.And(x => x.ClassmajorID == classmajorID);
            }
            if (coursematerialID.HasValue)
            {
                socExp = socExp.And(x => x.CoursematerialID == coursematerialID);
            }

            var query = SOCDetailScoreDAL.GetSOCDetailGroup(userID, socExp, facultyExp, gradeExp, classExp);

            if (recordStatus.HasValue)
            {
                query = query.Where(x => x.RecordStatus == recordStatus);
            }
            if (IDList != null)
            {
                query = query.Where(x => IDList.Contains(x.SOCDetailGroupID));
            }
            if (!string.IsNullOrEmpty(studentScoreConditionView.ConditionValue) && !string.IsNullOrEmpty(studentScoreConditionView.Attribute))
                query = query.DynamicWhere(studentScoreConditionView.Attribute, studentScoreConditionView.Condition, studentScoreConditionView.ConditionValue);
            query = query.OrderByDescending(x => x.SchoolyearCode)
                .ThenBy(x => x.CourseCode)
                .ThenBy(x => x.SOCDetailName);
            var socDetailList = query.ToList();
            foreach(var soc in socDetailList)
            {
                SOCDetailStudentScoreView Detail = new SOCDetailStudentScoreView();
                Detail.EducationMissionName = soc.EducationMissionName;
                Detail.CourseName = soc.CourseName;
                Detail.SOCDetailName = soc.SOCDetailName;
                Detail.LoginID = soc.LoginID;
                Detail.Name = soc.Name;
                Detail.SOCDetailUrl = soc.SOCDetailUrl;
                Detail.FileName = soc.FileName;
                DetailList.Add(Detail);
            }
            return DetailList;
        }
    }
}