///<summary>Gets time availalbility for appointment searching. Moved to business layer for unit tests. ///Returns the first available time slots for each of the next 10 available days. This means there will only be one time slot per day and ///that time slot will always be the first available time slot within that day regardless of additional time slots being available. ///resultCount defaults to preserve old functionality, the UI only holds 10 but this could be changed.</summary> public static List <ScheduleOpening> GetSearchResults(long aptNum, DateTime dateStart, DateTime dateEnd, List <long> listProvNums, List <long> listOpNums , List <long> listClinicNums, TimeSpan beforeTime, TimeSpan afterTime, long blockoutType = 0, bool hasProvAndBlockout = false, int resultCount = 10) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) //No call to db but designed to save middle tier trips. { return(Meth.GetObject <List <ScheduleOpening> >(MethodBase.GetCurrentMethod(), aptNum, dateStart, dateEnd, listProvNums, listOpNums, listClinicNums , beforeTime, afterTime, blockoutType, hasProvAndBlockout, resultCount)); } //if they didn't set a before time, set it to a large timespan so that we can use the same logic for checking appointment times. if (beforeTime == TimeSpan.FromSeconds(0)) { beforeTime = TimeSpan.FromHours(25); //bigger than any time of day. } ApptSearchData data = GetDataForSearch(aptNum, dateStart, dateEnd, listProvNums, listOpNums, listClinicNums, blockoutType); List <ScheduleOpening> retVal = new List <ScheduleOpening>(); if (data.AppointmentToAdd == null) //appointment was deleted after clicking search. { return(retVal); } DateTime dateEvaluating = data.DateEvaluating; SearchBehaviorCriteria searchType = (SearchBehaviorCriteria)PrefC.GetInt(PrefName.AppointmentSearchBehavior); if (hasProvAndBlockout) //searching for intersection of providers and blockouts get as many results as possible. { while (dateEvaluating < dateEnd) { List <ScheduleOpening> listPotentialTimeAvailable = GetProvAndOpAvailabilityHelper(listProvNums, dateEvaluating, data, searchType, listOpNums , blockoutType); //At this point listPotentialTimeAvailable is already filtered and only contains appt times that match both provider time and operatory time. List <ScheduleOpening> listOpeningsForEntireDay = AddTimesToSearchResultsHelper(listPotentialTimeAvailable, beforeTime, afterTime); retVal.AddRange(listOpeningsForEntireDay); dateEvaluating = dateEvaluating.AddDays(1); } } else { while (retVal.Count < resultCount && dateEvaluating < dateEnd) { List <ScheduleOpening> listPotentialTimeAvailable = GetProvAndOpAvailabilityHelper(listProvNums, dateEvaluating, data, searchType, listOpNums , blockoutType); //At this point listPotentialTimeAvailable is already filtered and only contains appt times that match both provider time and operatory time. ScheduleOpening firstOpeningForDay = AddTimeToSearchResultsHelper(listPotentialTimeAvailable, beforeTime, afterTime); if (firstOpeningForDay != null) { retVal.Add(firstOpeningForDay); } dateEvaluating = dateEvaluating.AddDays(1); } } return(retVal); }
///<summary>Gets the data necessary from the database to run the appointment search logic.</summary> public static ApptSearchData GetDataForSearch(long aptNum, DateTime dateAfter, DateTime dateBefore, List <long> listProvNums, List <long> listOpNums , List <long> listClinicNums, long blockoutType) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetObject <ApptSearchData>(MethodBase.GetCurrentMethod(), aptNum, dateAfter, dateBefore, listProvNums, listOpNums, listClinicNums , blockoutType)); } ApptSearchData data = new ApptSearchData(); data.DateEvaluating = dateAfter.AddDays(1); data.AppointmentToAdd = Appointments.GetOneApt(aptNum); data.ListSchedules = Schedules.GetSchedulesForAppointmentSearch(data.DateEvaluating, dateBefore, listClinicNums, listOpNums , listProvNums, blockoutType); //Get all appointments that exist in the operaotries we will be searching to find an opening, not just for provider we're looking for //so we can get conflicts when multiple provs work in a single operaotry. data.ListAppointments = Appointments.GetForPeriodList(data.DateEvaluating, dateBefore, listOpNums, listClinicNums); data.ListSchedOps = ScheduleOps.GetForSchedList(data.ListSchedules, listOpNums); //ops filter for case when a prov is scheduled in multiple ops return(data); }
private static List <ScheduleOpening> GetProvAndOpAvailabilityHelper(List <long> listProvNums, DateTime dateEvaluating, ApptSearchData data, SearchBehaviorCriteria searchType, List <long> listOpNums, long blockoutType) { //No need to check RemotingRole; no call to db. List <ScheduleOpening> listPotentialTimeAvailable = new List <ScheduleOpening>(); //create or clear //Providers--------------------------------------------------------------------------------------------------------------- List <ApptSearchProviderSchedule> listProvScheds = new List <ApptSearchProviderSchedule>(); //Provider Bar, ProviderSched Bar, Date and Provider listProvScheds = Appointments.GetProviderScheduleForProvidersAndDate(listProvNums, dateEvaluating, data.ListSchedules, data.ListAppointments); if (searchType == SearchBehaviorCriteria.ProviderTime) //Fill the time the provider is available { listPotentialTimeAvailable = FillProviderTimeHelper(listProvScheds, data.AppointmentToAdd, dateEvaluating, blockoutType); } //Handle Operatories ----------------------------------------------------------------------------------------------------- if (searchType == SearchBehaviorCriteria.ProviderTimeOperatory) //Fill the time the prov and op are available { List <ApptSearchOperatorySchedule> listOpScheds = new List <ApptSearchOperatorySchedule>(); //filtered based on SearchType listOpScheds = GetAllForDate(dateEvaluating, data.ListSchedules, data.ListAppointments, data.ListSchedOps, listOpNums, listProvNums, blockoutType); listPotentialTimeAvailable = FillOperatoryTime(listOpScheds, listProvScheds, data.AppointmentToAdd, dateEvaluating, listProvNums, blockoutType , data.ListSchedOps, data.ListSchedules); } return(listPotentialTimeAvailable); }