} // end of TimeLineConfiguration #endregion //-------------------------------------------------------------------------------------------------- // Public Methods implementing the booking model interface //-------------------------------------------------------------------------------------------------- #region GetEarliestSlot /// <summary> /// Loops through time lines and looks for the earliest slot /// for the request /// </summary> /// <param name="currentTime">Time the request is made</param> /// <param name="request">slot request to be booked</param> /// <returns>The earliest slot for the request</returns> public Slot GetEarliestSlot(DateTime currentTime, SlotRequest request) { CutTimeLines(currentTime); // if earliest time is later than latest time of all time lines // new time lines are added while (TimeLines.Last().EndTime < request.EarliestTime) { AddSingleTimeLine(); } // end while Slot slotFound = null; // loop through all time lines to find a slot for (int i = 0; i < TimeLines.Count; i++) { if (TimeLines[i].StartTime >= request.EarliestTime) { if ((slotFound = TimeLines[i].GetEarliestSlotTime(request, ConstraintsWithinTimeLine)) != null) { break; } } // end if } // end for // if all time lines are full or constraints do not allow extra bookings // new time lines are added as long as booking is possible while (slotFound == null) { AddSingleTimeLine(); slotFound = TimeLines.Last().GetEarliestSlotTime(request, ConstraintsWithinTimeLine); } // end while return(slotFound); } // end of GetEarliestSlot
} // end of GetEarliestSlot #endregion #region GetAllSlotTimes /// <summary> /// Loops through all time lines in the window and returns all slots possible in these time lines /// </summary> /// <param name="currentTime">Time the request is made</param> /// <param name="request">slot request to be booked</param> /// <param name="latestTime">Latest time for a booking</param> /// <returns>All available slots for the request within the specified time window</returns> public List <Slot> GetAllSlotTimes(DateTime currentTime, SlotRequest request, DateTime latestTime) { CutTimeLines(currentTime); // if current time lines do not cover the entire period extra time lines are added while (TimeLines.Last().EndTime < latestTime) { AddSingleTimeLine(); } // end while List <Slot> allSlots = new List <Slot>(); // loop through all time lines and add possible slots for (int i = 0; i < TimeLines.Count; i++) { if (TimeLines[i].StartTime >= latestTime) { break; } if (TimeLines[i].StartTime <= request.EarliestTime) { allSlots.AddRange(TimeLines[i].GetAllSlotTime(request, ConstraintsWithinTimeLine)); } else { break; } // end if } // end for return(allSlots); } // end of GetAllSlotTimes
/// <summary> /// Earliest slot for a request /// </summary> /// <param name="request">The request for the slot</param> /// <param name="constraints">Constraints associated with the request</param> /// <returns></returns> public Slot GetEarliestSlotTime(SlotRequest request, SingleTimeLineConstraints constraints) { if (Full) { return(null); } return(GetFirstSlotAtMinAtom(FirstAvailableAtom, request, constraints)); } // end if
} // end if #endregion #region GetAllSlotTimes /// <summary> /// Gets all slots on the time line for a request /// </summary> /// <param name="request">The request for the slot</param> /// <param name="constraints">Constraints associated with the request</param> /// <returns></returns> public List <Slot> GetAllSlotTime(SlotRequest request, SingleTimeLineConstraints constraints) { List <Slot> allSlots = new List <Slot>(); if (Full) { return(allSlots); } TimeAtom currentAtom = FirstAvailableAtom; // loops through all possible start atoms while (currentAtom != null) { allSlots.Add(GetFirstSlotAtMinAtom(currentAtom, request, constraints)); currentAtom = currentAtom.NextAvailableAtom; } // end while return(allSlots); } // end of GetAllSlotTime
} // end of TimeLineConstraints #endregion #region ConstraintsWithinTimeLine /// <summary> /// Method that defines constraints within a single time line, e.g. booking of different types to be /// balanced /// </summary> /// <param name="request">Request to be booked</param> /// <param name="timeLine">Time line for the booking</param> /// <param name="atom">Atom to be used as a start atom for a slot</param> /// <returns></returns> virtual public bool ConstraintsWithinTimeLine(SlotRequest request, SinglePerDayTimeLine timeLine, TimeAtom atom) { return(true); } // end of ConstraintsWithinTimeLine
} // end of CancelSlot #endregion //-------------------------------------------------------------------------------------------------- // Constraints //-------------------------------------------------------------------------------------------------- #region TimeLineConstraints /// <summary> /// This method my be overwritten to specify constraints on time lines and requests, e.g. certain bookings /// only on specific days /// </summary> /// <param name="request"></param> /// <param name="timeLine"></param> /// <returns></returns> virtual public bool TimeLineConstraints(SlotRequest request, SinglePerDayTimeLine timeLine) { return(true); } // end of TimeLineConstraints
} // end of GetAllSlotTime #endregion #region GetFirstSlotAtMinAtom /// <summary> /// Gets the first slot after a minimum atom that can be booked /// </summary> /// <param name="firstAtom">First atom to consider</param> /// <param name="request">Request for slot</param> /// <param name="constraints">Constraints associated with the slot</param> /// <returns>The first slot with a starting atom later than the first atom that can be booked</returns> private Slot GetFirstSlotAtMinAtom(TimeAtom firstAtom, SlotRequest request, SingleTimeLineConstraints constraints) { TimeAtom currentAtom = firstAtom; DateTime availableTo; // setting start atom for search while (currentAtom != null && (currentAtom.Blocked || currentAtom.NonBookable)) { currentAtom = currentAtom.NextAvailableAtom; } // while // looping through possible start atoms while (currentAtom != null) { TimeAtom loopingAtom; // calc the availability period for the current atom if (currentAtom.NextBlockedAtom == null) { availableTo = EndTime; } else { availableTo = currentAtom.NextBlockedAtom.StartTime; } // end if // checking if the availability length is sufficient if (availableTo - currentAtom.StartTime >= request.Length) { // checking constraints for booking // this is currently only done for the start atom of a possible slot // could be easily extended to the whole stretch if (constraints(request, this, currentAtom)) { DateTime endTime = currentAtom.StartTime + request.Length; loopingAtom = currentAtom; bool noViolationDetected = true; List <TimeAtom> coveredAtoms = new List <TimeAtom>(); // checking the capacitity of all covered atoms while (loopingAtom != null && loopingAtom.StartTime < endTime && noViolationDetected) { coveredAtoms.Add(loopingAtom); if (loopingAtom.Capacity > loopingAtom.MaxCapacity - request.Capacity) { noViolationDetected = false; } loopingAtom = loopingAtom.NextAtom; } // end while // in case a booking would be possible the atom is returned if (noViolationDetected) { return(new Slot( this, currentAtom, coveredAtoms.ToArray(), endTime, request.Capacity, request.Type.AdmissionType.Identifier)); } } // end if } // end if currentAtom = currentAtom.NextAvailableAtom; } // end while return(null); } // end of GetFirstSlotAfterTime
} // end of GetEarliestSlot #endregion #region GetAllSlotTimes /// <summary> /// Does not make sense for this model and throws an exception /// </summary> /// <param name="currentTime">Time the request is made</param> /// <param name="request">slot request to be booked</param> /// <param name="latestTime">Latest time for a booking</param> /// <returns>All available slots for the request within the specified time window</returns> public List <Slot> GetAllSlotTimes(DateTime currentTime, SlotRequest request, DateTime latestTime) { throw new NotImplementedException(); } // end of GetAllSlotTimes
//-------------------------------------------------------------------------------------------------- // Public Methods //-------------------------------------------------------------------------------------------------- #region GetEarliestSlot /// <summary> /// Returns current time as no actual booking is made /// </summary> /// <param name="currentTime">Time the request is made</param> /// <param name="request">slot request to be booked</param> /// <returns>The earliest slot for the request</returns> public Slot GetEarliestSlot(DateTime currentTime, SlotRequest request) { return(new Slot(currentTime)); } // end of GetEarliestSlot