Example #1
0
 /// <summary>
 /// Returns CanCancel status for the booking
 /// </summary>
 /// <param name="booking">Booking object</param>
 /// <returns>True if booking can be cancelled</returns>
 private static bool GetCanCancelStatus(Booking booking)
 {
     return !(booking.Order.OrderSourceCode == SourceType.Online.GetCode() && 
              booking.Order.IntegrationType.HasValue &&
             (booking.Order.IntegrationType.Value == IntegrationTypeEnum.Push || 
              booking.Order.IntegrationType.Value == IntegrationTypeEnum.RequestResponse || 
              booking.Order.IntegrationType.Value == IntegrationTypeEnum.TouristInformationCentre) &&
              booking.StartDate >= DateTime.UtcNow.Date);
 }
Example #2
0
        /// <summary>
        /// Copies updated values from a ModifyBookingDto into a Booking (and attached Guest)
        /// </summary>
        /// <param name="modifyBookingDto">ModifyBookingDto (source)</param>
        /// <param name="booking">Booking (target)</param>
        private void UpdateBookingFromModifyBookingDto(SaveMobileBookingDto modifyBookingDto, Booking booking)
        {
            var room = roomManager.GetByKey(modifyBookingDto.RoomId, booking.BusinessId);
            if (room == null)
            {
                throw new ValidationException(ErrorFactory.CreateAndLogError(Errors.SRVEX30016, GetMethodName(), additionalDescriptionParameters: new object[]{ modifyBookingDto.RoomId}));
            }

            //Necessary Guest fields
            booking.Guest.Surname = modifyBookingDto.Guest.Surname;
            booking.Guest.IsConfirmationEmailToBeSent = modifyBookingDto.Guest.SendConfirmation;

            //Optional Guest Fields
            booking.Guest.TitleId = modifyBookingDto.Guest.Title; //Null is an acceptable Title Id value
            if (modifyBookingDto.Guest.Forename != null)
            {
                booking.Guest.Forename = modifyBookingDto.Guest.Forename;
            }
            if (modifyBookingDto.Guest.PhoneNumber != null)
            {
                booking.Guest.GuestPhones.RemoveAll(x => x.PhoneTypeCode == PhoneTypeEnum.Contact1);
                booking.Guest.GuestPhones.Add(new GuestPhone
                {
                    Number = modifyBookingDto.Guest.PhoneNumber,
                    PhoneTypeCode = PhoneTypeEnum.Contact1
                });
            }
            if (modifyBookingDto.Guest.Email != null)
            {
                booking.Guest.Email = modifyBookingDto.Guest.Email;
            }

            //If cost has been manually overriden from the UI (non OTA) or booking is OTA and RoomType or RatePlan is different (which uses previous booking price)
            if (modifyBookingDto.IsCostOverridden || booking.Order.IsOTA && (booking.RatePlanId != modifyBookingDto.RatePlanId || booking.RoomTypeId != room.RoomTypeId))
            {
                booking.RateType.Code = Model.Pricing.RateType.MANUAL;
            }
            booking.StartDate = modifyBookingDto.StartDate.Date;
            booking.EndDate = modifyBookingDto.EndDate.Date;
            booking.RoomId = modifyBookingDto.RoomId;
            booking.RatePlanId = modifyBookingDto.RatePlanId;
            booking.Cost = modifyBookingDto.Cost;
            booking.NumberOfAdults = modifyBookingDto.NumberOfAdults;
            booking.NumberOfChildren = modifyBookingDto.NumberOfChildren;
            booking.RoomTypeId = room.RoomTypeId;
            booking.EstimatedTimeOfArrival = booking.StartDate.Add(modifyBookingDto.EstimatedTimeOfArrival);
        }
Example #3
0
        /// <summary>
        /// Static method to the cancellation info for a booking
        /// </summary>
        private static BookingCancellationInfoDto MapCancellationInfo(Booking booking)
        {
            var cancellationCharge = booking.CancellationDetails.CancellationCharge;

            // retrieve the cancellation charge value
            if (!cancellationCharge.HasValue)
            {
                cancellationCharge = default(decimal);
            }

            // calculate the refundable amount
            var refundableAmount = booking.AmountPaid.Value - cancellationCharge;

            if (refundableAmount < default(decimal))
            {
                refundableAmount = default(decimal);
            }

            string sourceType = null;

            // set the relevant source for the cancellation info
            if (booking.Order.IntegrationType.HasValue && booking.Order.IntegrationType.Value == IntegrationTypeEnum.Myweb)
            {
                sourceType = booking.SourceName;
            }
            else if (booking.Order.OrderSourceCode == SourceType.Online.GetCode())
            {
                sourceType = booking.Order.Channel.Name;
            }

            if (string.IsNullOrEmpty(sourceType))
            {
                sourceType = booking.Order.OrderSourceName;
            }

            var showNoShow = false;
            var showCancel = false;
            var showDeclined = false;
            var checkInPlus = booking.StartDate <= DateTime.UtcNow.Date;
            var paymentOutstanding = (booking.Order.AmountPaid < booking.Order.TotalValue);

            // If booking can be cancelled then set relevant flags
            if (booking.CanCancel)
            {
                // always true if CanCancel
                showCancel = true;

                // Offline bookings
                if (booking.Order.OrderSourceCode == SourceType.Pms.GetCode())
                {
                    if (checkInPlus)
                    {
                        showNoShow = true;
                    }
                    if (paymentOutstanding)
                    {
                        showDeclined = true;
                    }
                }
                else
                {
                    // Online bookings
                    switch (booking.BookingScenarioType)
                    {
                        case BookingScenarioTypeEnum.DepositFirstNight:
                        case BookingScenarioTypeEnum.DepositVariable:
                            {
                                if (checkInPlus)
                                {
                                    showNoShow = true;

                                    if (paymentOutstanding)
                                    {
                                        showDeclined = true;
                                    }
                                }
                                break;
                            }                        
                        case BookingScenarioTypeEnum.Prepaid:
                        case BookingScenarioTypeEnum.OnAccountBooking:
                        case BookingScenarioTypeEnum.VPayment:
                            {
                                if (checkInPlus)
                                {
                                    showNoShow = true;
                                }
                                break;
                            }
                        case BookingScenarioTypeEnum.DistributorDeposit:
                        case BookingScenarioTypeEnum.PayOnArrival:
                            {
                                if (checkInPlus)
                                {
                                    showNoShow = true;
                                }

                                if (paymentOutstanding)
                                {
                                    showDeclined = true;
                                }
                                break;
                            }
                    }
                }
            }

            return new BookingCancellationInfoDto
            {
                CancellationCharge = cancellationCharge.Value,
                DisplayCancellationCharge = string.Format("{0}{1}", booking.Order.CurrencySymbol, cancellationCharge.Value.ToString(FINANCIAL_FORMATTING)),
                RefundablePayment = refundableAmount.Value,
                DisplayRefundablePayment = string.Format("{0}{1}", booking.Order.CurrencySymbol, refundableAmount.Value.ToString(FINANCIAL_FORMATTING)),
                ShowReasonCancelled = showCancel,
                ShowReasonCardDeclined = showDeclined,
                ShowReasonNoShow = showNoShow,
                SourceInfo = sourceType
            };
        }
Example #4
0
            public void CreateBookingWrongBusinessIdThrowsAccessDeniedException()
            {
                var bookingToReturn = new Booking
                {
                    Id = int.Parse(BOOKING_ID),
                    BusinessId = BUSINESS_ID_INVALID,
                    Cost = 100,
                    AmountPaid = 0,
                    BookingStatus = new EnumEntity
                    {
                        Code = BookingStatusType.CONFIRMED
                    },
                    CheckinStatus = new EnumEntity
                    {
                        Code = CheckinStatusOptions.CHECKEDIN
                    },
                    CancellationDetails = new CancellationDetail()
                };

                bookingManager.Setup(x => x.GetByKey(It.Is<int>(y => y == int.Parse(BOOKING_ID)), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<bool>())).Returns(bookingToReturn);

                try
                {
                    pmsMobile.GetBooking(BOOKING_ID);

                    Assert.Fail("User should not be permitted to submit a booking to a different business");
                }
                catch (AccessDeniedException aex)
                {
                    Assert.AreEqual("SRVEX30000", aex.Code, "Incorrect error code in AccessDeniedException");
                }
            }
Example #5
0
            public void GetBookingSuccessReturnsBooking()
            {
                var bookingToReturn = new Booking
                                          {
                                              Id = int.Parse(BOOKING_ID),
                                              OrderId = 5,
                                              BusinessId = BUSINESS_ID,
                                              Cost = 100,
                                              AmountPaid = 0,
                                              BookingStatus = new EnumEntity
                                                                  {
                                                                      Code = BookingStatusType.CONFIRMED
                                                                  },
                                              CheckinStatus = new EnumEntity
                                                                  {
                                                                      Code = CheckinStatusOptions.CHECKEDIN
                                                                  },
                                              Order = new Model.Order.Order
                                              {
                                                  Id = 5,
                                                  OrderSourceCode = SourceType.Pms.GetCode()
                                              },
                                              
                                              CancellationDetails = new CancellationDetail()
                                          };

                bookingManager.Setup(x => x.GetByKey(It.Is<int>(y => y == int.Parse(BOOKING_ID)), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<bool>())).Returns(bookingToReturn);
                bookingManager.Setup(x => x.GetBookingFees(It.Is<int>(y => y == bookingToReturn.OrderId), It.IsAny<string>())).Returns(new List<BookingFee>());
                
                var booking = pmsMobile.GetBooking(BOOKING_ID);

                Assert.IsNotNull(booking, "Booking object is NULL");
            }
Example #6
0
            public void CancelValidBookingRefundFailsReturnsWithMessage()
            {
                // Arrange
                var operationContextManager = MockRepository.GenerateMock<IOperationContextManager>();
                operationContextManager.Expect(o => o.GetIncomingMessageProperty(Arg<string>.Is.Equal(PRIMARY_BUSINESS_ID))).Return(BUSINESS_ID);

                var userManager = MockRepository.GenerateMock<IUserManager>();
                userManager.Expect(u => u.GetByUserName(Arg<string>.Is.Equal(TEST_USER_NAME))).Return(new User { Extension = new UserExtension { PrimaryBusinessId = BUSINESS_ID, CultureCode = CULTURE_CODE }, UserName = TEST_USER_NAME });

                pmsMobile.OperationContextManager = operationContextManager;
                pmsMobile.UserManager = userManager;                

                var cancelBookingDto = new
                {
                    CancellationCharge = 100,
                    IsCancellationChargeOverridden = false,
                    CancellationReason = "N",
                    Notes = "Cancel Notes",
                    SendConfirmation = false
                };

                var bookingId = Convert.ToInt32(BOOKING_ID);

                var startDate = DateTime.UtcNow;
                var endDate = DateTime.UtcNow.AddDays(1);

                var existingBooking = new Booking
                {
                    Id = bookingId,
                    BusinessId = BUSINESS_ID,
                    BookingScenarioType = BookingScenarioTypeEnum.OnAccountBooking,
                    BookingStatus = new EnumEntity { Code = BookingStatusType.CANCELLED },
                    Guest = new Guest
                    {
                        Id = 1,
                        Email = "*****@*****.**",
                        Surname = "Test"
                    },
                    RoomId = 1,
                    RoomTypeId = 1,
                    RatePlanId = 1,
                    Cost = new decimal(10),
                    StartDate = startDate,
                    EndDate = endDate,
                    NumberOfAdults = 1,
                    CancellationDetails = new CancellationDetail { CancellationType = CancellationTypeEnum.NonRefundable }
                };

                var bookingManager = MockRepository.GenerateMock<IBookingManager>();
                bookingManager.Stub(b => b.GetByKey(bookingId)).Return(existingBooking);
                int? refundId;
                bool? isRefundSuccessful;
                bool? isRefundAttempted;
                bookingManager.Expect(c => c.CancelBooking(existingBooking, out refundId, out isRefundSuccessful, out isRefundAttempted)).OutRef(null, false);
                pmsMobile.BookingManager = bookingManager;

                // Stub the BusinessCache to be used by our service method
                CacheHelper.StubBusinessCacheSingleBusiness(BUSINESS_ID);

                // invalidate the cache so we make sure our business is loaded into the cache
                Cache.Business.Invalidate();

                // Act
                try
                {
                    var result = pmsMobile.CancelBooking(BOOKING_ID, cancelBookingDto.CancellationCharge, cancelBookingDto.IsCancellationChargeOverridden, cancelBookingDto.CancellationReason, cancelBookingDto.SendConfirmation, cancelBookingDto.Notes);

                    Assert.AreEqual("Cancellation was successful but refund failed.", result.Message, "The message returned was not the expected message");

                    operationContextManager.VerifyAllExpectations();
                    bookingManager.VerifyAllExpectations();
                    userManager.VerifyAllExpectations();
                }
                catch (Exception)
                {
                    // Assert
                    Assert.Fail("A Failed refund should throw no exceptions");
                }
                finally
                {
                    // Reassign the Dao on the cache to discard the stub assigned on the StubBusinessCacheSingleBusiness method
                    CacheHelper.ReAssignBusinessDaoToBusinessCache();
                }
            }
Example #7
0
            public void CancelBookingForDifferentBusinessThrowsValidationException()
            {
                // Arrange
                const long INVALID_BUSINESS_ID = 5;

                var operationContextManager = MockRepository.GenerateMock<IOperationContextManager>();
                operationContextManager.Expect(o => o.GetIncomingMessageProperty(Arg<string>.Is.Equal(PRIMARY_BUSINESS_ID))).Return(BUSINESS_ID);

                var userManager = MockRepository.GenerateMock<IUserManager>();
                userManager.Expect(u => u.GetByUserName(Arg<string>.Is.Equal(TEST_USER_NAME))).Return(new User { Extension = new UserExtension { PrimaryBusinessId = BUSINESS_ID, CultureCode = CULTURE_CODE }, UserName = TEST_USER_NAME });

                var cancelBookingDto = new
                {
                    CancellationCharge = 100,
                    IsCancellationChargeOverridden = false,
                    CancellationReason = "NS",
                    Notes = "Cancel Notes",
                    SendConfirmation = false
                };

                var bookingId = Convert.ToInt32(BOOKING_ID);
                var startDate = DateTime.UtcNow;
                var endDate = DateTime.UtcNow.AddDays(1);

                var existingBooking = new Booking
                {
                    Id = bookingId,
                    BusinessId = INVALID_BUSINESS_ID,
                    BookingScenarioType = BookingScenarioTypeEnum.OnAccountBooking,
                    BookingStatus = new EnumEntity { Code = BookingStatusType.CANCELLED },
                    Guest = new Guest
                    {
                        Id = 1,
                        Email = "*****@*****.**",
                        Surname = "Test"
                    },
                    RoomId = 1,
                    RoomTypeId = 1,
                    RatePlanId = 1,
                    Cost = new decimal(10),
                    StartDate = startDate,
                    EndDate = endDate,
                    NumberOfAdults = 1,
                    CancellationDetails = new CancellationDetail { CancellationType = CancellationTypeEnum.NonRefundable }
                };

                var bookingManager = MockRepository.GenerateMock<IBookingManager>();
                bookingManager.Stub(b => b.GetByKey(bookingId)).Return(existingBooking);

                pmsMobile.OperationContextManager = operationContextManager;
                pmsMobile.UserManager = userManager; 
                pmsMobile.BookingManager = bookingManager;

                try
                {
                    // Act
                    pmsMobile.CancelBooking(BOOKING_ID, cancelBookingDto.CancellationCharge, cancelBookingDto.IsCancellationChargeOverridden, cancelBookingDto.CancellationReason, cancelBookingDto.SendConfirmation, cancelBookingDto.Notes);

                    // Assert
                    Assert.Fail("An exception SRVEX30000 of type ValidationException should have been thrown");
                }
                catch (AccessDeniedException ex)
                {
                    // Assert
                    Assert.AreEqual("SRVEX30000", ex.Code, "The access denied exception is not returning the right error code");

                    operationContextManager.VerifyAllExpectations();
                    bookingManager.VerifyAllExpectations();
                    userManager.VerifyAllExpectations();
                }
            }