Ejemplo n.º 1
0
        public async Task<IActionResult> Book([FromBody] EdoContracts.Accommodations.BookingRequest bookingRequest)
        {
            var (_, isFailure, bookingDetails, error) = await _bookingService.Book(bookingRequest, LanguageCode);
            if (isFailure)
                return BadRequest(ProblemDetailsBuilder.Build(error));

            return Ok(bookingDetails);
        }
Ejemplo n.º 2
0
        public async Task <Result <EdoContracts.Accommodations.Booking> > Book(EdoContracts.Accommodations.BookingRequest bookingRequest, string languageCode)
        {
            return(await GetAvailabilityRequest()
                   .Bind(ProcessBooking)
                   .Map(Build));


            async Task <Result <EdoContracts.Accommodations.AvailabilityRequest> > GetAvailabilityRequest()
            {
                var availabilityRequest = await _availabilitySearchStorage.GetAvailabilityRequest(bookingRequest.AvailabilityId);

                if (availabilityRequest.Equals(default))
Ejemplo n.º 3
0
        public async Task <Result <Common.Models.Bookings.BookingOrder> > Book(EdoContracts.Accommodations.BookingRequest bookingRequest, EdoContracts.Accommodations.AvailabilityRequest availabilityRequest, string languageCode)
        {
            return(await GetRequiredHash()
                   .BindWithTransaction(_dbContext, requiredHash => GetAvailableRates(requiredHash)
                                        .Map(CreateBookingEntry)
                                        .Map(AddBookingEntry)
                                        .Bind(AddRoomOccupancy)));


            async Task <Result <string> > GetRequiredHash()
            {
                var hash = await _availabilityDataStorage.GetHash(bookingRequest.AvailabilityId, bookingRequest.RoomContractSetId);

                return(string.IsNullOrEmpty(hash)
                    ? Result.Failure <string>("Failed to retrieve the required hash")
                    : Result.Success(hash));
            }

            async Task <Result <AvailableRates> > GetAvailableRates(string requiredHash)
            {
                var error        = "Available rates not found";
                var availability = await _availabilityService.Get(availabilityRequest, languageCode);

                if (!availability.AvailableRates.Any())
                {
                    Result.Failure <Common.Models.Availabilities.Availability>(error);
                }

                foreach (var availableRates in availability.AvailableRates)
                {
                    var requiredRates = availableRates.Value.SingleOrDefault(ar => ar.Hash.Equals(requiredHash));
                    if (requiredRates != null)
                    {
                        return(Result.Success(requiredRates));
                    }
                }

                return(Result.Failure <AvailableRates>(error));
            }

            (Common.Models.Bookings.BookingOrder, AvailableRates) CreateBookingEntry(AvailableRates availableRates)
            {
                var accommodation = availableRates.Rates.First().Room.Accommodation;
                var utcNow        = _dateTimeProvider.UtcNow();

                return(new Common.Models.Bookings.BookingOrder
                {
                    Status = BookingStatuses.WaitingForConfirmation,
                    ReferenceCode = bookingRequest.ReferenceCode,
                    CheckInDate = availabilityRequest.CheckInDate,
                    CheckOutDate = availabilityRequest.CheckOutDate,
                    Created = utcNow,
                    Modified = utcNow,
                    BookingRequest = JsonDocumentUtilities.CreateJDocument(bookingRequest),
                    AvailabilityRequest = JsonDocumentUtilities.CreateJDocument(availabilityRequest),
                    AvailableRates = JsonDocumentUtilities.CreateJDocument(availableRates),
                    LanguageCode = languageCode,
                    ServiceSupplierId = accommodation.ServiceSupplierId,
                    AccommodationId = accommodation.Id
                }, availableRates);
            }

            async Task <(Common.Models.Bookings.BookingOrder bookingOrder, AvailableRates availableRates)> AddBookingEntry((Common.Models.Bookings.BookingOrder bookingOrder, AvailableRates availableRates) bookingOrderAndAvailableRates)
            {
                var entry = _dbContext.BookingOrders.Add(bookingOrderAndAvailableRates.bookingOrder);
                await _dbContext.SaveChangesAsync();

                _dbContext.DetachEntry(entry.Entity);

                return(entry.Entity, bookingOrderAndAvailableRates.availableRates);
            }

            async Task <Result <Common.Models.Bookings.BookingOrder> > AddRoomOccupancy((Common.Models.Bookings.BookingOrder bookingOrder, AvailableRates availableRates) bookingOrderAndAvailableRates)
            {
                var utcNow = _dateTimeProvider.UtcNow();

                foreach (var roomId in bookingOrderAndAvailableRates.availableRates.Rates.Select(rd => rd.Room.Id))
                {
                    _dbContext.RoomOccupancies.Add(new RoomOccupancy
                    {
                        RoomId         = roomId,
                        Created        = utcNow,
                        FromDate       = availabilityRequest.CheckInDate,
                        ToDate         = availabilityRequest.CheckOutDate,
                        BookingOrderId = bookingOrderAndAvailableRates.bookingOrder.Id
                    });
                }

                await _dbContext.SaveChangesAsync();

                return(Result.Success(bookingOrderAndAvailableRates.bookingOrder));
            }
        }