/// <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); }
/// <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); }
/// <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 }; }
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"); } }
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"); }
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(); } }
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(); } }