示例#1
0
        /// <summary>
        /// adds the roomtype to the business specified, does some unavailability logic too
        /// </summary>
        /// <param name="currentRoomType">current room type</param>
        /// <param name="currentBusiness">current business</param>
        /// <param name="availabilitySearchCriteria">original search criteria</param>
        private void AddRoomTypeToBusiness(AvailabilityResultRoomType currentRoomType, AvailabilityResultBusiness currentBusiness, AvailabilitySearchCriteria availabilitySearchCriteria)
        {
            // add room type and business of last business / room type
            if (currentRoomType != null)
            {
                // filter up unavailability
                if (currentRoomType.RatesAndRoomsAvailable.Max(rt => rt.RoomList != null ? rt.RoomList.Count : 0) == 0 ||
                    currentRoomType.RatesAndRoomsAvailable.TrueForAll(rt => rt.UnavailabilityReason.HasValue))
                {
                    currentRoomType.UnAvailabilityReasonCode =
                        currentRoomType.RatesAndRoomsAvailable.Min(rt => rt.UnavailabilityReason);
                }

                currentBusiness.RoomTypes.Add(currentRoomType);
            }
        }
示例#2
0
        /// <summary>
        /// Adds the business to the list and filters up unavailability reasons
        /// </summary>
        /// <param name="currentBusiness">current business</param>
        /// <param name="availableBusinesses">list of businesses for result</param>
        private void AddBusinessToList(AvailabilityResultBusiness currentBusiness, List<AvailabilityResultBusiness> availableBusinesses)
        {
            if (currentBusiness != null)
            {
                // filter up unavailability
                currentBusiness.UnavailabilityReasonCode = currentBusiness.RoomTypes.Min(rt => rt.UnAvailabilityReasonCode);

                // if there are any room types with availability then reset the overall business unavailability
                if (currentBusiness.RoomTypes.Any(r => !r.UnAvailabilityReasonCode.HasValue))
                {
                    currentBusiness.UnavailabilityReasonCode = null;
                }

                availableBusinesses.Add(currentBusiness);
            }
        }
        /// <summary>
        /// Convert the AvailabilityResultBusiness Model to the Dto Object
        /// </summary>
        /// <param name="availabilityResultBusiness">availabilityResultBusiness to convert</param>
        /// <returns>AvailabilityResultBusinessDto</returns>
        private static AvailabilityResultBusinessDto ConvertAvailabilityResultBusinessToDto(AvailabilityResultBusiness availabilityResultBusiness)
        {
            // Convert the main object
            var availabilityResultBusinessDto = new AvailabilityResultBusinessDto
                       {
                           BusinessId = availabilityResultBusiness.BusinessId
                       };

            // Convert the sub object
            List<AvailabilityResultRoomTypeDto> roomTypesDtos =
                availabilityResultBusiness.RoomTypes.ConvertAll(ConvertAvailabilityResultRoomTypeToDto);

            // Finalize and return
            availabilityResultBusinessDto.RoomTypes = roomTypesDtos;
            return availabilityResultBusinessDto;
        }
示例#4
0
        /// <summary>
        /// Check Availability for supplied criteria
        /// </summary>
        /// <param name="availabilitySearchCriteria">Criteria to consider in availability check</param>
        /// <param name="existingBooking">booking to be modified (if already loaded)</param>
        /// <returns>The Availability Result based on the criteria supplied</returns>
        public virtual AvailabilitySearchResult CheckAvailability(AvailabilitySearchCriteria availabilitySearchCriteria, Model.Booking.Booking existingBooking = null)
        {
            Logger.LogInfo("==========CheckAvailability Called==========");
            Logger.LogDebugAsXml(availabilitySearchCriteria);
            AvailabilitySearchResult result = null;

            if (availabilitySearchCriteria.ModifyBookingId.HasValue)
            {
                existingBooking = existingBooking ?? bookingManager.GetByKey(availabilitySearchCriteria.ModifyBookingId.Value);

                //Modify the presented criteria if this check is for a pre-existing booking
                result = UpdateCriteriaForExistingBooking(availabilitySearchCriteria, existingBooking);
                if (result != null)
                {
                    return result;
                }
            }

            // Validate the criteria
            availabilitySearchCriteria.IsValid();

            // Get the availability, only return available if there is no channel (help performance on pms slightly)
            bool onlyReturnAvailable = !availabilitySearchCriteria.ChannelId.HasValue;

            // set up tasks for availability / rate fetch
            List<RoomsAvailability> candidateRooms = null;
            
            // check if requested currency isn't one of the two for each business
            var criteriaSentToSproc = availabilitySearchCriteria.Clone();

            Task availabilityTask = TaskProxy.StartTask(
                () =>
                candidateRooms =
                pricingAvailabilityDao.GetAvailabilityForBusinessesBetweenDates(onlyReturnAvailable,
                                                                                criteriaSentToSproc));

            // set up concurrent dictionary with capacity = number of businesses 
            Dictionary<long, List<RateCache>> rateCacheDict = null;

            Task cacheTask = TaskProxy.StartTask(() => rateCacheDict = RateCacheManager.GetRatesByBusinessesAndDateRange
                                                                                                                   (availabilitySearchCriteria.BusinessIds,
                                                                                                                    availabilitySearchCriteria
                                                                                                                        .StartDate.ConvertToTimeZoneLessDateTime(),
                                                                                                                    availabilitySearchCriteria
                                                                                                                        .EndDate.ConvertToTimeZoneLessDateTime()));

            Task.WaitAll(availabilityTask, cacheTask);

            // set the currency for the returned candidates
            // previously done in sproc
            var currencyCache = Cache.Cache.CurrencyCache.GetValue("root");
            var requestedCurrency = currencyCache.Get(availabilitySearchCriteria.RequestedCurrency);
            string isoCode = availabilitySearchCriteria.RequestedCurrency;
            if (requestedCurrency != null)
            {
                isoCode = requestedCurrency.ISOCode;
            }

            foreach (var cR in candidateRooms)
            {
                cR.Currency = requestedCurrency;
                cR.CurrencyCode = isoCode;
            }

            // create initial list of businesses with those added that had neither currency
            List<AvailabilityResultBusiness> availableBusinesses = (from id in availabilitySearchCriteria.BusinessIds where !criteriaSentToSproc.BusinessIds.Contains(id) select new AvailabilityResultBusiness(UnavailabilityReasonCode.MissingCurrency, id)).ToList();

            // If there is no rooms return AvailabilitySearchResult as there is no rooms to check for RoomTypes etc
            if (candidateRooms == null || candidateRooms.Count == 0)
            {
                // no availability or bad business, return empty result back
                var nullBusinessResult = GetNullBusinessAvailabilityResult(availabilitySearchCriteria);
                // so that if it was because of currency, we send that back
                nullBusinessResult.BusinessCandidates = availableBusinesses;
                if (nullBusinessResult.BusinessCandidates.Any(bc => bc.UnavailabilityReasonCode.HasValue))
                {
                    nullBusinessResult.UnavailabilityReasonCode =
                        nullBusinessResult.BusinessCandidates.First(bc => bc.UnavailabilityReasonCode.HasValue).UnavailabilityReasonCode;
                }

                return nullBusinessResult;
            }

            // assign cache and deal with 0 prices / minloss based on cache results
            UpdateAvailabilityWithRateCache(availabilitySearchCriteria, candidateRooms, rateCacheDict);

            // set prepay based on rates set from above
            UpdateAvailabilityWithPrepay(candidateRooms, availabilitySearchCriteria);

            // If modify booking for an OTA booking then update all the rates with the current booking rate as OTA booking pricing cannot be changed
            if (availabilitySearchCriteria.ModifyBookingId.HasValue && existingBooking.Order.IsOTA)
            {
                // Set all fields on the available room object
                foreach (var room in candidateRooms)
                {
                    room.TotalRate = existingBooking.Cost.Value;
                    SetRoomTypeName(room);
                }
            }
            else
            {
                candidateRooms.ForEach(SetRoomTypeName);
            }

            // Create the object to be returned
            result = new AvailabilitySearchResult
                         {
                             StartDate = availabilitySearchCriteria.StartDate,
                             EndDate = availabilitySearchCriteria.EndDate,
                             NoOfAdults = availabilitySearchCriteria.NumberOfAdults,
                             NoOfChildren = availabilitySearchCriteria.NumberOfChildren
                         };

            
            // sort the results by business
            AvailabilityResultBusiness currentBusiness = null;
            AvailabilityResultRoomType currentRoomType = null;

            foreach (RoomsAvailability candidate in candidateRooms)
            {
                if (currentBusiness == null ||
                    candidate.BusinessId != currentBusiness.BusinessId)
                {
                    // Currently needs update to get all the businesses in list
                    // We also need to check the criteria is valid for the correct time zone of the businesses. All businesses are assumed in the same time zone
                    var business = Cache.Cache.Business.TryGetValue(candidate.BusinessId);

                    if (business == null)
                    {
                        continue;
                    }

                    // for last of previous business
                    AddRoomTypeToBusiness(currentRoomType, currentBusiness, availabilitySearchCriteria);
                    currentRoomType = null;

                    // add old business to list
                    AddBusinessToList(currentBusiness, availableBusinesses);

                    // set up new business
                    var newBusiness = new AvailabilityResultBusiness
                                                {
                                                    BusinessId = candidate.BusinessId,
                                                    ShortName = business.ShortName,
                                                    RoomTypes = new List<AvailabilityResultRoomType>(),
                                                    Is3DSecureAllowed = business.MerchantDetails.Is3DSecureAllowed ?? true,
                                                    IsAmexAllowed = business.MerchantDetails.IsAmexAllowed ?? true,
                                                    IsPaypalAllowed = business.MerchantDetails.IsPaypalAllowed ?? false
                                                };
                    currentBusiness = newBusiness;
                }

                // add this roomtype candidate to the business
                if (currentRoomType == null ||
                    candidate.RoomTypeId != currentRoomType.RoomTypeId)
                {
                    // first add the old one if it is present
                    AddRoomTypeToBusiness(currentRoomType, currentBusiness, availabilitySearchCriteria);

                    // set up new room type
                    AvailabilityResultRoomType newRoomType = new AvailabilityResultRoomType
                                          {
                                              RoomTypeId = candidate.RoomTypeId,
                                              BusinessId = candidate.BusinessId,
                                              RoomTypeName = candidate.RoomTypeName,
                                              RatesAndRoomsAvailable = new List<RoomsAvailability>(),
                                              UnAvailabilityReasonCode = null
                                          };

                    currentRoomType = newRoomType;
                }

                currentRoomType.RatesAndRoomsAvailable.Add(candidate);
            }

            AddRoomTypeToBusiness(currentRoomType, currentBusiness, availabilitySearchCriteria);

            AddBusinessToList(currentBusiness, availableBusinesses);

            if (!availableBusinesses.Any())
            {
                // bad business list, return empty result back
                return GetNullBusinessAvailabilityResult(availabilitySearchCriteria);
            }
            
            result.BusinessCandidates = availableBusinesses;

            CorrectWasPriceForResults(candidateRooms);


            Logger.LogInfo("==========CheckAvailability Returns==========");
            Logger.LogDebugAsXml(result);

            return result;
        }
        /// <summary>
        /// Convert the AvailabilityResultBusiness Model to the Dto Object
        /// </summary>
        /// <param name="availabilityResultBusiness">availabilityResultBusiness to convert</param>
        /// <returns>AvailabilityResultBusinessDto</returns>
        private static OnlineAvailabilityResultBusinessDto ConvertAvailabilityResultBusinessToOnlineDto(AvailabilityResultBusiness availabilityResultBusiness)
        {
            // Convert the main object
            var availabilityResultBusinessDto = new OnlineAvailabilityResultBusinessDto
            {
                BusinessId = availabilityResultBusiness.BusinessId,
                ShortName = availabilityResultBusiness.ShortName,
                Is3DSecureAllowed = availabilityResultBusiness.Is3DSecureAllowed,
                IsAmexAllowed = availabilityResultBusiness.IsAmexAllowed,
                IsPaypalAllowed = availabilityResultBusiness.IsPaypalAllowed
            };

            // Convert the sub object
            var roomsAvailable = new List<RoomsAvailabilityDto>();
            availabilityResultBusiness.RoomTypes.ForEach(rt => roomsAvailable.AddRange(Mapper.Map<List<RoomsAvailabilityDto>>(rt.RatesAndRoomsAvailable)));

            // Get all the reason codes present
            var reasonCodes = new List<UnavailabilityReasonCodeDto>();

            if (availabilityResultBusiness.UnavailabilityReasonCode != null)
            {
                reasonCodes.Add((UnavailabilityReasonCodeDto)availabilityResultBusiness.UnavailabilityReasonCode);
            }

            // Finalize and return
            availabilityResultBusinessDto.RoomTypes = roomsAvailable;
            availabilityResultBusinessDto.NoAvailabilityReasons = reasonCodes;

            return availabilityResultBusinessDto;
        }