/// <summary> /// Check if a custom cancellation policy is valid compared to its cancellation terms /// </summary> /// <param name="cancelTerms">The cancellation terms to compare</param> /// <returns>True if policy is valid</returns> public bool IsCustomCancelValid(ChannelCancellationTerms cancelTerms) { if (cancelTerms == null || CancellationValues == null) { return false; } // Valid if all values are null (for when using property default) if ((CancellationValues.CancellationChargeType != null && CancellationValues.CancellationChargeType.Code == null) && (CancellationValues.CancellationType != null && CancellationValues.CancellationType.Code == null) && CancellationValues.CancellationChargeValue == null && CancellationValues.CancellationWindowHours == null) { return true; } return (// window checks (CancellationValues.CancellationWindowHours.HasValue == false || (cancelTerms.WindowMinValue.HasValue == false || CancellationValues.CancellationWindowHours >= cancelTerms.WindowMinValue.Value) && (cancelTerms.WindowMaxValue.HasValue == false || CancellationValues.CancellationWindowHours <= cancelTerms.WindowMaxValue.Value)) && (CancellationValues.CancellationChargeValue.HasValue == false || // fixed charge checks (CancellationValues.CancellationChargeType != CancellationChargeTypeEnum.Fixed || (cancelTerms.MinChargeValue.HasValue == false || CancellationValues.CancellationChargeValue.Value >= cancelTerms.MinChargeValue.Value) && (cancelTerms.MaxChargeValue.HasValue == false || CancellationValues.CancellationChargeValue.Value <= cancelTerms.MaxChargeValue.Value) && (cancelTerms.ChargeValueMultiple.HasValue == false || CancellationValues.CancellationChargeValue.Value%cancelTerms.ChargeValueMultiple.Value == 0)) && // percentage checks (CancellationValues.CancellationChargeType != CancellationChargeTypeEnum.Percentage || (cancelTerms.MinChargePercentage.HasValue == false || CancellationValues.CancellationChargeValue.Value >= cancelTerms.MinChargePercentage.Value) && (cancelTerms.MaxChargePercentage.HasValue == false || CancellationValues.CancellationChargeValue.Value <= cancelTerms.MaxChargePercentage.Value) && (cancelTerms.ChargePercentageMultiple.HasValue == false || CancellationValues.CancellationChargeValue.Value%cancelTerms.ChargePercentageMultiple.Value == 0))) && // type checks (cancelTerms.AcceptedChargeTypes == null || CancellationValues.CancellationChargeType == null || CancellationValues.CancellationChargeType.Code == null || cancelTerms.AcceptedChargeTypes.Contains(CancellationValues.CancellationChargeType))); }
/// <summary> /// update cancellation information for an opted in channel /// </summary> /// <param name="channelTerms">channel cancel terms to use</param> /// <param name="channelUpdateInfo">data to change</param> public bool UpdateCancellationForOptedInChannel(BusinessChannelOptIn channelUpdateInfo, ChannelCancellationTerms channelTerms = null) { var result = false; if (channelUpdateInfo.IsValid() && channelUpdateInfo.CancellationValues != null) { // verify they can edit cancellation details Channel currentChannel = channelDao.GetById(channelUpdateInfo.ChannelId.Value); if (currentChannel == null) { //throw error if we cannot find the channel throw new ValidationException(ErrorFactory.CreateAndLogError(Errors.SRVEX30130, "DistributionManager.UpdateCancellationForOptedInChannel", additionalDescriptionParameters: new object[] { channelUpdateInfo.ChannelId .Value }, arguments: new object[] { channelUpdateInfo })); } if (currentChannel.SupportsCustomCancPolicy == false) { //throw error if we don't support custom cancel throw new ValidationException(ErrorFactory.CreateAndLogError(Errors.SRVEX30131, "DistributionManager.UpdateCancellationForOptedInChannel", additionalDescriptionParameters: new object[] { currentChannel.ShortName }, arguments: new object[] { currentChannel.ShortName })); } // get restrictions for editing here List<ChannelCancellationTerms> ListOfChannelTerms = null; if (channelTerms == null) { ListOfChannelTerms = channelCancellationTermsDao.GetByBusiness(channelUpdateInfo.BusinessId.Value); channelTerms = ListOfChannelTerms.FirstOrDefault(ct => ct.ChannelId == currentChannel.Id); } //channel terms would be null if the business is not subscribed to the channel if (channelTerms != null) { // set the terms to the channels currentChannel.ChannelCancellationTerms = channelTerms; if (channelUpdateInfo.IsCustomCancelValid(currentChannel.ChannelCancellationTerms) == false) { throw new ValidationException(ErrorFactory.CreateAndLogError(Errors.SRVEX30132, "DistributionManager.UpdateCancellationForOptedInChannel", additionalDescriptionParameters: new object[] { currentChannel.ShortName }, arguments: new object[] { currentChannel.ShortName })); } } using (var tx = new BusinessTransaction()) { result = businessChannelOptInDao.UpdateCancellation(channelUpdateInfo); // Record business event eventTrackingManager.CreateBusinessEventAsync(channelUpdateInfo.BusinessId.Value, BusinessEventTypesEnum.OptinChannelModified, channelUpdateInfo.ChannelId.ToString()); tx.Commit(); } // if not a channel (so a group) update the related channels if (currentChannel.ChannelType != ChannelTypeEnum.Channel) { // update the opted in related channels with this info as well List<int> channelIds = businessChannelOptInDao.GetOptedInChannelsRelatedToGroup(channelUpdateInfo.BusinessId.Value, currentChannel.Id); if (channelIds != null && channelIds.Any()) { foreach (int channelId in channelIds) { channelUpdateInfo.ChannelId = channelId; UpdateCancellationForOptedInChannel(channelUpdateInfo, channelTerms); // update the sub-channel } } } } return result; }
public void UpdateCancellationForOptedInChannelInvalidTermsUpdateThrowsValidationException(TestData testData) { // Arrange const int CHANNEL_ID = 1; const long BUSINESS_ID = 1; const int CHANNEL_TERMS_ID = 1; var channelDao = new Mock<IChannelDao>(); var channelTermsDao = new Mock<IChannelCancellationTermsDao>(); var distributionManager = new DistributionManager { ChannelDao = channelDao.Object, ChannelCancellationTermsDao = channelTermsDao.Object }; channelDao.Setup(c => c.GetById(It.Is<int>(i => i == CHANNEL_ID))).Returns(new Channel { Id = CHANNEL_ID, SupportsCustomCancPolicy = true }); var businessChannelOptIn = new BusinessChannelOptIn { ChannelId = CHANNEL_ID, BusinessId = BUSINESS_ID, ChannelTermsId = CHANNEL_TERMS_ID, CancellationValues = new CancellationValues { CancellationChargeType = new CancellationChargeType { Type = testData.chargeTypeToUse }, CancellationWindowHours = testData.windowHoursToUse, CancellationChargeValue = testData.chargeValueToUse } }; // set up terms here var channelTerms = new ChannelCancellationTerms { ChannelId = CHANNEL_ID, AcceptedChargeTypes = new List<CancellationChargeTypeEnum> { testData.acceptableChargeType }, MinChargeValue = testData.minChargeValue, MaxChargeValue = testData.maxChargeValue, ChargeValueMultiple = testData.chargeMultiple, MinChargePercentage = testData.minPercentValue, MaxChargePercentage = testData.maxPercentValue, ChargePercentageMultiple = testData.percentMultiple, WindowMinValue = testData.windowMinValue, WindowMaxValue = testData.windowMaxValue }; channelTermsDao.Setup(ct => ct.GetByBusiness(It.IsAny<long>())).Returns(new List<ChannelCancellationTerms> {channelTerms}); // Act try { distributionManager.UpdateCancellationForOptedInChannel(businessChannelOptIn); Assert.Fail("Validation exception SRVEX30132 was not thrown"); } catch (ValidationException ex) { Assert.AreEqual("SRVEX30132", ex.Code, "SRVEX30132 was not thrown"); channelDao.VerifyAll(); channelTermsDao.VerifyAll(); } }