public static string BookAppointment(TurnDetailsDTO appointment) { try { ActivityTimeDTO activityTime = ActivityTimeBL.GetActivityTime(appointment.EstimatedHour, appointment.ServiceId); customersInLine turn = new customersInLine() { activityTimeId = activityTime.ActivityTimeId, custId = appointment.CustId, estimatedHour = appointment.EstimatedHour, preAlert = appointment.PreAlert, statusTurn = (int)eStatus.ADVANCE, enterHour = ConfigureHour(appointment.EstimatedHour, activityTime), isActive = true }; turn.TurnId = TurnDal.AddAppointment(turn); string verificationCode = TurnBL.CreateVerificationCode(turn); turn.verificationCode = verificationCode; TurnDal.UpdateTurn(turn); return(verificationCode); } catch (Exception) { throw; } }
//toask: סטטי או מופעים של המחלקות /// <summary> /// push the turns till the end of the activity time or stop if an empty time was found /// </summary> /// <param name="line">רשימת התורים שבהם אמורה להתבצע הדחיפה</param> /// <param name="time">שעת התור</param> /// <param name="activityTime"></param> /// <returns>num of pushed turns</returns> private static int pushTurns(List <customersInLine> line, TimeSpan time, ActivityTimeDTO activityTime) { TimeSpan ts = TimeSpan.FromMinutes((double)activityTime.AvgServiceDuration); int pushedTurnsCnt = 0; for (int i = 0; i < line.Count(); i++) { if ((line[i].statusTurn == (int)eStatus.IMMEDIATELY && line[i].estimatedHour.TimeOfDay >= time && line[i].estimatedHour.TimeOfDay < time.Add(ts)) || (line[i].statusTurn == (int)eStatus.ADVANCE && line[i].enterHour >= time && line[i].enterHour < time.Add(ts))) { pushedTurnsCnt++; if (line[i].statusTurn == (int)eStatus.IMMEDIATELY) { line[i].estimatedHour = line[i].estimatedHour.Add(ts); time = line[i].estimatedHour.TimeOfDay; } else { line[i].enterHour = line[i].enterHour.Value.Add(ts); time = line[i].enterHour.Value; } } else { break; } } return(pushedTurnsCnt); }
public static TurnDetailsDTO GetNearestTurn(int serviceId) { try { ActivityTimeDTO activityTime = ActivityTimeBL.GetActivityTime(DateTime.Now, serviceId); List <customersInLine> line = new List <customersInLine>(); if (activityTime != null) { line = TurnDal.GetLinePerActivityTime(activityTime.ActivityTimeId); if (line.Count() == 0) { throw new Exception("there is no turns now"); } } else { throw new Exception("there is no activityTime now"); } if (line[0].actualHour == null) { line[0].actualHour = new TimeSpan(); } return(converters.TurnDetailsConverters.GetTurnDetailsDTO(line[0])); } catch (Exception ex) { throw ex; } }
//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); }
/// <summary> /// /// </summary> /// <param name="businessId"></param> /// <returns>optional hour for immidate turn for the required business</returns> public static TimeSpan GetOptionalHourPerBusiness(int serviceId, TimeSpan timeToLookFor, ref bool pushFlag) { //to ask: ... לכתוב את החילוץ פעמיים DateTime time = DateTime.Now; time = time.Add(timeToLookFor - time.TimeOfDay); ActivityTimeDTO activityTime = ActivityTimeBL.GetActivityTime(time, serviceId); if (activityTime == null) { return(new TimeSpan()); } return((TimeSpan)lookForAvailableTurn(activityTime, ref pushFlag, timeToLookFor)); }
/// <summary> /// פונקציה המחשבת את השעה עבור תור הנקבע מראש ומטרתה לחסוך המתנה בזמני עומס /// </summary> /// <param name="date"></param> /// <param name="activityTime"></param> /// <returns>שעה לוגית </returns> public static TimeSpan ConfigureHour(DateTime date, ActivityTimeDTO activityTime) { if (activityTime.AverageNumOfWaitingPeople == null) { return(date.TimeOfDay); } TimeSpan logicHour = new TimeSpan(); //todoever: לקבוע את המשתנה בהתאם לאמינות-לסטית תקן int numOfIgnoreServiceDuration = 3; // int numOfSub = (int)(activityTime.AverageNumOfWaitingPeople.Value / activityTime.AvgServiceDuration - numOfIgnoreServiceDuration); logicHour = date.TimeOfDay.Subtract(TimeSpan.FromMinutes(activityTime.AvgServiceDuration.Value * numOfSub)); if (logicHour > activityTime.StartTime) { return(logicHour); } else { return(activityTime.StartTime); } }
/// <summary> /// הפונקציה קובעת תור זמני עבור שעה אופציונלית בעסק /// </summary> /// <param name="turn"></param> /// <returns>turn id</returns> public static int MakeTemporaryTurn(TurnInBusinessDTO turn, bool pushFlag, int custId) { DateTime time = DateTime.Now; ActivityTimeDTO activityTime = ActivityTimeBL.GetActivityTime(time.Add(turn.EstimatedHour.Value - time.TimeOfDay), turn.ServiceId); if (activityTime == null) { throw new Exception("אין משמרת פעילה כרגע"); } //todoever: להחליף בהמשך לאינדקסים try { int status = (int)eStatus.TEMPORARY; if (pushFlag) { status = (int)eStatus.TEMPORARY_WITH_PUSH; } customersInLine temporaryTurn = new customersInLine() { activityTimeId = activityTime.ActivityTimeId, custId = custId, enterHour = TimeSpan.FromMinutes(turn.Duration).Add(DateTime.Now.TimeOfDay), estimatedHour = DateTime.Today.Add(turn.EstimatedHour.Value), isActive = true, preAlert = 0, statusTurn = status }; int turnId = TurnDal.AddAppointment(temporaryTurn); return(turnId); } catch (Exception) { throw; } }