/// <summary> /// 作者:Primo /// 日期:2015.01.20 /// 描述:匹配至 ArrangeCourse /// </summary> /// <param name="branchId"></param> /// <param name="beginDate"></param> /// <param name="endDate"></param> /// <param name="createBy"></param> /// <returns></returns> public static bool DisposeArrangeCourse(int branchId, DateTime beginDate, DateTime endDate, int createBy, out Dictionary<string, string> outList) { var result = false;//初始化状态 var removeUnfinishedCourses = "";//匹配成功后需要移除的课程 var removeAvailableTime = "";//匹配成功后需要移除的时间 var ProductLevelCourseTypeCourseName = "";//课程名称 outList = new Dictionary<string, string>(); var edbAcs = new Model.Acs.EmeAcsEntities(); var countPercent = Common.Global.CountPercent.ToString().Split(','); //匹配次数,必须要有一个float值 var maxPlanNum = countPercent.Count();//最大的匹配次数 var planNum = 0;//记录当前的匹配次数 //获取第一个符合条件的学员,主要循环的学员 var tempStudent = edbAcs.Student.OrderBy(p => p.WorkDate) .ThenByDescending(p => p.IsFirst) .ThenBy(p => p.ArrangeCourseOrder) .FirstOrDefault(p => p.BranchId == branchId //所属中心 && p.WorkDate >= beginDate //在匹配的范围内 && p.WorkDate <= endDate //在匹配的范围内 && p.CurrTaskNum < Common.Global.MaxNum //小于最大匹配数 && p.Status == ConvertEnum.StatusTypeForActive); //是有效的数据 try { if (tempStudent == null)//表示已经循环所有学员了 { return BranchBLL.UpateStudentByPlanNum(maxPlanNum, branchId, beginDate, endDate, createBy); } //学生可用时间数组 var availableTimeList = tempStudent.AvailableTime.Trim(',').Split(',').ToList(); #region 循环学生的可用时间 //循环学生可用时间 foreach (var itemAvailableTime in availableTimeList) { if (result)//result 为 true ,说明已经找到了适合的 break; if (itemAvailableTime == string.Empty)//如果时间是空的,则跳过继续执行下一个 continue; outList = new Dictionary<string, string>();//声明一个字符词典,用来输出学生 //获取同一类的学生 var studentLikeList = (from a in edbAcs.Student where a.BranchId == tempStudent.BranchId && a.StudentId != tempStudent.StudentId && a.ProductLevelId == tempStudent.ProductLevelId && a.WorkDate == tempStudent.WorkDate && a.CurrTaskNum < Common.Global.MaxNum && a.Status == ConvertEnum.StatusTypeForActive && a.AvailableTime.Contains(itemAvailableTime) == true select a).OrderByDescending(p => p.IsFirst).ThenBy(p => p.ArrangeCourseOrder); var unfinishedCoursesList = new List<string>(); var unfinishedCoursesList2 = new List<string>(); var unfinishedCoursesStr = tempStudent.UnfinishedCourses.Trim(','); //把这些学生所有的未上过的课程都合并起来 foreach (var studentLike in studentLikeList) { unfinishedCoursesStr = unfinishedCoursesStr.Trim(',') + "," + studentLike.UnfinishedCourses.Trim(','); } //把这些学生所有的未上过的课程合并之后,转换成数组 unfinishedCoursesList = unfinishedCoursesStr.Trim(',').Split(',').ToList(); unfinishedCoursesList2 = tempStudent.UnfinishedCourses.Trim(',').Split(',').ToList(); //把数组中的重复元素合并,且统计 var modelUnfinishedCourses = (from a in unfinishedCoursesList group a by a into g select new { g.Key, NumCount = g.Count() }).OrderByDescending(a => a.NumCount).ToList(); var modelUnfinishedCourses2 = (from a in unfinishedCoursesList2 group a by a into g select new { g.Key, NumCount = g.Count() }).OrderByDescending(a => a.NumCount).ToList(); modelUnfinishedCourses = (from a in modelUnfinishedCourses2 join b in modelUnfinishedCourses on a.Key equals b.Key select new { a.Key, b.NumCount }).OrderBy(a => a.NumCount).ToList(); //教室 var modelClassroom = new Model.Acs.Classroom(); //教师 var modelTeacher = new Model.Acs.Teacher(); //上课时间拼接 var dtDate = Convert.ToDateTime(string.Format("{0}/{1}/{2} {3}:{4}" , itemAvailableTime.Substring(0, 4) , itemAvailableTime.Substring(4, 2) , itemAvailableTime.Substring(6, 2) , itemAvailableTime.Substring(8, 2) , itemAvailableTime.Substring(10, 2))); // 课程结束时间 var dtEndDate = dtDate; var edb = new Model.Eme.EmeEntities(); //Int类型的未上过课程ID var unfinishedCoursesToInt = 0; //String类型的未上过课程ID var unfinishedCoursesToString = ""; //循环未上过的课程 foreach (var itemUnfinishedCourses in modelUnfinishedCourses) { //如果为空,则跳出执行下一个 if (itemUnfinishedCourses.Key == "") continue; unfinishedCoursesToInt = Convert.ToInt32(itemUnfinishedCourses.Key); unfinishedCoursesToString = string.Format(",{0},", itemUnfinishedCourses.Key); //获取课节 var plctc = edb.ProductLevelCourseTypeCourse.SingleOrDefault(p => p.Id == unfinishedCoursesToInt); dtEndDate = dtDate.AddMinutes(plctc.Course.ClassTime); ProductLevelCourseTypeCourseName = plctc.Course.EName; //不排LMW课程 if (plctc.Course.EName.Contains("LMW")) { tempStudent.Remark = "不排LMW课程!"; continue; } #region 教师 //获取符合条件的第一个获取教师 var strTeachRange = string.Format(",{0}{1}", tempStudent.ProductLevelId, ','); //最后上课时间 var endAvailableTime = dtEndDate.AddHours(-1).ToString("yyyyMMddHHmm"); var selectTeacher = edbAcs.Teacher.Where(a => a.WorkDate == tempStudent.WorkDate && a.TeachRange.Contains(strTeachRange) && a.AvailableTime.Contains(itemAvailableTime) && a.AvailableTime.Contains(endAvailableTime) && a.AvailableTime != "" && a.BranchId == branchId && a.AvailableTime != null && a.MaxTaskNum > a.CurrTaskNum); //判断是否有教师 if (selectTeacher.Count() > 0) { //判断是否存在特殊配置要求该课节只能是外教或者中教上 if (edbAcs.TeacherProductLevelCourseTypeCourseConfig.Any(a => a.BranchId == branchId && a.ProductLevelCourseTypeCourseID == plctc.Id && a.Status == ConvertEnum.StatusTypeForActive)) { //获取特殊配置 var tplctcc = edbAcs.TeacherProductLevelCourseTypeCourseConfig.SingleOrDefault(p => p.BranchId == branchId && p.ProductLevelCourseTypeCourseID == plctc.Id && p.Status == ConvertEnum.StatusTypeForActive); //判断老师的类别跟特殊配置要求的列表是否是一致 if (!selectTeacher.Any(a => a.TeacherTypeId == tplctcc.TeacherType)) { //不符合,跳出 tempStudent.Remark = "没有符合条件的教师!"; continue; } else { //获取教师 modelTeacher = selectTeacher.OrderByDescending(p => p.IsFullTime) .OrderBy(p => p.CurrTaskNum) .FirstOrDefault(a => a.TeacherTypeId == tplctcc.TeacherType); } } else { //获取教师 modelTeacher = selectTeacher.OrderByDescending(p => p.IsFullTime) .OrderBy(p => p.CurrTaskNum).FirstOrDefault(); } } else { tempStudent.Remark = "没有符合条件的教师!"; continue;//没有符合条件的教师,跳出,执行下一次循环 } //验证教师是否已存在相同时间段日程 if (modelTeacher != null) { if (Eme.UserBLL.GetExistUserScheduleByTeacherId(modelTeacher.Id, dtDate, dtEndDate).Count() > 0) { tempStudent.Remark = "没有符合条件的教师!"; continue; } } else { tempStudent.Remark = "没有符合条件的教师!"; continue; } #endregion #region 教室 //获取符合条件的第一个教室 var strProductCourseTypeId = string.Format(",{0},", plctc.ProductLevelCourseType.ProductCourseTypeId.ToString()); //匹配较大的教室 if (edbAcs.Classroom.Any(a => a.WorkDate == tempStudent.WorkDate && a.ClassroomTypeForProductCourseType.Contains(strProductCourseTypeId) && a.MaxBookNum > 1 && a.MaxBookNum >= itemUnfinishedCourses.NumCount && a.BranchId == branchId && !a.UnavailableTime.Contains(itemAvailableTime))) { //获取教室 modelClassroom = edbAcs.Classroom.OrderBy(p => p.MaxBookNum) .ThenByDescending(p => p.ClassroomTypeForProductCourseType) .FirstOrDefault(a => a.WorkDate == tempStudent.WorkDate && a.ClassroomTypeForProductCourseType.Contains(strProductCourseTypeId) && a.MaxBookNum > 1 && a.MaxBookNum >= itemUnfinishedCourses.NumCount && a.BranchId == branchId && !a.UnavailableTime.Contains(itemAvailableTime)); } else if (edbAcs.Classroom.Any(a => a.WorkDate == tempStudent.WorkDate && a.ClassroomTypeForProductCourseType.Contains(strProductCourseTypeId) && a.MaxBookNum > 1 && a.MaxBookNum <= itemUnfinishedCourses.NumCount && a.BranchId == branchId && !a.UnavailableTime.Contains(itemAvailableTime)))//匹配较小的教室 { //获取教室 modelClassroom = edbAcs.Classroom.OrderByDescending(p => p.MaxBookNum) .ThenByDescending(p => p.ClassroomTypeForProductCourseType) .FirstOrDefault(a => a.WorkDate == tempStudent.WorkDate && a.ClassroomTypeForProductCourseType.Contains(strProductCourseTypeId) && a.MaxBookNum > 1 && a.BranchId == branchId && a.MaxBookNum <= itemUnfinishedCourses.NumCount && !a.UnavailableTime.Contains(itemAvailableTime)); } else { tempStudent.Remark = "没有符合条件的教室!"; continue;//没有符合条件的教室,跳出,执行下一次循环 } // 验证教室是否同一时间段被占用 if (Eme.StudyBLL.IsExistClassroomForArrangeCourse(modelClassroom.Id, dtDate, dtEndDate)) { tempStudent.Remark = "没有符合条件的教室!"; continue; } #endregion var theCount = itemUnfinishedCourses.NumCount * 1.0f / modelClassroom.MaxBookNum; if (tempStudent.PlanNum.HasValue) planNum = tempStudent.PlanNum.Value; //50% 或者是 25% 以上的学员符合的话,都排 if (theCount < float.Parse(countPercent[planNum])) { tempStudent.Remark = "没有相同需求的学生!"; continue; } #region 进行匹配 学生,教师,教室 //50% 或者是 25% 以上的学员符合的话,都排 if (theCount >= float.Parse(countPercent[planNum])) { //创建 ArrangeCourse var modelArrangeCourse = new Model.Acs.ArrangeCourse() { BranchId = branchId, TeacherId = modelTeacher.TeacherId.Value, ArrangeCourseId = 0, ClassroomId = modelClassroom.ClassroomId, ProductLevelCourseTypeCourseId = unfinishedCoursesToInt,//当前未上过的课程 BeginTime = dtDate, IsSuccessful = false, Status = ConvertEnum.StatusTypeForActive, IsSystem = true, CreateBy = createBy, ClassTime = (plctc.Course.ClassTime / 60), CreateTime = DateTime.Now }; #region 返回值拼接 outList.Add("StudentNames", tempStudent.StudentName);//学员名称 outList.Add("ProductLevelName", tempStudent.ProductLevelName);//级别名称 outList.Add("ClassroomName", modelClassroom.ClassroomName);//教室名称 outList.Add("ClassroomTypeName", modelClassroom.ClassroomTypeName);//教室类型 outList.Add("TeacherName", modelTeacher.TeacherName);//教师名称 outList.Add("TeacherTypeName", modelTeacher.TeacherTypeName);//教师类型 outList.Add("BeginDate", dtDate.ToString("yyyy/MM/dd HH:mm"));//上课时间 outList.Add("ProductLevelCourseTypeCourseName", ProductLevelCourseTypeCourseName);//课程名称 modelArrangeCourse.ProductLevelId = tempStudent.ProductLevelId;//学员级别 modelArrangeCourse.ProductLevelName = tempStudent.ProductLevelName;//级别名称 modelArrangeCourse.ClassroomName = modelClassroom.ClassroomName;//教室名称 modelArrangeCourse.ClassroomTypeId = modelClassroom.ClassroomTypeId; modelArrangeCourse.ClassroomTypeName = modelClassroom.ClassroomTypeName;//教室类型 modelArrangeCourse.TeacherName = modelTeacher.TeacherName;//教师名称 modelArrangeCourse.TeacherTypeId = modelTeacher.TeacherTypeId; modelArrangeCourse.TeacherTypeName = modelTeacher.TeacherTypeName;//教师类型 modelArrangeCourse.ProductLevelCourseTypeCourseName = ProductLevelCourseTypeCourseName;//课程名称 modelArrangeCourse.ProductLevelCourseTypeId = plctc.ProductLevelCourseTypeId;//类型ID modelArrangeCourse.ProductLevelCourseTypeName = "";//类型名称 #endregion modelArrangeCourse.StudentIds = string.Format(",{0}", tempStudent.StudentId);//在原学员ID基础上拼接学员ID modelArrangeCourse.StudentNames = string.Format(",{0}", tempStudent.StudentName);//在原学员名称基础上拼接学员名称 /////获取时间和未上课程都符合的学生 var studentList = studentLikeList.Where(a => a.AvailableTime.Contains(itemAvailableTime) && a.UnfinishedCourses.Contains(unfinishedCoursesToString)) .OrderBy(p => p.WorkDate).ThenByDescending(p => p.IsFirst).ThenBy(p => p.ArrangeCourseOrder).ToList(); //学员ID拼接 for (var num = 0; num < (modelClassroom.MaxBookNum - 1); num++) { if (num < (itemUnfinishedCourses.NumCount - 1)) { modelArrangeCourse.StudentIds = string.Format("{0},{1}", modelArrangeCourse.StudentIds, studentList[num].StudentId); outList["StudentNames"] = string.Format("{0},{1}", outList["StudentNames"], studentList[num].StudentName); //学员名称返回值拼接 //学员名称 modelArrangeCourse.StudentNames = outList["StudentNames"]; } } //写入匹配好的ArrangeCourse edbAcs.Entry(modelArrangeCourse).State = EntityState.Added; edbAcs.Configuration.ValidateOnSaveEnabled = false; result = edbAcs.SaveChanges() > 0; edbAcs.Configuration.ValidateOnSaveEnabled = true; if (result) //需要移除的课程 { removeUnfinishedCourses = unfinishedCoursesToString; removeAvailableTime = itemAvailableTime; //把匹配的学生至为无效 for (var num = 0; num < (modelClassroom.MaxBookNum - 1); num++) { if (num < (itemUnfinishedCourses.NumCount - 1)) { studentList[num].Status = ConvertEnum.StatusTypeForDelete; studentList[num].UnfinishedCourses = studentList[num].UnfinishedCourses.Replace(unfinishedCoursesToString, ","); studentList[num].AvailableTime = studentList[num].AvailableTime.Replace("," + itemAvailableTime, ","); studentList[num].Remark = "匹配到合适的课程:" + unfinishedCoursesToString; studentList[num].UpdateBy = createBy; studentList[num].UpdateTime = DateTime.Now; if (studentList[num].PlanNum.HasValue) studentList[num].PlanNum = studentList[num].PlanNum + 1; else studentList[num].PlanNum = 1; studentList[num].CurrTaskNum = studentList[num].CurrTaskNum + 1;//增加课量 edbAcs.Entry(studentList[num]).State = EntityState.Modified; edbAcs.SaveChanges(); //移除上过的课程 var removeStudentId = studentList[num].StudentId; var removeStudentList = edbAcs.Student.Where(p => p.StudentId == removeStudentId && p.WorkDate >= beginDate && p.WorkDate <= endDate).ToList(); foreach (var itemRemoveStudent in removeStudentList) { itemRemoveStudent.UnfinishedCourses = itemRemoveStudent.UnfinishedCourses.Replace(unfinishedCoursesToString, ","); itemRemoveStudent.AvailableTime = itemRemoveStudent.AvailableTime.Replace("," + itemAvailableTime, ","); itemRemoveStudent.UpdateBy = createBy; itemRemoveStudent.UpdateTime = DateTime.Now; itemRemoveStudent.CurrTaskNum = studentList[num].CurrTaskNum;//增加课量 edbAcs.Entry(itemRemoveStudent).State = EntityState.Modified; } edbAcs.SaveChanges(); } } #region 给教室加上不可用时间 TimeSpan dtTimeSpan = dtEndDate - dtDate; for (var dtNum = 0; dtNum < dtTimeSpan.Hours; dtNum++) { modelClassroom.UnavailableTime = string.Format("{0},{1}", modelClassroom.UnavailableTime, dtDate.AddHours(dtNum).ToString("yyyyMMddHHmm")); } modelClassroom.UpdateBy = createBy; modelClassroom.UpdateTime = DateTime.Now; edbAcs.Entry(modelClassroom).State = EntityState.Modified; edbAcs.SaveChanges(); #endregion #region 给老师加上任务量,还有把相应的可用时间移除 modelTeacher.CurrTaskNum = modelTeacher.CurrTaskNum + 1; for (var dtNum = 0; dtNum < dtTimeSpan.Hours; dtNum++) { modelTeacher.AvailableTime = modelTeacher.AvailableTime.Replace("," + dtDate.AddHours(dtNum).ToString("yyyyMMddHHmm"), ""); } modelTeacher.UpdateBy = createBy; modelTeacher.UpdateTime = DateTime.Now; edbAcs.Entry(modelTeacher).State = EntityState.Modified; edbAcs.SaveChanges(); #endregion break; } } else { tempStudent.Remark = "没有相同需求的学生!"; continue; } #endregion } } #endregion //需要把安排后的课程移除 if (removeUnfinishedCourses != "") { tempStudent.UnfinishedCourses = tempStudent.UnfinishedCourses.Replace(removeUnfinishedCourses, ","); tempStudent.AvailableTime = tempStudent.AvailableTime.Replace("," + removeAvailableTime, ","); tempStudent.CurrTaskNum = tempStudent.CurrTaskNum + 1;//增加课量 tempStudent.Remark = "匹配到合适的课程:" + removeUnfinishedCourses; } else { //绝对优先,一定要匹配课程 if (tempStudent.IsFirst) { return IsFirstDisposeArrangeCourse(branchId, beginDate, endDate, tempStudent, createBy, out outList); } } tempStudent.Status = ConvertEnum.StatusTypeForDelete; if (tempStudent.PlanNum.HasValue) { tempStudent.PlanNum = tempStudent.PlanNum.Value + 1; } else { tempStudent.PlanNum = 1; } tempStudent.UpdateBy = createBy; tempStudent.UpdateTime = DateTime.Now; edbAcs.Entry(tempStudent).State = EntityState.Modified; result = edbAcs.SaveChanges() > 0; try { //移除上过的课程 if (removeUnfinishedCourses != "") { //移除上过的课程 var studentRemoveList = edbAcs.Student.Where(p => p.StudentId == tempStudent.StudentId && p.WorkDate >= beginDate && p.WorkDate <= endDate).ToList(); foreach (var itemStudentRemove in studentRemoveList) { itemStudentRemove.UnfinishedCourses = itemStudentRemove.UnfinishedCourses.Replace(removeUnfinishedCourses, ","); itemStudentRemove.AvailableTime = itemStudentRemove.AvailableTime.Replace("," + removeAvailableTime, ","); itemStudentRemove.CurrTaskNum = tempStudent.CurrTaskNum;//增加课量 itemStudentRemove.UpdateBy = createBy; itemStudentRemove.UpdateTime = DateTime.Now; edbAcs.Entry(itemStudentRemove).State = EntityState.Modified; edbAcs.Configuration.ValidateOnSaveEnabled = false; edbAcs.SaveChanges(); edbAcs.Configuration.ValidateOnSaveEnabled = true; } } } catch (Exception ex) { var edbAcsCopy = new Model.Acs.EmeAcsEntities(); tempStudent = edbAcsCopy.Student.First(p => p.Id == tempStudent.Id); if (tempStudent.PlanNum.HasValue) { tempStudent.PlanNum = tempStudent.PlanNum.Value + 1; } else { tempStudent.PlanNum = 1; } tempStudent.Status = ConvertEnum.StatusTypeForDelete; tempStudent.Remark = ex.ToString(); edbAcsCopy.Entry(tempStudent).State = EntityState.Modified; edbAcsCopy.Configuration.ValidateOnSaveEnabled = false; edbAcsCopy.SaveChanges(); edbAcsCopy.Configuration.ValidateOnSaveEnabled = true; return true;//继续执行下一个学生 } return result; } catch (Exception e) { var edbAcsCopy = new Model.Acs.EmeAcsEntities(); tempStudent = edbAcsCopy.Student.First(p => p.Id == tempStudent.Id); if (tempStudent.PlanNum.HasValue) { tempStudent.PlanNum = tempStudent.PlanNum.Value + 1; } else { tempStudent.PlanNum = 1; } tempStudent.Status = ConvertEnum.StatusTypeForDelete; tempStudent.Remark = e.ToString(); edbAcsCopy.Entry(tempStudent).State = EntityState.Modified; edbAcsCopy.Configuration.ValidateOnSaveEnabled = false; edbAcsCopy.SaveChanges(); edbAcsCopy.Configuration.ValidateOnSaveEnabled = true; //// 异常日志消息队列 //Common.MSMQ.QueueManager.AddExceptionLog(new ExceptionLogs //{ // ExceptionType = CommonHelper.To<int>(ExceptionType.Function), // Message = string.Format("StudyBLL-DisposeArrangeCourse:{0};{1};{2}", e.Message, e.InnerException.Message, e.HelpLink), // IsTreat = false, // CreateTime = DateTime.Now //}); return true;//继续执行下一个学生 } }
/// <summary> /// 作者:Primo /// 日期:2014.08.12 /// 描述:匹配至 ArrangeCourse /// </summary> /// <param name="branchId"></param> /// <param name="beginDate"></param> /// <param name="endDate"></param> /// <param name="createBy"></param> /// <returns></returns> public static bool DisposeArrangeCourse1(int branchId, DateTime beginDate, DateTime endDate, int createBy, out Dictionary<string, string> outList) { //初始化状态 var result = false; var removeUnfinishedCourses = ""; //匹配成功后需要移除的课程 //课程名称 var ProductLevelCourseTypeCourseName = ""; outList = new Dictionary<string, string>(); var edbAcs = new Model.Acs.EmeAcsEntities(); try { var countPercent = Common.Global.CountPercent.ToString().Split(',');//匹配次数,必须要有一个float值 var planNum = 0; //获取第一个学员 var tempStudent = edbAcs.Student.OrderBy(p => p.WorkDate) .ThenByDescending(p => p.IsFirst) .ThenBy(p => p.ArrangeCourseOrder) .FirstOrDefault(p => p.BranchId == branchId && p.WorkDate >= beginDate && p.WorkDate <= endDate && p.CurrTaskNum <= Common.Global.MaxNum && p.Status == ConvertEnum.StatusTypeForActive); //表示已经循环所有学员了 if (tempStudent == null) { return BranchBLL.UpateStudentByPlanNum(countPercent.Count(), branchId, beginDate, endDate, createBy); } //未上过的课程 var unfinishedCoursesList = tempStudent.UnfinishedCourses.Trim(',').Split(','); //循环未上过的课 foreach (var itemUnfinishedCourses in unfinishedCoursesList) { if (result)//result 为 true ,说明已经找到了适合的 break; if (tempStudent.CurrTaskNum >= Common.Global.MaxNum)//最多匹配三节课给他 { tempStudent.Status = ConvertEnum.StatusTypeForDelete; tempStudent.Remark = "达到最大匹配课时数!"; edbAcs.Entry(tempStudent).State = EntityState.Modified; edbAcs.Configuration.ValidateOnSaveEnabled = false; result = edbAcs.SaveChanges() > 0; edbAcs.Configuration.ValidateOnSaveEnabled = true; break; } if (itemUnfinishedCourses.Trim() == "")//没有可匹配的课程 { tempStudent.Remark = "没有可匹配的课程!"; break; } //未上过的课程转数字类型 var itemUnfinishedCoursesToInt = Convert.ToInt32(itemUnfinishedCourses); //学员可上课时间 var availableTimeList = tempStudent.AvailableTime.Trim(',').Split(','); //循环上课时间去找适合的教室 foreach (var itemAvailableTime in availableTimeList) { //教室 var modelClassroom = new Model.Acs.Classroom(); //教师 var modelTeacher = new Model.Acs.Teacher(); #region 学员 //未上过的课 var strUnfinishedCourses = string.Format(",{0},", itemUnfinishedCourses); //可上课的时间 var strAvailableTime = string.Format(",{0},", itemAvailableTime); //获取类似条件的学生 var studentList = (from a in edbAcs.Student where a.WorkDate == tempStudent.WorkDate && a.UnfinishedCourses.Contains(strUnfinishedCourses) && a.AvailableTime.Contains(strAvailableTime) && a.StudentId != tempStudent.StudentId && a.BranchId == branchId && a.CurrTaskNum < Common.Global.MaxNum //最多只能匹配课节数 select a).ToList(); //符合条件的学员个数 var studentListCount = (studentList.Count() + 1); //如果没有类似的学员,则直接跳过,执行下一次循环 if (studentListCount == 1) continue; #endregion //上课时间拼接 var dtDate = Convert.ToDateTime(string.Format("{0}/{1}/{2} {3}:{4}", itemAvailableTime.Substring(0, 4), itemAvailableTime.Substring(4, 2), itemAvailableTime.Substring(6, 2), itemAvailableTime.Substring(8, 2), itemAvailableTime.Substring(10, 2))); var dtEndDate = dtDate;// 课程结束时间 var edb = new Model.Eme.EmeEntities(); //查询 ProductLevelCourseTypeCourse var modelProductLevelCourseTypeCourse = edb.ProductLevelCourseTypeCourse.SingleOrDefault(p => p.Id == itemUnfinishedCoursesToInt); var plctc = edb.ProductLevelCourseTypeCourse.Single(p => p.Id == itemUnfinishedCoursesToInt); dtEndDate = dtDate.AddMinutes(plctc.Course.ClassTime); ProductLevelCourseTypeCourseName = plctc.Course.EName; if (plctc.Course.EName.Contains("LMW"))//不排LMW课程 continue; #region 教室 //获取符合条件的第一个教室 var strProductCourseTypeId = string.Format(",{0},", modelProductLevelCourseTypeCourse.ProductLevelCourseType.ProductCourseTypeId.ToString()); #region 教室注释 //匹配较大的教室 if (edbAcs.Classroom.Any(a => a.WorkDate == tempStudent.WorkDate && a.ClassroomTypeForProductCourseType.Contains(strProductCourseTypeId) && a.MaxBookNum > 1 && a.MaxBookNum >= studentListCount && a.BranchId == branchId && !a.UnavailableTime.Contains(itemAvailableTime))) { //获取教室 modelClassroom = edbAcs.Classroom.OrderBy(p => p.MaxBookNum) .ThenByDescending(p => p.ClassroomTypeForProductCourseType) .FirstOrDefault(a => a.WorkDate == tempStudent.WorkDate && a.ClassroomTypeForProductCourseType.Contains(strProductCourseTypeId) && a.MaxBookNum > 1 && a.MaxBookNum >= studentListCount && a.BranchId == branchId && !a.UnavailableTime.Contains(itemAvailableTime)); } else if (edbAcs.Classroom.Any(a => a.WorkDate == tempStudent.WorkDate && a.ClassroomTypeForProductCourseType.Contains(strProductCourseTypeId) && a.MaxBookNum > 1 && a.MaxBookNum <= studentListCount && a.BranchId == branchId && !a.UnavailableTime.Contains(itemAvailableTime)))//匹配较小的教室 { //获取教室 modelClassroom = edbAcs.Classroom.OrderByDescending(p => p.MaxBookNum) .ThenByDescending(p => p.ClassroomTypeForProductCourseType) .FirstOrDefault(a => a.WorkDate == tempStudent.WorkDate && a.ClassroomTypeForProductCourseType.Contains(strProductCourseTypeId) && a.MaxBookNum > 1 && a.BranchId == branchId && a.MaxBookNum <= studentListCount && !a.UnavailableTime.Contains(itemAvailableTime)); } else { tempStudent.Remark = "没有符合条件的教室!"; continue;//没有符合条件的教室,跳出,执行下一次循环 } #endregion // 验证教室是否同一时间段被占用 if (Eme.StudyBLL.IsExistClassroomForArrangeCourse(modelClassroom.Id, dtDate, dtEndDate)) { tempStudent.Remark = "没有符合条件的教室!"; continue; } #endregion #region 教师 //获取符合条件的第一个获取教师 var strTeachRange = string.Format(",{0}{1}", tempStudent.ProductLevelId, ','); //最后上课时间 var endAvailableTime = dtEndDate.AddHours(-1).ToString("yyyyMMddHHmm"); var selectTeacher = edbAcs.Teacher.Where(a => a.WorkDate == tempStudent.WorkDate && a.TeachRange.Contains(strTeachRange) && a.AvailableTime.Contains(itemAvailableTime) && a.AvailableTime.Contains(endAvailableTime) && a.AvailableTime != "" && a.BranchId == branchId && a.AvailableTime != null && a.MaxTaskNum > a.CurrTaskNum); //判断是否有教师 if (selectTeacher.Count() > 0) { //判断是否存在特殊配置要求该课节只能是外教或者中教上 if (edbAcs.TeacherProductLevelCourseTypeCourseConfig.Any(a => a.BranchId == branchId && a.ProductLevelCourseTypeCourseID == plctc.Id && a.Status == ConvertEnum.StatusTypeForActive)) { //获取特殊配置 var tplctcc = edbAcs.TeacherProductLevelCourseTypeCourseConfig.SingleOrDefault(p => p.BranchId == branchId && p.ProductLevelCourseTypeCourseID == plctc.Id && p.Status == ConvertEnum.StatusTypeForActive); //判断老师的类别跟特殊配置要求的列表是否是一致 if (!selectTeacher.Any(a => a.TeacherTypeId == tplctcc.TeacherType)) { //不符合,跳出 tempStudent.Remark = "没有符合条件的教师!"; continue; } else { //获取教师 modelTeacher = selectTeacher.OrderByDescending(p => p.IsFullTime) .OrderBy(p => p.CurrTaskNum) .FirstOrDefault(a => a.TeacherTypeId == tplctcc.TeacherType); } } else { //获取教师 modelTeacher = selectTeacher.OrderByDescending(p => p.IsFullTime) .OrderBy(p => p.CurrTaskNum).FirstOrDefault(); } } else { tempStudent.Remark = "没有符合条件的教师!"; continue;//没有符合条件的教师,跳出,执行下一次循环 } //验证教师是否已存在相同时间段日程 if (Eme.UserBLL.GetExistUserScheduleByTeacherId(modelTeacher.Id, dtDate, dtEndDate).Count() > 0) { tempStudent.Remark = "没有符合条件的教师!"; continue; } #endregion #region 进行匹配 学生,教师,教室 var theCount = studentListCount * 1.0f / modelClassroom.MaxBookNum; if (tempStudent.PlanNum.HasValue) planNum = tempStudent.PlanNum.Value; if (theCount >= float.Parse(countPercent[planNum]))//50% 或者是 25% 以上的学员符合的话,都排 { //创建 ArrangeCourse var modelArrangeCourse = new Model.Acs.ArrangeCourse() { BranchId = branchId, TeacherId = modelTeacher.TeacherId.Value, ArrangeCourseId = 0, ClassroomId = modelClassroom.ClassroomId, ProductLevelCourseTypeCourseId = Convert.ToInt32(itemUnfinishedCourses),//当前未上过的课程 BeginTime = dtDate, IsSuccessful = false, Status = ConvertEnum.StatusTypeForActive, IsSystem = true, CreateBy = createBy, ClassTime = (plctc.Course.ClassTime / 60), CreateTime = DateTime.Now }; #region 返回值拼接 outList.Add("StudentNames", tempStudent.StudentName);//学员名称 outList.Add("ProductLevelName", tempStudent.ProductLevelName);//级别名称 outList.Add("ClassroomName", modelClassroom.ClassroomName);//教室名称 outList.Add("ClassroomTypeName", modelClassroom.ClassroomTypeName);//教室类型 outList.Add("TeacherName", modelTeacher.TeacherName);//教师名称 outList.Add("TeacherTypeName", modelTeacher.TeacherTypeName);//教师类型 outList.Add("BeginDate", dtDate.ToString("yyyy/MM/dd HH:mm"));//上课时间 outList.Add("ProductLevelCourseTypeCourseName", ProductLevelCourseTypeCourseName);//课程名称 modelArrangeCourse.ProductLevelId = tempStudent.ProductLevelId;//学员级别 modelArrangeCourse.ProductLevelName = tempStudent.ProductLevelName;//级别名称 modelArrangeCourse.ClassroomName = modelClassroom.ClassroomName;//教室名称 modelArrangeCourse.ClassroomTypeId = modelClassroom.ClassroomTypeId; modelArrangeCourse.ClassroomTypeName = modelClassroom.ClassroomTypeName;//教室类型 modelArrangeCourse.TeacherName = modelTeacher.TeacherName;//教师名称 modelArrangeCourse.TeacherTypeId = modelTeacher.TeacherTypeId; modelArrangeCourse.TeacherTypeName = modelTeacher.TeacherTypeName;//教师类型 modelArrangeCourse.ProductLevelCourseTypeCourseName = ProductLevelCourseTypeCourseName;//课程名称 #endregion modelArrangeCourse.StudentIds = string.Format(",{0}", tempStudent.StudentId);//在原学员ID基础上拼接学员ID modelArrangeCourse.StudentNames = string.Format(",{0}", tempStudent.StudentName);//在原学员名称基础上拼接学员名称 //学员ID拼接 for (var num = 0; num < (modelClassroom.MaxBookNum - 1); num++) { if (num < (studentListCount - 1)) { modelArrangeCourse.StudentIds = string.Format("{0},{1}", modelArrangeCourse.StudentIds, studentList[num].StudentId); outList["StudentNames"] = string.Format("{0},{1}", outList["StudentNames"], studentList[num].StudentName); //学员名称返回值拼接 //学员名称 modelArrangeCourse.StudentNames = outList["StudentNames"]; } } //写入匹配好的ArrangeCourse edbAcs.Entry(modelArrangeCourse).State = EntityState.Added; edbAcs.Configuration.ValidateOnSaveEnabled = false; result = edbAcs.SaveChanges() > 0; edbAcs.Configuration.ValidateOnSaveEnabled = true; if (result) { //需要移除的课程 removeUnfinishedCourses = itemUnfinishedCourses; //把匹配的学生至为无效 for (var num = 0; num < (modelClassroom.MaxBookNum - 1); num++) { if (num < (studentListCount - 1)) { studentList[num].Status = ConvertEnum.StatusTypeForDelete; studentList[num].UnfinishedCourses = studentList[num].UnfinishedCourses.Replace("," + itemUnfinishedCourses + ",", ","); studentList[num].Remark = "匹配到合适的课程:" + itemUnfinishedCourses; studentList[num].UpdateBy = createBy; studentList[num].UpdateTime = DateTime.Now; studentList[num].CurrTaskNum = studentList[num].CurrTaskNum + 1;//增加课量 edbAcs.Entry(studentList[num]).State = EntityState.Modified; edbAcs.SaveChanges(); //移除上过的课程 var removeStudentId = studentList[num].StudentId; var removeStudentList = edbAcs.Student.Where(p => p.StudentId == removeStudentId && p.WorkDate >= beginDate && p.WorkDate <= endDate).ToList(); foreach (var itemRemoveStudent in removeStudentList) { itemRemoveStudent.UnfinishedCourses = itemRemoveStudent.UnfinishedCourses.Replace("," + itemUnfinishedCourses + ",", ","); itemRemoveStudent.UpdateBy = createBy; itemRemoveStudent.UpdateTime = DateTime.Now; itemRemoveStudent.CurrTaskNum = studentList[num].CurrTaskNum;//增加课量 edbAcs.Entry(itemRemoveStudent).State = EntityState.Modified; edbAcs.SaveChanges(); } } } #region 给教室加上不可用时间 TimeSpan dtTimeSpan = dtEndDate - dtDate; for (var dtNum = 0; dtNum < dtTimeSpan.Hours; dtNum++) { modelClassroom.UnavailableTime = string.Format("{0},{1}", modelClassroom.UnavailableTime, dtDate.AddHours(dtNum).ToString("yyyyMMddHHmm")); } modelClassroom.UpdateBy = createBy; modelClassroom.UpdateTime = DateTime.Now; edbAcs.Entry(modelClassroom).State = EntityState.Modified; edbAcs.SaveChanges(); #endregion #region 给老师加上任务量,还有把相应的可用时间移除 modelTeacher.CurrTaskNum = modelTeacher.CurrTaskNum + 1; for (var dtNum = 0; dtNum < dtTimeSpan.Hours; dtNum++) { modelTeacher.AvailableTime = modelTeacher.AvailableTime.Replace("," + dtDate.AddHours(dtNum).ToString("yyyyMMddHHmm"), ""); } modelTeacher.UpdateBy = createBy; modelTeacher.UpdateTime = DateTime.Now; edbAcs.Entry(modelTeacher).State = EntityState.Modified; edbAcs.SaveChanges(); #endregion break; } } else { tempStudent.Remark = "没有相同需求的学生!"; continue; } #endregion } } //把安排后的课程移除 if (removeUnfinishedCourses != "") { tempStudent.UnfinishedCourses = tempStudent.UnfinishedCourses.Replace("," + removeUnfinishedCourses, ""); tempStudent.CurrTaskNum = tempStudent.CurrTaskNum + 1;//增加课量 tempStudent.Remark = "匹配到合适的课程:" + removeUnfinishedCourses; } else { //绝对优先,一定要匹配课程 if (tempStudent.IsFirst) { return IsFirstDisposeArrangeCourse(branchId, beginDate, endDate, tempStudent, createBy, out outList); } } tempStudent.Status = ConvertEnum.StatusTypeForDelete; if (tempStudent.PlanNum.HasValue) { tempStudent.PlanNum = tempStudent.PlanNum + 1; } else { tempStudent.PlanNum = planNum + 1; } tempStudent.UpdateBy = createBy; tempStudent.UpdateTime = DateTime.Now; edbAcs.Entry(tempStudent).State = EntityState.Modified; result = edbAcs.SaveChanges() > 0; try { //移除上过的课程 if (removeUnfinishedCourses != "") { //移除上过的课程 var studentRemoveList = edbAcs.Student.Where(p => p.StudentId == tempStudent.StudentId && p.WorkDate >= beginDate && p.WorkDate <= endDate).ToList(); foreach (var itemStudentRemove in studentRemoveList) { itemStudentRemove.UnfinishedCourses = itemStudentRemove.UnfinishedCourses.Replace("," + removeUnfinishedCourses + ",", ","); itemStudentRemove.CurrTaskNum = tempStudent.CurrTaskNum;//增加课量 itemStudentRemove.UpdateBy = createBy; itemStudentRemove.UpdateTime = DateTime.Now; edbAcs.Entry(itemStudentRemove).State = EntityState.Modified; edbAcs.Configuration.ValidateOnSaveEnabled = false; edbAcs.SaveChanges(); edbAcs.Configuration.ValidateOnSaveEnabled = true; } } } catch { } return result; } catch (Exception e) { // 异常日志消息队列 Common.MSMQ.QueueManager.AddExceptionLog(new ExceptionLogs { ExceptionType = CommonHelper.To<int>(ExceptionType.Function), Message = string.Format("StudyBLL-DisposeArrangeCourse:{0};{1};{2}", e.Message, e.InnerException.Message, e.HelpLink), IsTreat = false, CreateTime = DateTime.Now }); return false; } }
/// <summary> /// 作者:Primo /// 日期:2014.07.29 /// 描述:根据中心区域ID获取教室,重新在Eme库整理后返回 /// </summary> /// <param name="branchId"></param> /// <param name="beginDate"></param> /// <param name="endDate"></param> /// <param name="createBy"></param> /// <param name="result"></param> /// <returns></returns> public static List<Model.Acs.Classroom> CreateClassroomByBranchId(int branchId, DateTime beginDate, DateTime endDate, int createBy, out bool result) { //教室数据集 var classroomList = new List<Model.Acs.Classroom>(); try { //用于计算时间相隔的天数 var dateNum = endDate - beginDate; //获取中心的所有教室 var modelClassroom = Eme.BranchBLL.GetClassroomList(branchId); //初始化 result = false; var edb = new Model.Acs.EmeAcsEntities(); for (var i = 0; i <= dateNum.Days; i++) { foreach (var item in modelClassroom) { var classroom = new Model.Acs.Classroom { BranchId = branchId, BranchName = item.Branch.CName, ClassroomId = item.Id, ClassroomName = item.ClassroomName, ClassroomTypeId = item.ClassroomTypeId, ClassroomTypeName = item.ClassroomType.CName, ClassroomTypeForProductCourseType = "", MaxBookNum = item.MaxBookNum, WorkDate = beginDate.AddDays(i), CreateBy = createBy, CreateTime = DateTime.Now, UnavailableTime = "", Status = ConvertEnum.StatusTypeForActive }; //教室不可用时间 1 if (item.Status == ConvertEnum.StatusTypeForInactive) { if (item.RenewTime.HasValue) if (beginDate.AddDays(i) <= item.RenewTime.Value) { var dateRenewTime = item.RenewTime.Value - beginDate.AddDays(i); var strRenewTime = new StringBuilder(); for (var renewTimeNum = 0; renewTimeNum <= dateRenewTime.Hours; renewTimeNum++) { strRenewTime.AppendFormat(",{0}", beginDate.AddDays(i).AddHours(renewTimeNum).ToString("yyyyMMddHHmm")); } classroom.UnavailableTime = strRenewTime.ToString(); } } //教室不可用时间 2 var modelExistClassroomForArrangeCourse = Eme.StudyBLL.GetExistClassroomForArrangeCourse(classroom.ClassroomId, beginDate.AddDays(i), beginDate.AddDays(i + 1)); foreach (var itemExistClassroomForArrangeCourse in modelExistClassroomForArrangeCourse) { classroom.UnavailableTime = string.Format("{0},{1}", classroom.UnavailableTime, itemExistClassroomForArrangeCourse.BeginTime.ToString("yyyyMMddHHmm")); } classroom.UnavailableTime = string.Format("{0},", classroom.UnavailableTime); //教室不可用时间3 var modelArrangeCourse = edb.ArrangeCourse.Where(p => p.BeginTime >= beginDate && p.BeginTime < endDate && p.BranchId == branchId && p.ClassroomId == item.Id); foreach (var itemArrangeCourse in modelArrangeCourse) { for (var iac = 0; iac < itemArrangeCourse.ClassTime.Value; iac++) { classroom.UnavailableTime = string.Format("{0},{1}", classroom.UnavailableTime, itemArrangeCourse.BeginTime.AddHours(iac).ToString("yyyyMMddHHmm")); } } //教室可上的课程 foreach (var itemClassroomTypeConfig in item.ClassroomType.ClassroomTypeConfig.Where(p => p.Status == ConvertEnum.StatusTypeForActive && p.BranchId == branchId)) { classroom.ClassroomTypeForProductCourseType = string.Format("{0},{1}", classroom.ClassroomTypeForProductCourseType, itemClassroomTypeConfig.ProductCourseTypeId); } //如果课程都是空的,则跳转 if (classroom.ClassroomTypeForProductCourseType.Trim(',').Length <= 0) { continue; } else { classroom.ClassroomTypeForProductCourseType = string.Format("{0},", classroom.ClassroomTypeForProductCourseType); } edb.Entry(classroom).State = EntityState.Added; classroomList.Add(classroom); edb.Configuration.ValidateOnSaveEnabled = false; edb.SaveChanges(); edb.Configuration.ValidateOnSaveEnabled = true; result = true; } } return classroomList; } catch (Exception e) { // 异常日志消息队列 Common.MSMQ.QueueManager.AddExceptionLog(new ExceptionLogs { ExceptionType = CommonHelper.To<int>(ExceptionType.Function), Message = string.Format("BranchBLL-DeleteClassroomByBranchId:{0};{1};{2}", e.Message, e.InnerException.Message, e.HelpLink), IsTreat = false, CreateTime = DateTime.Now }); result = false; return classroomList; } }