public void TestReservationPossibleInvalidPlayAt()
        {
            ReservationType resv = new ReservationType()
            {
                HowManyHours = 3,
                NumberOfPlayers = 20,
                PlayAt = DateTime.Now.AddDays(-1),
                TimeOfDay = TimeSpan.FromHours(13)
            };

            ReservationPossible request = new ReservationPossible() { Reservation = resv };
            ReservationPossibleValidator validator = new ReservationPossibleValidator();
            var response = validator.Validate(request);
            Assert.That(response.IsValid, Is.False);
            Assert.That(response.Errors[0].PropertyName, Is.EqualTo("Reservation.PlayAt"));
        }
        public void TestReservationPossibleValidRequest1()
        {
            ReservationType resv = new ReservationType()
            {
                HowManyHours = 2,
                NumberOfPlayers = 20,
                PlayAt = DateTime.Now.AddDays(1),
                TimeOfDay = TimeSpan.FromHours(13)
            };

            ReservationPossible request = new ReservationPossible() { Reservation = resv };
            ReservationPossibleValidator validator = new ReservationPossibleValidator();
            Assert.That(validator.Validate(request).IsValid, Is.True);
        }
        /// <summary>
        /// Determines whether the new reservation <paramref name="reservation"/> is possible
        /// based on the current reservation schedule for the day of that reservations
        /// </summary>
        /// <remarks>
        /// The lane scheduler will be queried to check for availablility. While doing this,
        /// all current reservations for that day might be rescheduled, therefore, the new schedule
        /// is returned. This schedule will have to be persisted if the new reservation is acuallly
        /// added to the database.
        /// 
        /// The out paramter "newReservation" will contain an reservation instance ready for persisting
        /// if this is sought.
        /// 
        /// Execptions will be thrown if the reservation does not fit in the current schedule
        /// </remarks>
        /// <param name="reservation">The new reservation</param>
        /// <param name="theReservation">An intance of a reservation, based on the data from <paramref name="reservation"/></param>
        /// <returns>The list of rescheduled reservations and an instance ready to commit in <paramref name="theReservation"/></returns>
        /// <exception cref="ArgumentException">If the <paramref name="reservation"/> is not possible</exception>
        public List<Reservation> Go(ReservationType reservation, out Reservation theReservation, out bool isPossible, out List<LaneSchedulerReservation> suggestions)
        {
            // quick pruning of the result - does the requested timeslot exist at all??
            TimeSlot startTimeSlot = timeSlotRepos.GetAll().FindTimeSlotStartingAt(reservation.TimeOfDay);
            if (startTimeSlot == null)
            {
                throw new ArgumentException("Reservation is not possible as the timeslot does not exist", "timeSlot");
            }

            var reservations = reservationRepos.GetAll().FindReservationsByDate(reservation.PlayAt);

            // convert these into a format the scheduler understands...
            List<LaneSchedulerReservation> schedulerReservations;
            var convertToState = ServiceLocator.Current.GetInstance<ReservationsToLaneSchedulerState>();
            var schedulerState = convertToState.Convert(reservations.ToList(), out schedulerReservations);

            LaneSchedulerReservation newReservation = new LaneSchedulerReservation()
            {
                Id = -1,
                NumberOfLanes = (int)Math.Ceiling(reservation.NumberOfPlayers / 6.0m),
                NumberOfTimeSlots = reservation.HowManyHours,
                StartTimeSlot = startTimeSlot.Id - 1
            };

            // do the scheduling
            var newState = LaneScheduler.Search(schedulerState, schedulerReservations, newReservation);

            if (newState.state == null)
            {

                suggestions = newState.reservations;
                isPossible = false;
                theReservation = null;
                return null;

            }
            suggestions = null;
            // The scheduler attempts to place the reservation +/- one time slot in the schedule if it's full,
            // so we have to try and handle that
            var convertToReservation = ServiceLocator.Current.GetInstance<LaneSchedulerStateToReservations>();
            var rescheduledReservations = convertToReservation.Convert(newState.state, out theReservation);
            theReservation.NumberOfPlayers = reservation.NumberOfPlayers;
            theReservation.PlayAt = reservation.PlayAt;
            theReservation.Name = reservation.Name;
            theReservation.PhoneNumber = reservation.PhoneNumber;
            theReservation.Status = ReservationStatus.Pending;
            theReservation.CreatedAt = DateTime.Now;

            // now that we have the actual reservation, we can check
            // the added time-slots against the requested timeslot
            if (theReservation.TimeSlots[0].Start != startTimeSlot.Start)
            {
                isPossible = false;
            }
            else
            {
                isPossible = true;
            }

            return rescheduledReservations;
        }