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); }
/// <summary> /// /// </summary> /// <param name="activityTimeId"></param> public static void calcAvgServiceDuration(int activityTimeId) { DAL.activityTime activityTime = ActivityTimeDal.GetActivityTimeById(activityTimeId); double avg = activityTime.avgServiceDuration.Value; findUnusualSequences(activityTimeId, avg, true); }
public static List <DateTime> GetOptionalDaysPerService(int serviceId) { int day = (int)DateTime.Today.DayOfWeek + 1; DateTime date = DateTime.Now; List <activityTime> activityTimes = ActivityTimeDal.GetActivityTimes(serviceId); List <DateTime> optionalDays = new List <DateTime>(); var service = ServiceDal.GetServiceById(serviceId); int limitDays; if (service.kindOfPermission == true) { limitDays = service.limitDays.Value; } else { throw new Exception("בעסק זה לא ניתן לקבוע תורים מראש"); } for (int i = 0; i < limitDays; i++, day++) { if (day == 7) { day = 1; i++; limitDays++; } if (activityTimes.FirstOrDefault(a => a.dayInWeek == day) != null) { optionalDays.Add(date.AddDays(i)); } } return(optionalDays); }
/// <summary> /// find sequence of unusual turns /// </summary> /// <param name="activityTimeId"></param> public static void findUnusualSequences(int activityTimeId, double avg, bool IsServiceDuration) { var line = DAL.TurnDal.GetLinePerActivityTime(activityTimeId); List <int> significantDeviationIndexes = new List <int>(); DAL.activityTime activityTime = ActivityTimeDal.GetActivityTimeById(activityTimeId); int i = 0; bool isSignificantStatus = false; //שומרת ברשימה את האינדקסים של כל התחלה וסוף של תורים חריגים foreach (var item in line) { bool isSignificant = IsSignificantDeviation(item, avg, IsServiceDuration); if (isSignificant && !isSignificantStatus) { significantDeviationIndexes.Add(i); isSignificantStatus = true; } else if (!isSignificant && isSignificantStatus) { significantDeviationIndexes.Add(i - 1); isSignificantStatus = false; } i++; } int sum = 0; int index = 0; // עוברת על מערך האינדקסים ובודקת האם הרצף משמעותי -אם כן ממשיכה ובודקת האם קים הפרש משמעותי בינו לבין הרצף הבא //אם כן ממשיכה לסכום- אם לא בודקת האם זהו רצף ארוך מספיק כדי להכניסו לטבלת חריגים for (i = 1; i < significantDeviationIndexes.Count; i += 2) { int length = significantDeviationIndexes[i] - significantDeviationIndexes[i - 1]; if (length > minSequence) { sum += length; if (index == 0) { index = significantDeviationIndexes[i - 1]; } } if (significantDeviationIndexes[i + 1] - significantDeviationIndexes[i] > minSequence) {/* * if (sum >= minToDivide) * //todo: SetUnusualActivityTime(line.Skip(index).Take(significantDeviationIndexes[i]).ToList()); * else * //todo: UpdateStatistics(line.Skip(index).Take(significantDeviationIndexes[i]).ToList(), activityTime); * index = 0; * sum = 0; */ } } }
public static void calcAvgWaitingPeople(int activityTimeId) { //ההבדל בין הזמן המשוער לזמן האמיתי //הנתון המענין כמה דחיפות היו בזמן הזה צריך לדעת ממוצע דחיפות //numOfPushTimes לפי //מאד דומה לפונקציה למעלה //todo: כשמאתחלים משמרת חדשה לאפס נתונים DAL.activityTime activityTime = ActivityTimeDal.GetActivityTimeById(activityTimeId); double avg = activityTime.avgWaitings.Value; findUnusualSequences(activityTimeId, avg, false); }
/// <summary> /// get the avg per-day in all services of specific business /// </summary> /// <param name="businessId"></param> /// <returns></returns> public static List <List <double> > GetAvgForBusiness(int businessId) { //todo: check if it is cprrect List <List <double> > avgForService = new List <List <double> >(); var services = DAL.BusinessDal.GetBusinessById(businessId).services; if (services == null) { throw new Exception("there is no services!"); } int cnt = 0; foreach (var item in services) { var activityTimes = ActivityTimeDal.GetActivityTimes(item.serviceId); if (activityTimes == null) { throw new Exception("there is no activityTimes!"); } List <double> days = new List <double>(); for (int i = 0; i < 7; i++) { var dailyAC = activityTimes.Where(a => a.dayInWeek == i + 1); if (dailyAC != null && dailyAC.Count() > 0) { days.Add(dailyAC.Average(a => a.avgWaitings.Value)); } else { days.Add(0); } } avgForService.Add(days); cnt++; } return(avgForService); }
/// <summary> /// calc the new data with the old statisic /// </summary> /// <param name="line">the turns that are not unuaual</param> /// <param name="activityTime"></param> private static void UpdateStatistics(List <customersInLine> line, activityTime activityTime, bool IsServiceDuration) { //todoever: לעשות ביטוי למבדה במקום ה-if //שליפת ממוצע משמרת הכפלה ברוחב המדגם הוספת הנתונים החדשים, הוספת מספר הנתונים לרוחב המדגם וחלוקה של הסכום ברוחב המדגם //חישוב מחודש של סטיית טקן int totalSampleSize = activityTime.sampleSize.Value + line.Count(); double activityTimeAvg, newAvg, weightedAverage; if (IsServiceDuration) { activityTimeAvg = activityTime.avgServiceDuration.Value; newAvg = line.Average(lenOfServiceSelector); } else { activityTimeAvg = activityTime.avgWaitings.Value; newAvg = line.Average(lenOfWaitingSelector); } weightedAverage = (activityTimeAvg * activityTime.sampleSize.Value + newAvg * line.Count()) / totalSampleSize; double newStandardDeviation = calcStandartDeviation(line, IsServiceDuration); //todo: double weightedStandardDeviation = (activityTime.sampleSize.Value * Math.Sqrt(activityTime.sStandardDeviation.Value) + line.Count() * Math.Sqrt(newStandardDeviation)); // weightedStandardDeviation += Math.Sqrt(activityTime.sampleSize.Value * (activityTimeAvg - weightedAverage)) + Math.Sqrt(line.Count() * (newAvg - weightedAverage)); // weightedStandardDeviation /= totalSampleSize; //todo: להוציא שורש מכל הסיפור הזה כי זה שונות משוקללת ולא סטית תקן activityTime.sampleSize = totalSampleSize; if (IsServiceDuration) { activityTime.avgServiceDuration = weightedAverage; // activityTime.serviceStandardDeviation = weightedStandardDeviation; } else { activityTime.avgWaitings = weightedAverage; // activityTime.waitingStandardDeviation = weightedStandardDeviation; } ActivityTimeDal.UpdateActivityTime(activityTime); }
public static ActivityTimeDTO GetNearestActivityTime(TimeSpan time, int serviceId) { List <ActivityTimeDTO> activityTimes = new List <ActivityTimeDTO>(); activityTimes = converters.ActivityTimeConverters.GetListActivityTimesDTO(ActivityTimeDal.GetActivityTimes(serviceId)); activityTimes = activityTimes.Where(a => a.DayInWeek == (int)DateTime.Now.DayOfWeek + 1 && a.StartDate <= DateTime.Now && a.EndDate <= DateTime.Now && a.StartTime >= time).OrderBy(t => t.StartTime).Take(1).ToList(); if (activityTimes.Count() == 0) { return(null); } return(activityTimes[0]); }
/// <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); }