private bool AddNewRecurringReservation(ReservationCollection reservations, ReservationData data) { // [2013-05-16 jg] We need find any existing, unended and uncancelled reservations in the // same time slot. This can happen if there are overlapping recurring reservation patterns. // To determine if two reservations overlap I'm using this logic: (StartA < EndB) and(EndA > StartB) // [2019-06-10 jg] Can also overlap if the RecurrenceID and time slots are the same, // regardless of IsActive. This will prevent previously cancelled recurrences from being // created again. // Step 1. Get any overlapping by resource and date range. var overlapping = reservations.Where(x => x.ResourceID == data.ResourceID && (x.BeginDateTime <data.Duration.EndDateTime && x.EndDateTime> data.Duration.BeginDateTime)).ToList(); // Step 2. Check for any active (uncancelled) or a reservation with the same RecurrenceID (cancelled or uncancelled). // The idea here is a recurrence should be created if the time slot is unused or there is a cancelled reservation unless // the cancelled reservation is the same recurrence, in which case we do not want to create the recurrence again. var isOverlapped = overlapping.Any(x => x.IsActive || x.RecurrenceID == data.RecurrenceID); //var overlapping = reservations.Any(x => // (x.IsActive || x.RecurrenceID == data.RecurrenceID) // && x.ResourceID == data.ResourceID // && (x.BeginDateTime < data.Duration.EndDateTime && x.EndDateTime > data.Duration.BeginDateTime) // && x.ActualEndDateTime == null); <-- this was causing a problem when an existing cancelled recurrence was present because in this case ActualEndDateTime was not null so the recurrence was created again. if (!isOverlapped) { var util = Reservations.Create(Provider, DateTime.Now); var rsv = util.CreateReservation(data); reservations.Add(rsv); return(true); } return(false); }
/// <summary> /// Returns true if a new reservation is created. /// </summary> public bool AddRegularFromRecurring(ReservationCollection reservations, IReservationRecurrence rr, DateTime d) { // reservations should contain cancelled reservations // first, find out the pattern type if (rr.PatternID == (int)PatternType.Weekly) { if (rr.PatternParam1 == (int)d.DayOfWeek) { if ((d >= rr.BeginDate && rr.EndDate == null) || (d >= rr.BeginDate && d <= rr.EndDate.Value)) { return(AddNewRecurringReservation(reservations, GetReservationData(rr, d))); } } } else if (rr.PatternID == (int)PatternType.Monthly) { if ((d >= rr.BeginDate && rr.EndDate == null) || (d >= rr.BeginDate && d <= rr.EndDate)) { DateTime dayOfMonth = GetDate(new DateTime(d.Year, d.Month, 1), rr.PatternParam1, (DayOfWeek)rr.PatternParam2); if (d.Date == dayOfMonth) { return(AddNewRecurringReservation(reservations, GetReservationData(rr, d))); } } } // currently only supports two types return(false); }