public static List <TimeSpan> GetOptionalHoursPerDay(int serviceId, DateTime date) { List <activityTime> activityTimes = ActivityTimeDal.GetActivityTimesByDay(serviceId, (int)date.DayOfWeek + 1); List <TimeSpan> optionalHours = new List <TimeSpan>(); int activityTimeIndex = 0; int index = 0; activityTimes.OrderBy(a => a.startTime); while (activityTimeIndex < activityTimes.Count()) { activityTime activityTime = activityTimes[activityTimeIndex]; List <customersInLine> line = TurnDal.GetLinePerActivityTime(activityTime.activityTimeId); double durationOfService = activityTime.avgServiceDuration.Value; TimeSpan ts = TimeSpan.FromMinutes(durationOfService); for (TimeSpan hour = activityTime.startTime; hour < activityTime.endTime; hour = hour.Add(ts)) { if (TurnBL.IsAvailableHour(ref index, activityTime.numOfWorkers, hour.Add(ts), line)) { if (!date.Equals(DateTime.Today) || hour.Add(ts) > DateTime.Now.TimeOfDay) { optionalHours.Add(hour); } } index++; } activityTimeIndex++; } return(optionalHours); }
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; } }
//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> /// confirm the turn and add it to the table /// </summary> /// <param name="turn"></param> /// <returns></returns> public static confirmResponse ConfirmImmediateTurn(TurnDetailsDTO turn) { List <customersInLine> line = new List <customersInLine>(); customersInLine newTurn = TurnDal.GetTurnByTurnId(turn.TurnId); line = TurnDal.GetLineByCustomer(newTurn.custId).Where(l => l.statusTurn == (int)eStatus.TEMPORARY || l.statusTurn == (int)eStatus.TEMPORARY_WITH_PUSH).ToList(); var x = line.Remove(line.First(t => t.TurnId == turn.TurnId)); if (newTurn.statusTurn == (int)eStatus.TEMPORARY_WITH_PUSH) { pushTurns(TurnDal.GetLinePerActivityTime(newTurn.activityTime.serviceId), newTurn.estimatedHour.TimeOfDay, ActivityTimeConverters.GetActivityTimeDTO(newTurn.activityTime)); } newTurn.statusTurn = (int)eStatus.IMMEDIATELY; string verificationCode = TurnBL.CreateVerificationCode(newTurn); newTurn.verificationCode = verificationCode; newTurn.preAlert = turn.PreAlert; TurnDal.UpdateTurn(newTurn); if (line.Count() > 0) { line.ForEach(a => TurnDal.DeleteTurn(a.TurnId)); } //טיפול במקרי קצה של תורים באותה שעה var allTurnsToCus = BL.CustInLineBL.GetTurnsToCustomer(newTurn.custId); allTurnsToCus = allTurnsToCus.Where(t => t.FullTime == newTurn.estimatedHour && t.TurnId != newTurn.TurnId).ToList(); confirmResponse confirmResponse = new DTO.confirmResponse() { turnId = turn.TurnId, verificationCode = verificationCode, isConflict = allTurnsToCus.Count != 0 ? true : false }; return(confirmResponse); }