//totake: /// <summary> /// looks for available turn in activityTime,begin to search from the time she got. /// </summary> /// <param name="activityTime"></param> /// <param name="pushFlag"></param> /// <param name="timeToLookFor"></param> /// <returns></returns> private static TimeSpan?lookForAvailableTurn(ActivityTimeDTO activityTime, ref bool pushFlag, TimeSpan timeToLookFor) { List <customersInLine> line = TurnDal.GetLinePerActivityTime(activityTime.ActivityTimeId); pushFlag = false; double durationOfService = (double)activityTime.AvgServiceDuration; //מחשב את ההפרש בין זמן התחלת המשמרת לזמן שקבלנו בפרמטר ע"מ למצוא את הזמן שבו יתחיל לחפש תור int totalPassedShifts = (int)((timeToLookFor.TotalMinutes - activityTime.StartTime.TotalMinutes) / durationOfService) + 1; // פרמטר של פנוי שיהיה לפי ממוצע זמן ההמתנה const int maxStandbyTime = 3; const int maxPushedTimes = 2; TimeSpan hour; TimeSpan ts = TimeSpan.FromMinutes(durationOfService * totalPassedShifts); int index = 0, numOfStandbyTime = 0; timeToLookFor = activityTime.StartTime.Add(ts); line = line.Where(t => t.estimatedHour.TimeOfDay >= timeToLookFor).ToList(); //השעה המבוקשת פנויה if (line.Count() == 0 && timeToLookFor < activityTime.EndTime) { return(timeToLookFor); } ts = TimeSpan.FromMinutes(durationOfService); //לולאה המתחילה מהזמן שקבלה ומחפשת תור פנוי for (hour = timeToLookFor; numOfStandbyTime < maxStandbyTime && hour < activityTime.EndTime; hour = hour.Add(ts), numOfStandbyTime++) { if (TurnBL.IsAvailableHour(ref index, activityTime.NumOfWorkers, hour.Add(ts), line)) { return(hour); } index++; } //אם לא נמצא תור פנוי בתוך זמן ההמתנה המקסימלי שמאופשר: //אם כבר המשמרת הנוכחית תפוסה לגמרי if (hour >= activityTime.EndTime) { //מחפש את המשמרת הבאה הקרובה ביותר activityTime = ActivityTimeBL.GetNearestActivityTime(hour, activityTime.ServiceId); if (activityTime == null) { return(null); } //קורא בצורה רקורסיבית לפונקציה הנוכחית ומתחיל את החיפוש תור פנוי במשמרת החדשה מההתחלה return(lookForAvailableTurn(activityTime, ref pushFlag, activityTime.StartTime)); } //אם המשמרת עדיין לא נגמרה אבל הזמן המקסימלי להמתנה עבר ואין תור פנוי אז יש צורך לדחוף את התור בין התורים pushFlag = true; while (index < line.Count() && line[index].estimatedHour.TimeOfDay == hour && line[index].numOfPushTimes == maxPushedTimes) { index++; hour = hour.Add(ts); } return(hour); }
/// <summary> /// הפונקציה מקבלת שעה וקוד שירות ומחפשת את המשמרת בשירות הספציפי בהתאם לשעה שקיבלה /// </summary> /// <param name="time">שעה</param> /// <param name="serviceId">קוד שירות</param> /// <returns>קוד משמרת </returns> public static ActivityTimeDTO GetActivityTime(DateTime time, int serviceId) { List <ActivityTimeDTO> activityTimes = new List <ActivityTimeDTO>(); activityTimes = converters.ActivityTimeConverters.GetListActivityTimesDTO(ActivityTimeDal.GetActivityTimes(serviceId)); ActivityTimeDTO activityTime = activityTimes.FirstOrDefault(a => a.DayInWeek == ((int)time.DayOfWeek + 1) && a.StartTime <= time.TimeOfDay && a.EndTime > time.TimeOfDay && a.StartDate <= time && (a.EndDate == null || a.EndDate >= time)); if (activityTime == null) { activityTime = ActivityTimeBL.GetNearestActivityTime(time.TimeOfDay, serviceId); } return(activityTime); }