private TimePeriod FitPeriodIntoOffer(OfferModel offer, TimePeriod period) { TimePeriod offerPeriod = new TimePeriod(offer.From, offer.To); TimePeriod printPeriod = new TimePeriod(DateTime.Today, DateTime.Today); if (offerPeriod.IsBefore(period) || offerPeriod.IsAfter(period)) { return(null); } if (offerPeriod.HasInside(period)) { printPeriod = period; } else if (offerPeriod.EndsInside(period)) { printPeriod.Start = period.Start; printPeriod.End = offer.To; } else if (offerPeriod.StartsInside(period)) { printPeriod.Start = offer.From; printPeriod.End = period.End; } else if (offerPeriod.IsInside(period)) { printPeriod.Start = offer.From; printPeriod.End = offer.To; } return(printPeriod); }
private static void OfferUpdateAlgTesting() { OfferModel offer = GlobalConfig.OfferModelConection.GetAll() .OrderBy(model => model.From) .ToArray().First(); TimePeriod offerPeriod = new TimePeriod(offer.From, offer.To); TimePeriod leftRange = null; TimePeriod rightRange = null; if (offerPeriod.IsBefore(DateTime.Today)) { leftRange = new TimePeriod(offerPeriod.Start, offerPeriod.Start); rightRange = new TimePeriod(offerPeriod.End, offerPeriod.End); } else { TimePeriod[] offerPeriods = GlobalConfig.OfferModelConection.GetAll() .Select(model => new TimePeriod(model.From, model.To)) .OrderBy(period => period.Start) .ToArray(); TimePeriod[] reservedPeriods = GlobalConfig.ReservationModelConection.GetAll() .Select(model => new TimePeriod(model.From, model.To)) .Where(period => offerPeriod.IntersectsWith(period)) .OrderBy(period => period.Start) .ToArray(); // Find outer limits DateTime leftOuterLimit = DateTime.Today; DateTime rightOuterLimit = DateTime.MaxValue; for (int i = 0; i < offerPeriods.Length; i++) { TimePeriod period = offerPeriods[i]; if (period.IsExactMatch(offerPeriod)) { try { leftOuterLimit = offerPeriods[i - 1].End.AddDays(1); } catch (IndexOutOfRangeException) { } try { rightOuterLimit = offerPeriods[i + 1].Start.AddDays(-1); } catch (IndexOutOfRangeException) { } break; } } DateTime leftInnerLimit = rightOuterLimit; DateTime rightInnerLimit = leftOuterLimit; if (reservedPeriods.Length > 0) { TimePeriod first = reservedPeriods[0]; TimePeriod last = reservedPeriods[reservedPeriods.Length - 1]; leftInnerLimit = first.Start < DateTime.Today ? DateTime.Today : first.Start; rightInnerLimit = last.End; if (offerPeriod.StartsInside(first)) { leftInnerLimit = offerPeriod.Start; } if (offerPeriod.EndsInside(last)) { rightInnerLimit = offerPeriod.End; } } leftRange = new TimePeriod(leftOuterLimit, leftInnerLimit); rightRange = new TimePeriod(rightInnerLimit, rightOuterLimit); } Console.WriteLine("sds"); }
private static void TimePeriodTesting() { CarModel car = GlobalConfig.CarModelConection.Get(1); OfferModel[] offers = GlobalConfig.OfferModelConection.GetAll(); offers = offers.OrderBy(offer => offer.From).ToArray(); ReservationModel[] reservations = GlobalConfig.ReservationModelConection.Filter( model => model.CarID == car.ID ); //TimePeriod[] reservedDates = new TimePeriod[] //{ // new TimePeriod(DateTime.Today.AddDays(4),DateTime.Today.AddDays(6)), // new TimePeriod(DateTime.Today,DateTime.Today.AddDays(2)), // new TimePeriod(DateTime.Today.AddDays(9),DateTime.Today.AddDays(13)), // new TimePeriod(DateTime.Today.AddDays(14),DateTime.Today.AddDays(19)) //}; List <TimePeriod> reservedDates = reservations.Select( reservation => new TimePeriod(reservation.From, reservation.To) ).OrderBy(period => period.Start).ToList(); //reservedDates.Add(new TimePeriod(new DateTime(2019, 9, 5), new DateTime(2019, 9, 11))); TimePeriod range = new TimePeriod(DateTime.Today.AddDays(-2), offers.Last().To); TimePeriod[] freePeriods = TimePeriod.GetFreePeriods(range, reservedDates.ToArray()); List <string> freeDatePriceOutput = new List <string>(); foreach (OfferModel offer in offers) { TimePeriod offerPeriod = new TimePeriod(offer.From, offer.To); TimePeriod printPeriod = new TimePeriod(DateTime.Today, DateTime.Today); foreach (TimePeriod period in freePeriods) { if (offerPeriod.IsBefore(period) || offerPeriod.IsAfter(period)) { continue; } if (offerPeriod.HasInside(period)) { printPeriod = period; } else if (offerPeriod.EndsInside(period)) { printPeriod.Start = period.Start; printPeriod.End = offer.To; } else if (offerPeriod.StartsInside(period)) { printPeriod.Start = offer.From; printPeriod.End = period.End; } else if (offerPeriod.IsInside(period)) { printPeriod.Start = offer.From; printPeriod.End = offer.To; } int days = printPeriod.GetDaySpan() + 1; double price = days * offer.PricePerDay; string output = $"{printPeriod} - price {price}"; freeDatePriceOutput.Add(output); } } Console.WriteLine("Offers"); foreach (OfferModel offer in offers) { Console.WriteLine($"{offer.From.ToShortDateString()}-{offer.To.ToShortDateString()} price per day {offer.PricePerDay}"); } Console.WriteLine("Reserved Dates"); foreach (TimePeriod period in reservedDates) { Console.WriteLine(period); } Console.WriteLine("Free dates"); foreach (TimePeriod period in freePeriods) { Console.WriteLine(period); } Console.WriteLine("Prices"); foreach (string output in freeDatePriceOutput) { Console.WriteLine(output); } // for user time period input // check if it is in the free periods // find which offers corespond to that time period // calculate the price Console.WriteLine("sad"); }
private void FindUpdateLimits() { /* * Algorithm needs to find how much given period can expand or shrink depending on other periods. * First it checks how much it can expand by checking other offer periods. * Then it checks how much it can shrink by checking reservations for that offer. * Then it creates left and right range as available update values. */ TimePeriod offerPeriod = new TimePeriod(selectedOffer.Record.From, selectedOffer.Record.To); /* * If the selected offer is in the past, there is no point in updating it. */ if (offerPeriod.IsBefore(DateTime.Today)) { leftRange = null; rightRange = null; return; } // find reservations for this offer period TimePeriod[] reservationPeriods = RentACarLibrary.GlobalConfig.ReservationModelConection .Filter(model => model.CarID == (view.Car as CarModel).ID) .Select(model => new TimePeriod(model.From, model.To)) .Where(period => offerPeriod.IntersectsWith(period)) .OrderBy(period => period.Start) .ToArray(); // find offers for the selected offer's car TimePeriod[] offerPeriods = RentACarLibrary.GlobalConfig.OfferModelConection .Filter(model => model.CarID == selectedOffer.Record.CarID) .Select(model => new TimePeriod(model.From, model.To)) .OrderBy(period => period.Start) .ToArray(); /* * The minimum value that the left outer limit can take is the present day. * There is no point in expanding the time period so it starts in the past. * And if the period already starts in the past, we won't be able to expand or shrink * it on the left side. */ // Find outer limits DateTime leftOuterLimit = (offerPeriod.Start < DateTime.Today) ? offerPeriod.Start : DateTime.Today; DateTime rightOuterLimit = DateTime.MaxValue; for (int i = 0; i < offerPeriods.Length; i++) { TimePeriod period = offerPeriods[i]; if (period.IsExactMatch(offerPeriod)) { // offer before try { // ignore offers that are in the past if (!offerPeriods[i - 1].IsBefore(DateTime.Today)) { leftOuterLimit = offerPeriods[i - 1].End.AddDays(1); } } catch (IndexOutOfRangeException) { } // offer after try { rightOuterLimit = offerPeriods[i + 1].Start.AddDays(-1); } catch (IndexOutOfRangeException) { } break; } } // Find Inner limits // asumption that offer has no active reservations DateTime leftInnerLimit = rightOuterLimit; DateTime rightInnerLimit = leftOuterLimit; // then check against that asumption if (reservationPeriods.Length > 0) { TimePeriod firstReservation = reservationPeriods.First(); TimePeriod lastReservation = reservationPeriods.Last(); // Again checks if the start should not change at all because it is already in the past. leftInnerLimit = firstReservation.Start < DateTime.Today ? offerPeriod.Start : firstReservation.Start; rightInnerLimit = lastReservation.End; // Here we check for reservations that may contain more than one offer if (offerPeriod.StartsInside(firstReservation)) { // First reservation began in an offer before the selected offer leftInnerLimit = offerPeriod.Start; } if (offerPeriod.EndsInside(lastReservation)) { // Last reservation ends in an offer after the selected offer rightInnerLimit = offerPeriod.End; } } leftRange = new TimePeriod(leftOuterLimit, leftInnerLimit); rightRange = new TimePeriod(rightInnerLimit, rightOuterLimit); }