protected override async Task <Booking> AddStaticData(Booking booking, BookingAvailabilityInfo availabilityInfo)
        {
            var(_, isFailure, accommodation, error) = await _accommodationMapperClient.GetAccommodation(availabilityInfo.HtId, booking.LanguageCode ?? "en");

            if (isFailure)
            {
                throw new Exception($"Cannot get accommodation for '{availabilityInfo.HtId}' with error `{error.Detail}`");
            }

            var edoAccommodation = accommodation.ToEdoContract();
            var location         = edoAccommodation.Location;

            booking.Location = new AccommodationLocation(location.Country,
                                                         location.Locality,
                                                         location.LocalityZone,
                                                         location.Address,
                                                         location.Coordinates);

            booking.AccommodationId   = edoAccommodation.Id;
            booking.AccommodationName = edoAccommodation.Name;

            if (accommodation.Photos.Any())
            {
                booking.AccommodationInfo = new Data.Bookings.AccommodationInfo(
                    new ImageInfo(edoAccommodation.Photos[0].Caption, edoAccommodation.Photos[0].SourceUrl));
            }

            return(booking);
        }
예제 #2
0
        public Task Set(string referenceCode, AccommodationBookingRequest request, BookingAvailabilityInfo availabilityInfo)
        {
            var bookingRequest = new BookingRequest
            {
                ReferenceCode    = referenceCode,
                RequestData      = JsonConvert.SerializeObject(request),
                AvailabilityData = JsonConvert.SerializeObject(availabilityInfo),
            };

            _edoContext.BookingRequests.Add(bookingRequest);
            return(_edoContext.SaveChangesAsync());
        }
예제 #3
0
        protected virtual Task <Booking> AddStaticData(Booking booking, BookingAvailabilityInfo availabilityInfo)
        {
            booking.Location = new AccommodationLocation(availabilityInfo.CountryName,
                                                         availabilityInfo.LocalityName,
                                                         availabilityInfo.ZoneName,
                                                         availabilityInfo.Address,
                                                         availabilityInfo.Coordinates);

            booking.AccommodationId   = availabilityInfo.AccommodationId;
            booking.AccommodationName = availabilityInfo.AccommodationName ?? string.Empty;
            booking.AccommodationInfo = new Data.Bookings.AccommodationInfo(
                new ImageInfo(availabilityInfo.AccommodationInfo.Photo.Caption, availabilityInfo.AccommodationInfo.Photo.SourceUrl));

            return(Task.FromResult(booking));
        }
예제 #4
0
        public Task Set(Guid searchId, Guid roomContractSetId, string htId, DataWithMarkup <RoomContractSetAvailability> availability, Deadline agentDeadline,
                        Deadline supplierDeadline, CreditCardRequirement?cardRequirement, string supplierAccommodationCode, AvailabilityRequest availabilityRequest)
        {
            var accommodation       = availability.Data.Accommodation;
            var key                 = BuildKey(searchId, htId, roomContractSetId);
            var roomSetAvailability = availability.Data;
            var location            = accommodation.Location;

            var bookingAvailabilityInfo = new BookingAvailabilityInfo(
                accommodationId: supplierAccommodationCode,
                accommodationName: accommodation.Name,
                accommodationInfo: new AccommodationInfo(accommodation.Photo),
                roomContractSet: roomSetAvailability.RoomContractSet,
                zoneName: location.LocalityZone,
                localityName: location.Locality,
                countryName: location.Country,
                countryCode: location.CountryCode,
                address: location.Address,
                coordinates: location.Coordinates,
                checkInDate: roomSetAvailability.CheckInDate,
                checkOutDate: roomSetAvailability.CheckOutDate,
                numberOfNights: roomSetAvailability.NumberOfNights,
                supplier: availability.Data.RoomContractSet.Supplier.Value,
                appliedMarkups: availability.AppliedMarkups,
                convertedSupplierPrice: availability.ConvertedSupplierPrice,
                originalSupplierPrice: availability.OriginalSupplierPrice,
                availabilityId: roomSetAvailability.AvailabilityId,
                htId: htId,
                availablePaymentTypes: roomSetAvailability.AvailablePaymentMethods,
                isDirectContract: roomSetAvailability.RoomContractSet.IsDirectContract,
                agentDeadline: agentDeadline,
                supplierDeadline: supplierDeadline,
                cardRequirement: cardRequirement,
                availabilityRequest: availabilityRequest);

            return(_doubleFlow.SetAsync(key, bookingAvailabilityInfo, CacheExpirationTime));
        }
예제 #5
0
        public async Task <string> Register(AccommodationBookingRequest bookingRequest,
                                            BookingAvailabilityInfo availabilityInfo, AgentContext agentContext, string languageCode)
        {
            var(_, _, booking, _) = await Result.Success()
                                    .Map(GetTags)
                                    .Map(Create);

            return(booking.ReferenceCode);


            async Task <(string itn, string referenceCode)> GetTags()
            {
                string itn;

                if (string.IsNullOrWhiteSpace(bookingRequest.ItineraryNumber))
                {
                    itn = await _tagProcessor.GenerateItn();
                }
                else
                {
                    // User can send reference code instead of itn
                    if (!_tagProcessor.TryGetItnFromReferenceCode(bookingRequest.ItineraryNumber, out itn))
                    {
                        itn = bookingRequest.ItineraryNumber;
                    }

                    if (!await AreExistBookingsForItn(itn, agentContext.AgentId))
                    {
                        itn = await _tagProcessor.GenerateItn();
                    }
                }

                var referenceCode = await _tagProcessor.GenerateReferenceCode(
                    ServiceTypes.HTL,
                    availabilityInfo.CountryCode,
                    itn);

                return(itn, referenceCode);
            }

            async Task <Data.Booking.Booking> Create((string itn, string referenceCode) tags)
            {
                var createdBooking = BookingFactory.Create(
                    _dateTimeProvider.UtcNow(),
                    agentContext,
                    tags.itn,
                    tags.referenceCode,
                    availabilityInfo,
                    bookingRequest.PaymentMethod,
                    bookingRequest,
                    languageCode,
                    availabilityInfo.Supplier,
                    availabilityInfo.RoomContractSet.Deadline.Date,
                    availabilityInfo.CheckInDate,
                    availabilityInfo.CheckOutDate);

                _context.Bookings.Add(createdBooking);
                await _context.SaveChangesAsync();

                _context.Entry(createdBooking).State = EntityState.Detached;

                return(createdBooking);
            }
        }
예제 #6
0
        public async Task <Result <Booking> > Register(AccommodationBookingRequest bookingRequest,
                                                       BookingAvailabilityInfo availabilityInfo, PaymentTypes paymentMethod, AgentContext agentContext, string languageCode)
        {
            var(_, isFailure, booking, error) = await CheckRooms()
                                                .Map(GetTags)
                                                .Map(Create)
                                                .Tap(SaveRequestInfo)
                                                .Tap(LogBookingStatus)
                                                .Tap(SaveMarkups)
                                                .Tap(CreateSupplierOrder);

            if (isFailure)
            {
                return(Result.Failure <Booking>(error));
            }

            _logger.LogBookingRegistrationSuccess(booking.ReferenceCode);
            return(booking);


            Result CheckRooms()
            {
                if (bookingRequest.RoomDetails.Count != availabilityInfo.AvailabilityRequest.RoomDetails.Count)
                {
                    return(Result.Failure("Rooms does not correspond to search rooms"));
                }

                for (var i = 0; i < bookingRequest.RoomDetails.Count; i++)
                {
                    var adultsCount   = bookingRequest.RoomDetails[i].Passengers.Count(p => p.Age == null);
                    var childrenCount = bookingRequest.RoomDetails[i].Passengers.Count(p => p.Age != null);

                    if (availabilityInfo.AvailabilityRequest.RoomDetails[i].AdultsNumber != adultsCount ||
                        availabilityInfo.AvailabilityRequest.RoomDetails[i].ChildrenAges.Count != childrenCount)
                    {
                        return(Result.Failure("Rooms does not correspond to search rooms"));
                    }
                }

                return(Result.Success());
            }

            async Task <(string itn, string referenceCode)> GetTags()
            {
                string itn;

                if (string.IsNullOrWhiteSpace(bookingRequest.ItineraryNumber))
                {
                    itn = await _tagProcessor.GenerateItn();
                }
                else
                {
                    // User can send reference code instead of itn
                    if (!_tagProcessor.TryGetItnFromReferenceCode(bookingRequest.ItineraryNumber, out itn))
                    {
                        itn = bookingRequest.ItineraryNumber;
                    }

                    if (!await AreExistBookingsForItn(itn, agentContext.AgentId))
                    {
                        itn = await _tagProcessor.GenerateItn();
                    }
                }

                var referenceCode = await _tagProcessor.GenerateReferenceCode(
                    ServiceTypes.HTL,
                    availabilityInfo.CountryCode,
                    itn);

                return(itn, referenceCode);
            }

            async Task <Booking> Create((string itn, string referenceCode) tags)
            {
                var createdBooking = await CreateBooking(
                    created : _dateTimeProvider.UtcNow(),
                    agentContext : agentContext,
                    itineraryNumber : tags.itn,
                    referenceCode : tags.referenceCode,
                    clientReferenceCode : bookingRequest.ClientReferenceCode,
                    availabilityInfo : availabilityInfo,
                    paymentMethod : paymentMethod,
                    bookingRequest : bookingRequest,
                    languageCode : languageCode);

                _context.Bookings.Add(createdBooking);
                await _context.SaveChangesAsync();

                _context.Entry(createdBooking).State = EntityState.Detached;

                return(createdBooking);
            }

            Task SaveRequestInfo(Booking booking)
            => _requestStorage.Set(booking.ReferenceCode, bookingRequest, availabilityInfo);


            Task LogBookingStatus(Booking booking)
            {
                var changeReason = new BookingChangeReason
                {
                    Event  = BookingChangeEvents.Create,
                    Source = BookingChangeSources.System
                };

                return(_changeLogService.Write(booking, BookingStatuses.Created, booking.Created.DateTime,
                                               agentContext.ToApiCaller(), changeReason));
            }

            Task SaveMarkups(Booking booking)
            => _appliedBookingMarkupRecordsManager.Create(booking.ReferenceCode, availabilityInfo.AppliedMarkups);


            Task CreateSupplierOrder(Booking booking)
            => _supplierOrderService.Add(referenceCode: booking.ReferenceCode,
                                         serviceType: ServiceTypes.HTL,
                                         convertedPrice: availabilityInfo.ConvertedSupplierPrice,
                                         supplierPrice: availabilityInfo.OriginalSupplierPrice,
                                         deadline: availabilityInfo.SupplierDeadline,
                                         supplier: (int)booking.Supplier,
                                         paymentType: availabilityInfo.CardRequirement is not null
                        ? SupplierPaymentType.CreditCard
                        : SupplierPaymentType.DirectPayment,
                                         paymentDate: availabilityInfo.RoomContractSet.IsAdvancePurchaseRate
                        ? booking.Created.DateTime
                        : booking.CheckOutDate.DateTime);
        }
예제 #7
0
        private async Task <Booking> CreateBooking(DateTime created, AgentContext agentContext, string itineraryNumber,
                                                   string referenceCode, string clientReferenceCode, BookingAvailabilityInfo availabilityInfo, PaymentTypes paymentMethod,
                                                   AccommodationBookingRequest bookingRequest, string languageCode)
        {
            var booking = new Booking
            {
                Created             = created,
                ItineraryNumber     = itineraryNumber,
                ReferenceCode       = referenceCode,
                ClientReferenceCode = clientReferenceCode,
                Status                = BookingStatuses.Created,
                PaymentType           = paymentMethod,
                LanguageCode          = languageCode,
                Supplier              = availabilityInfo.Supplier,
                PaymentStatus         = BookingPaymentStatuses.NotPaid,
                DeadlineDate          = availabilityInfo.RoomContractSet.Deadline.Date,
                CheckInDate           = availabilityInfo.CheckInDate,
                CheckOutDate          = availabilityInfo.CheckOutDate,
                HtId                  = availabilityInfo.HtId,
                Tags                  = availabilityInfo.RoomContractSet.Tags,
                IsDirectContract      = availabilityInfo.RoomContractSet.IsDirectContract,
                CancellationPolicies  = availabilityInfo.RoomContractSet.Deadline.Policies,
                IsAdvancePurchaseRate = availabilityInfo.RoomContractSet.IsAdvancePurchaseRate,
                IsPackage             = availabilityInfo.RoomContractSet.IsPackageRate
            };

            AddRequestInfo(bookingRequest);
            AddServiceDetails();
            AddAgentInfo();
            AddRooms(availabilityInfo.RoomContractSet.Rooms, bookingRequest.RoomDetails);
            booking = await AddStaticData(booking, availabilityInfo);

            return(booking);


            void AddRequestInfo(in AccommodationBookingRequest bookingRequestInternal)
            {
                booking.Nationality       = availabilityInfo.AvailabilityRequest.Nationality.ToUpper();
                booking.Residency         = availabilityInfo.AvailabilityRequest.Residency.ToUpper();
                booking.MainPassengerName = bookingRequestInternal.MainPassengerName.Trim();
            }

            void AddServiceDetails()
            {
                var rate = availabilityInfo.RoomContractSet.Rate;

                booking.TotalPrice = rate.FinalPrice.Amount;
                booking.Currency   = rate.Currency;
            }

            void AddAgentInfo()
            {
                booking.AgentId  = agentContext.AgentId;
                booking.AgencyId = agentContext.AgencyId;
            }

            void AddRooms(List <RoomContract> roomContracts, List <BookingRoomDetails> bookingRequestRoomDetails)
            {
                booking.Rooms = roomContracts
                                .Select((r, number) =>
                                        new BookedRoom(r.Type,
                                                       r.IsExtraBedNeeded,
                                                       r.Rate.FinalPrice,
                                                       r.BoardBasis,
                                                       r.MealPlan,
                                                       r.Deadline.Date,
                                                       r.ContractDescription,
                                                       r.Remarks,
                                                       r.Deadline,
                                                       GetCorrespondingPassengers(number),
                                                       r.IsAdvancePurchaseRate,
                                                       string.Empty))
                                .ToList();


                List <Passenger> GetCorrespondingPassengers(int number)
                => bookingRequestRoomDetails[number].Passengers
                .Select(p => new Passenger(p.Title, p.LastName.Trim(), p.FirstName.Trim(), p.IsLeader, p.Age))
                .ToList();
            }
        }
예제 #8
0
 public static Booking Create(DateTime created, AgentContext agentContext, string itineraryNumber,
                              string referenceCode, BookingAvailabilityInfo availabilityInfo, PaymentMethods paymentMethod,
                              in AccommodationBookingRequest bookingRequest, string languageCode, Suppliers supplier,