public GenericStatusMessage ChangeRoomActivation(long roomId, bool activate, bool force) { DateTime now = DateTime.Now; using (ReservationDataContext context = new ReservationDataContext()) { Room room = context.Rooms.Include(x => x.Reservations).Single(x => x.Id == roomId); if (!activate) { bool hasFutureReservations = room.Reservations.Any(x => x.RentStart >= now && x.Status != ReservationStatus.Rejected); if (hasFutureReservations) { if (!force) { return(new GenericStatusMessage(false, "Could not complete operation, room has future reservations.")); } IEnumerable <ReservationRequest> futureReservations = room.Reservations.Where(x => x.RentStart >= now && x.Status != ReservationStatus.Rejected); foreach (ReservationRequest reservation in futureReservations) { reservation.Status = ReservationStatus.Rejected; } } } room.IsActive = activate; context.SaveChanges(); return(new GenericStatusMessage(true)); } }
public GenericStatusMessage ValidateRequest(long roomId, long requestId, long userId, bool validateDoubleBooking = false) { using (ReservationDataContext context = new ReservationDataContext()) { ReservationRequest reservationRequest = context.ReservationRequests.Include(x => x.Room).SingleOrDefault(x => x.Id == requestId); if (reservationRequest == null) { return(new GenericStatusMessage(false, $"Reservation with ID {requestId} does not exist.")); } if (reservationRequest.RoomId != roomId) { return(new GenericStatusMessage(false, $"Request {requestId} does not belong to room {roomId}.")); } if (reservationRequest.Room.OwnerId != userId) { return(new GenericStatusMessage(false, $"Request {requestId} can not be verified by user.")); } if (validateDoubleBooking) { return(ValidateRoomAvailability(context, reservationRequest)); } return(new GenericStatusMessage(true)); } }
public LoginResponse ValidateLogin(string username, string password) { using (ReservationDataContext context = new ReservationDataContext()) { User user = context.Users.FirstOrDefault(x => x.Username == username); if (user == null) { Logger.Debug($"Username {username} does not exist."); return(null); } bool correctPassword = PasswordHasher.Validate(password, user.PasswordHash); if (!correctPassword) { Logger.Debug($"{username} failed to login due to incorrect password."); return(null); } user.Token = Guid.NewGuid(); user.TokenExpiryDate = DateTime.UtcNow + TokenExpiryWindow; context.SaveChanges(); return(new LoginResponse() { Token = user.Token }); } }
/// <summary> /// User payload validations: /// Email matches ^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$ regex. /// Password matches confirm password. /// First and last name does not exceed 20 chars. /// Country and city does not exceed 20 chars. /// Street does not exceed 50 chars. /// Building number > 0. /// </summary> public GenericStatusMessage ValidateCreateUserData(CreateUserPayload payload) { if (!payload.Username.Matches(EmailRegexPattern)) { return(new GenericStatusMessage(false, "Username is not an email.")); } using (ReservationDataContext context = new ReservationDataContext()) { bool usernameExists = context.Users.Any(x => x.Username == payload.Username); if (usernameExists) { return(new GenericStatusMessage(false, "Username already exists.")); } } if (!payload.Password.CheckLength(25, 8) || !payload.ConfirmPassword.CheckLength(25, 8)) { return(new GenericStatusMessage(false, "Passwords should be between 8 and 25 characters.")); } if (payload.Password != payload.ConfirmPassword) { return(new GenericStatusMessage(false, "Passwords do not match.")); } return(ValidateUserData(payload)); }
public GenericObjectResponse <List <WorkingHoursPayload> > ChangeWorkingHoursForRoom(long roomId, List <WorkingHoursPayload> workingHours, bool shouldValidate = true) { if (shouldValidate) { WorkingHoursValidationService workingHoursValidationService = new WorkingHoursValidationService(); GenericStatusMessage validationMessage = workingHoursValidationService.ValidateWorkingHoursData(workingHours); if (!validationMessage.Success) { return(new GenericObjectResponse <List <WorkingHoursPayload> >(validationMessage.Message)); } } try { using (ReservationDataContext context = new ReservationDataContext()) { List <WorkingHours> workingHoursToRemove = context.WorkingHours.Where(x => x.RoomId == roomId).ToList(); context.WorkingHours.RemoveRange(workingHoursToRemove); List <WorkingHours> workingHoursToAdd = workingHours.Select(x => ConvertWorkingHoursFromPayload(roomId, x)).ToList(); context.WorkingHours.AddRange(workingHoursToAdd); context.SaveChanges(); List <WorkingHoursPayload> savedWorkingHours = context.WorkingHours .Where(x => x.RoomId == roomId) .Select(ConvertWorkingHoursToPayload) .ToList(); return(new GenericObjectResponse <List <WorkingHoursPayload> >(savedWorkingHours)); } } catch (DbEntityValidationException e) { string exceptionMessage = e.EntityValidationErrors.FirstOrDefault()?.ValidationErrors.FirstOrDefault()?.ErrorMessage; Logger.Error($"Failed to create working hours. Error: '{exceptionMessage}'"); return(new GenericObjectResponse <List <WorkingHoursPayload> >("Failed to add working hours, please contact support.")); } }
public GenericObjectResponse <UserResponse> ChangeUserData(ChangeUserDataPayload payload, long userId) { UserValidationService service = new UserValidationService(); GenericStatusMessage validationResponse = service.ValidateUserData(payload, false); if (validationResponse.Success) { using (ReservationDataContext context = new ReservationDataContext()) { User user = context.Users.Single(x => x.Id == userId); user.FirstName = payload.FirstName ?? user.FirstName; user.LastName = payload.LastName ?? user.LastName; user.Country = payload.Country ?? user.Country; user.City = payload.City ?? user.City; user.Street = payload.Street ?? user.Street; user.BuildingNumber = payload.BuildingNumber ?? user.BuildingNumber; context.SaveChanges(); return(new GenericObjectResponse <UserResponse>(ConvertUserToUserResponse(user))); } } else { return(new GenericObjectResponse <UserResponse>(validationResponse.Message)); } }
public UserResponse GetUserById(long queryingUserId) { using (ReservationDataContext context = new ReservationDataContext()) { User queryingUser = context.Users.Single(x => x.Id == queryingUserId); return(ConvertFromUser(queryingUser)); } }
public static void Main(string[] args) { using (ReservationDataContext context = new ReservationDataContext()) { context.CreateTables(); } CreateHostBuilder(args).Build().Run(); }
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 GenericStatusMessage ValidateRoomExistsAndOwnedByUser(long roomId, long userId) { using (ReservationDataContext context = new ReservationDataContext()) { bool exists = context.Rooms.Any(x => x.Id == roomId && x.OwnerId == userId); return(new GenericStatusMessage(exists)); } }
public void ExpireToken(long userId) { using (ReservationDataContext context = new ReservationDataContext()) { User user = context.Users.Single(x => x.Id == userId); user.TokenExpiryDate = DateTime.UtcNow; context.SaveChanges(); } }
public GenericListResponse <RoomResponse> GetRoomsByOwner(long ownerId) { using (ReservationDataContext context = new ReservationDataContext()) { List <Objects.Room> rooms = context.Rooms.Where(x => x.OwnerId == ownerId).ToList(); RoomManipulationService roomManipulationService = new RoomManipulationService(); List <RoomResponse> roomResponses = rooms.Select(x => roomManipulationService.ConvertRoomToResponse(x, ownerId)).ToList(); return(new GenericListResponse <RoomResponse>(roomResponses, roomResponses.Count)); } }
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)); } }
public GenericStatusMessage ChangeReservationApproval(long requestId, ReservationStatus status) { using (ReservationDataContext context = new ReservationDataContext()) { ReservationRequest reservationRequest = context.ReservationRequests.Single(x => x.Id == requestId); reservationRequest.Status = status; context.SaveChanges(); return(new GenericStatusMessage(true)); } }
public async Task <GenericObjectResponse <RoomResponse> > AddRoom(CreateRoomPayload payload, long?userId) { try { Logger.Debug($"Attempting to create new room for user {userId}"); RoomResponse roomResponse = null; RoomValidationService service = new RoomValidationService(); GenericStatusMessage validationResult = service.ValidateRoomData(payload); if (!validationResult.Success) { return(new GenericObjectResponse <RoomResponse>(validationResult.Message)); } using (ReservationDataContext context = new ReservationDataContext()) { Room room = ConvertRoomFromPayload(payload, userId); context.Rooms.Add(room); context.SaveChanges(); roomResponse = ConvertRoomToResponse(room, userId); } Logger.Debug($"Attempting to create working hours for room {roomResponse.Id}"); WorkingHoursManipulationService workingHoursService = new WorkingHoursManipulationService(); GenericObjectResponse <List <WorkingHoursPayload> > workingHours = workingHoursService.ChangeWorkingHoursForRoom(roomResponse.Id, payload.WorkingHours); if (!workingHours.Status.Success) { Logger.Error($"failed to create working hours for room {roomResponse.Id}, Deleting created room."); using (ReservationDataContext context = new ReservationDataContext()) { Room room = context.Rooms.Single(x => x.Id == roomResponse.Id); context.Rooms.Remove(room); context.SaveChanges(); } return(new GenericObjectResponse <RoomResponse>($"Failed to add room due to faulty working hours: {workingHours.Status.Message}")); } roomResponse.WorkingHours = workingHours.Object; Logger.Debug($"Room created for user {userId}."); LatLon latLon = await AddLatLonForRoom(roomResponse.Id); if (latLon != null) { roomResponse.Lat = latLon.Lat; roomResponse.Lon = latLon.Lon; } return(new GenericObjectResponse <RoomResponse>(roomResponse)); } catch (DbEntityValidationException e) { string exceptionMessage = e.EntityValidationErrors.FirstOrDefault()?.ValidationErrors.FirstOrDefault()?.ErrorMessage; Logger.Error($"Failed to create room. Error: '{exceptionMessage}'"); return(new GenericObjectResponse <RoomResponse>("Failed to add the room, please contact support.")); } }
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)); }
public GenericObjectResponse <RoomResponse> GetRoomById(long roomId, long?userId, bool expand) { RoomManipulationService roomManipulationService = new RoomManipulationService(); using (ReservationDataContext context = new ReservationDataContext()) { var roomQuery = expand ? context.Rooms.Include(x => x.WorkingHours).Include(x => x.Reservations) : context.Rooms; var room = roomQuery.SingleOrDefault(x => x.Id == roomId); return(room != null ? new GenericObjectResponse <RoomResponse>(roomManipulationService.ConvertRoomToResponse(room, userId)) : new GenericObjectResponse <RoomResponse>("Room not found.")); } }
public GenericListResponse <ReservationRequestResponse> GetUserReservations(long userId) { using (ReservationDataContext context = new ReservationDataContext()) { List <ReservationRequest> reservations = context.ReservationRequests.Include(x => x.Room).Where(x => x.UserId == userId).ToList(); ReservationManipulationService reservationManipulationService = new ReservationManipulationService(); List <ReservationRequestResponse> reservationResponses = reservations.Select(x => { bool returnAllData = x.Room.OwnerId == userId || x.UserId == userId; return(reservationManipulationService.ConvertToResponse(x, returnAllData)); }).OrderBy(x => x.RentStart).ToList(); return(new GenericListResponse <ReservationRequestResponse>(reservationResponses, reservationResponses.Count)); } }
public GenericListResponse <RoomResponse> GetRoomsByNameOrCity(long?userId, string city, string name, int skip, int take) { RoomManipulationService roomManipulationService = new RoomManipulationService(); using (ReservationDataContext context = new ReservationDataContext()) { var roomsQuery = context.Rooms.Include(x => x.WorkingHours) .ToList() .Where(x => CompareStrings(city, x.City) || CompareStrings(name, x.Name)); List <RoomResponse> rooms = roomsQuery .OrderBy(x => x.Id) .Skip(skip) .Take(take) .ToList() .Select(x => roomManipulationService.ConvertRoomToResponse(x, userId)) .ToList(); int count = roomsQuery.Count(); return(new GenericListResponse <RoomResponse>(rooms, count)); } }
public GenericListResponse <ReservationRequestResponse> GetReservationsByDate(long roomId, DateTime startDate, DateTime endDate, long userId, int skip, int take) { using (ReservationDataContext context = new ReservationDataContext()) { Room room = context.Rooms.Include(x => x.Reservations).Single(x => x.Id == roomId); IEnumerable <ReservationRequest> reservationsQuery = room.Reservations.Where(x => x.RentStart >= startDate && x.RentStart <= endDate && (x.Status != ReservationStatus.Rejected || (room.OwnerId == userId || x.UserId == userId))); List <ReservationRequest> reservationList = reservationsQuery.Skip(skip).Take(take).ToList(); int totalCount = reservationsQuery.Count(); long[] reservationIds = reservationList.Select(x => x.Id).ToArray(); List <ReservationRequest> expandedReservationList = context.ReservationRequests.Include(x => x.User).Where(x => reservationIds.Contains(x.Id)).ToList(); ReservationManipulationService reservationManipulationService = new ReservationManipulationService(); List <ReservationRequestResponse> reservationResponses = expandedReservationList.Select(x => { bool returnAllData = room.OwnerId == userId || x.UserId == userId; return(reservationManipulationService.ConvertToResponse(x, returnAllData)); }).OrderBy(x => x.RentStart).ToList(); return(new GenericListResponse <ReservationRequestResponse>(reservationResponses, totalCount)); } }
public GenericStatusMessage AddUser(CreateUserPayload payload, UserRole role) { try { Logger.Debug($"Attempting to create new user {payload.Username}"); using (ReservationDataContext context = new ReservationDataContext()) { User user = ConvertUserFromPayload(payload, role); context.Users.Add(user); context.SaveChanges(); } Logger.Debug($"{payload.Username} was created successfully."); return(new GenericStatusMessage(true)); } catch (DbEntityValidationException e) { string exceptionMessage = e.EntityValidationErrors.FirstOrDefault()?.ValidationErrors.FirstOrDefault()?.ErrorMessage; Logger.Error($"Failed to create user {payload.Username}. Error: '{exceptionMessage}'"); return(new GenericStatusMessage(false, "Failed to add user, please contact support.")); } }
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)); }
public GenericStatusMessage ChangePassword(PasswordChangePayload payload, long userId) { using (ReservationDataContext context = new ReservationDataContext()) { User user = context.Users.Single(x => x.Id == userId); bool correctPassword = PasswordHasher.Validate(payload.CurrentPassword, user.PasswordHash); if (!correctPassword) { Logger.Debug($"{user.Username} failed to change password due to incorrect password."); return(new GenericStatusMessage(false, "Password incorrect.")); } else if (payload.NewPassword != payload.NewPasswordAgain) { Logger.Debug($"{user.Username} failed to change password due to mismatching passwords."); return(new GenericStatusMessage(false, "Passwords do not match.")); } user.PasswordHash = PasswordHasher.Create(payload.NewPassword); context.SaveChanges(); return(new GenericStatusMessage(true)); } }
private async Task <LatLon> AddLatLonForRoom(long roomId) { using (ReservationDataContext context = new ReservationDataContext()) { Room room = context.Rooms.Single(x => x.Id == roomId); IGeolocationClient geolocationClient = new MapQuestClient(); try { LatLon latLon = await geolocationClient.ForwardGeolocation(room.Country, room.City, room.Street, room.BuildingNumber); room.Lat = latLon.Lat; room.Lon = latLon.Lon; context.SaveChanges(); return(latLon); } catch (Exception e) { Logger.Error($"Failed to extract lat lon information for {roomId}: {e.Message}"); return(null); } } }
/// <summary> /// Returns the user's ID if token is valid, the user exists, and the role is correct. /// </summary> /// <param name="username"></param> /// <param name="token"></param> /// <param name="requiredRoles"></params /// <returns></returns> public long?ValidateUserToken(string username, Guid token, UserRole[] requiredRoles) { using (ReservationDataContext context = new ReservationDataContext()) { User user = context.Users.SingleOrDefault(x => x.Username == username && x.Token == token && requiredRoles.Contains(x.Role)); if (user == null) { Logger.Debug($"{username} does not exist."); return(null); } if (user.TokenExpiryDate < DateTime.UtcNow) { Logger.Debug($"{username}'s token has expired."); return(null); } user.TokenExpiryDate = DateTime.UtcNow + TokenExpiryWindow; context.SaveChanges(); return(user.Id); } }
public GenericListResponse <RoomResponse> GetRoomsByLatLonAndRadius(long?userId, decimal lat, decimal lon, int radius, int skip = 0, int take = 10) { RoomManipulationService roomManipulationService = new RoomManipulationService(); using (ReservationDataContext context = new ReservationDataContext()) { var roomsQuery = context.Rooms.Include(x => x.WorkingHours) .Where(x => x.Lat.HasValue && x.Lon.HasValue) .ToList() .Select(x => new { Room = x, Distance = GetDistance(lon, lat, x.Lon.Value, x.Lat.Value) }) .Where(x => x.Distance <= radius); List <RoomResponse> rooms = roomsQuery .Skip(skip) .Take(take) .Select(x => roomManipulationService.ConvertRoomToResponse(x.Room, userId)) .ToList(); int count = roomsQuery.Count(); return(new GenericListResponse <RoomResponse>(rooms, count)); } }
public override void Up() { UserManipulationService userManipulationService = new UserManipulationService(); CreateUserPayload owner = new CreateUserPayload { FirstName = "Ron", LastName = "Shachar", Country = "Israel", City = "Tel Aviv", Street = "Rambam", BuildingNumber = 6, Password = "******", ConfirmPassword = "******", Username = "******" }; userManipulationService.AddUser(owner, UserRole.RoomOwner); long ownerId = 0; using (ReservationDataContext context = new ReservationDataContext()) { ownerId = context.Users.Single(x => x.Username == "*****@*****.**").Id; } RoomManipulationService roomManipulationService = new RoomManipulationService(); CreateRoomPayload roomPayload = new CreateRoomPayload { Name = "Globo Gym", Country = "Israel", City = "Givatayim", Street = "Borochov", BuildingNumber = 5, IsActive = true, WorkingHours = CreateDefaultWorkingHours(Days.Sunday, Days.Tuesday, Days.Thursday) }; roomManipulationService.AddRoom(roomPayload, ownerId); }
public UserResponse FindUser(string usernameToFind, long queryingUserId) { using (ReservationDataContext context = new ReservationDataContext()) { User queryingUser = context.Users.Single(x => x.Id == queryingUserId); if (usernameToFind == queryingUser.Username) { Logger.Debug($"User {usernameToFind} found itself."); return(ConvertFromUser(queryingUser)); } else if (queryingUser.Role == UserRole.RoomOwner) { User userToFind = context.Users.SingleOrDefault(x => x.Username == usernameToFind); if (userToFind != null && userToFind.Role == UserRole.Coach) { Logger.Debug($"User {queryingUser.Username} found {usernameToFind}."); return(ConvertFromUser(userToFind)); } } Logger.Debug($"No user {usernameToFind} was found."); return(null); } }
public async Task <GenericObjectResponse <RoomResponse> > ChangeRoomData(CreateRoomPayload payload, long roomId) { RoomValidationService service = new RoomValidationService(); GenericStatusMessage validationResponse = service.ValidateRoomData(payload, false); RoomResponse roomResponse = null; if (validationResponse.Success) { using (ReservationDataContext context = new ReservationDataContext()) { Room room = context.Rooms.Include(x => x.WorkingHours).Single(x => x.Id == roomId); room.Name = payload.Name ?? room.Name; room.Size = payload.Size ?? room.Size; room.MaxNumberOfPeople = payload.MaxNumberOfPeople ?? room.MaxNumberOfPeople; room.Country = payload.Country ?? room.Country; room.City = payload.City ?? room.City; room.Street = payload.Street ?? room.Street; room.BuildingNumber = payload.BuildingNumber ?? room.BuildingNumber; context.SaveChanges(); roomResponse = ConvertRoomToResponse(room, room.OwnerId); } LatLon latLon = await AddLatLonForRoom(roomResponse.Id); if (latLon != null) { roomResponse.Lat = latLon.Lat; roomResponse.Lon = latLon.Lon; } return(new GenericObjectResponse <RoomResponse>(roomResponse)); } else { return(new GenericObjectResponse <RoomResponse>(validationResponse.Message)); } }
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))); } }