Exemplo n.º 1
0
        public GenericObjectResponse <ReservationRequestResponse> RequestReservation(long roomId, [FromBody] ReservationRequestPayload payload)
        {
            long?userId = AuthenticationService.IsAuthorized(Request, UserRole.RoomOwner, UserRole.Coach);

            if (userId == null)
            {
                Response.StatusCode = 401;
                return(new GenericObjectResponse <ReservationRequestResponse>(""));
            }

            ReservationRequestPayload trimmedPayload = new ReservationRequestPayload()
            {
                Description = payload.Description,
                RentStart   = payload.RentStart.TrimDate(DateTimePrecision.Minute).ToLocalDate(),
                RentEnd     = payload.RentEnd.TrimDate(DateTimePrecision.Minute).ToLocalDate()
            };
            ReservationValidationService reservationValidationService = new ReservationValidationService();
            GenericStatusMessage         roomAvailabilityValidation   = reservationValidationService.ValidateRoomAvailability(roomId, trimmedPayload);

            if (!roomAvailabilityValidation.Success)
            {
                Response.StatusCode = 400;
                return(new GenericObjectResponse <ReservationRequestResponse>(roomAvailabilityValidation.Message));
            }

            ReservationManipulationService reservationManipulationService = new ReservationManipulationService();

            return(reservationManipulationService.AddReservation(roomId, userId.Value, trimmedPayload));
        }
Exemplo n.º 2
0
        public WorkingHours GetMatchingWorkingHours(ReservationRequestPayload payload, Room room)
        {
            int  reservationStartTime = payload.RentStart.ToMinutes();
            int  resevationEndTime    = payload.RentEnd.ToMinutes();
            Days reservationDay       = payload.RentStart.ToDaysEnum();

            return(room.WorkingHours.FirstOrDefault(x => x.Day == reservationDay && x.TimeStart <= reservationStartTime && x.TimeEnd >= resevationEndTime));
        }
Exemplo n.º 3
0
 public GenericStatusMessage ValidateRoomAvailability(long roomId, ReservationRequestPayload payload)
 {
     using (ReservationDataContext context = new ReservationDataContext())
     {
         Room room = context.Rooms.Include(x => x.WorkingHours).SingleOrDefault(x => x.Id == roomId && x.IsActive);
         return(ValidateRoomAvailability(context, room, payload));
     }
 }
        public GenericListResponse <AvailableReservationTime> GetRoomAvailableTimes(long roomId, DateTime?startDate, int duration, int take)
        {
            using (ReservationDataContext context = new ReservationDataContext())
            {
                if (duration <= 0)
                {
                    return(new GenericListResponse <AvailableReservationTime>("Invalid duration."));
                }

                var roomQuery = context.Rooms.Include(x => x.WorkingHours).Include(x => x.Reservations);
                var room      = roomQuery.SingleOrDefault(x => x.Id == roomId);
                if (room == null)
                {
                    return(new GenericListResponse <AvailableReservationTime>("Room not found."));
                }

                List <AvailableReservationTime> availableTimes = new List <AvailableReservationTime>();
                DateTime now             = DateTime.Now;
                DateTime currentDateTemp = (startDate != null && startDate > now ? startDate.Value.ToLocalDate() : now);
                DateTime currentDate     = currentDateTemp.Date;
                int      limit           = 1440 - duration;
                ReservationValidationService reservationValidationService = new ReservationValidationService();
                while (availableTimes.Count < take)
                {
                    for (int i = 0; i < limit && availableTimes.Count < take; i += 30)
                    {
                        DateTime rentStart = currentDate + TimeSpan.FromMinutes(i);
                        if (rentStart < now)
                        {
                            continue;
                        }

                        ReservationRequestPayload payload = new ReservationRequestPayload
                        {
                            RentStart = rentStart,
                            RentEnd   = rentStart + TimeSpan.FromMinutes(duration)
                        };

                        GenericStatusMessage availability = reservationValidationService.ValidateRoomAvailability(context, room, payload);
                        if (availability.Success)
                        {
                            var matchedWorkingHours = reservationValidationService.GetMatchingWorkingHours(payload, room);
                            availableTimes.Add(new AvailableReservationTime
                            {
                                RentStart = rentStart,
                                Price     = PriceHelper.CalculatePrice(matchedWorkingHours.PriceForHour, rentStart, payload.RentEnd)
                            });
                        }
                    }

                    currentDate += TimeSpan.FromDays(1);
                }
                return(new GenericListResponse <AvailableReservationTime>(availableTimes, availableTimes.Count));
            }
        }
Exemplo n.º 5
0
        private GenericStatusMessage ValidateRoomAvailability(ReservationDataContext context, ReservationRequest request)
        {
            Room room = context.Rooms.Include(x => x.WorkingHours).SingleOrDefault(x => x.Id == request.RoomId);
            ReservationRequestPayload payload = new ReservationRequestPayload
            {
                RentStart   = request.RentStart,
                RentEnd     = request.RentEnd,
                Description = request.Description
            };

            return(ValidateRoomAvailability(context, room, payload));
        }
Exemplo n.º 6
0
        public GenericObjectResponse <ReservationRequestResponse> AddReservation(long roomId, long requesterId, ReservationRequestPayload payload)
        {
            ReservationValidationService reservationValidationService = new ReservationValidationService();

            using (ReservationDataContext context = new ReservationDataContext())
            {
                Room               room = context.Rooms.Include(x => x.WorkingHours).Single(x => x.Id == roomId);
                WorkingHours       matchedWorkingHours = reservationValidationService.GetMatchingWorkingHours(payload, room);
                ReservationRequest reservationRequest  = new ReservationRequest()
                {
                    RentStart   = payload.RentStart,
                    RentEnd     = payload.RentEnd,
                    Status      = ReservationStatus.Pending,
                    Description = payload.Description,
                    FinalPrice  = PriceHelper.CalculatePrice(matchedWorkingHours.PriceForHour, payload.RentStart, payload.RentEnd),
                    RoomId      = roomId,
                    UserId      = requesterId
                };
                context.ReservationRequests.Add(reservationRequest);
                context.SaveChanges();

                return(new GenericObjectResponse <ReservationRequestResponse>(ConvertToResponse(reservationRequest)));
            }
        }
Exemplo n.º 7
0
        public GenericStatusMessage ValidateRoomAvailability(ReservationDataContext context, Room room, ReservationRequestPayload payload)
        {
            if (room == null)
            {
                return(new GenericStatusMessage(false, "Room not found or is not currently active."));
            }

            if (payload.RentStart.Date != payload.RentEnd.Date)
            {
                return(new GenericStatusMessage(false, "Rent start and rent end should be on the same day."));
            }

            if (payload.RentStart >= payload.RentEnd)
            {
                return(new GenericStatusMessage(false, "Rent start can't be after rent end."));
            }

            if (GetMatchingWorkingHours(payload, room) == null)
            {
                return(new GenericStatusMessage(false, "Reservation is not in the rooms working hours."));
            }

            var todaysReservations = context.ReservationRequests.Where(x => x.RoomId == room.Id &&
                                                                       x.Status == ReservationStatus.Approved &&
                                                                       DbFunctions.TruncateTime(x.RentStart) == DbFunctions.TruncateTime(payload.RentStart)).ToList();
            bool collision = todaysReservations.Any(x =>
            {
                bool startValidation    = payload.RentStart > x.RentStart && payload.RentStart < x.RentEnd;
                bool endValidation      = payload.RentEnd > x.RentStart && payload.RentEnd < x.RentEnd;
                bool sameTimeValidation = payload.RentStart == x.RentStart && payload.RentEnd == x.RentEnd;
                return(startValidation || endValidation || sameTimeValidation);
            });

            if (collision)
            {
                return(new GenericStatusMessage(false, "Reservation collides with an already approved reservation."));
            }

            return(new GenericStatusMessage(true));
        }