public async Task TestPriceEpisodeIdentifierPickedFromHistoryForRefunds2(ApprenticeshipEmployerType employerType, OnProgrammeEarning earning, PaymentHistoryEntity previousPayment) { // arrange var period = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 3); var deliveryPeriod = (byte)2; var earningEvent = new ApprenticeshipContractType2EarningEvent { Ukprn = 1, CollectionPeriod = period, CollectionYear = period.AcademicYear, Learner = EarningEventDataHelper.CreateLearner(), LearningAim = EarningEventDataHelper.CreateLearningAim(), OnProgrammeEarnings = new List <OnProgrammeEarning>() { earning, } }; earning.Periods[0].ApprenticeshipEmployerType = previousPayment.ApprenticeshipEmployerType = employerType; earning.Type = OnProgrammeEarningType.Balancing; earning.Periods = earning.Periods.Take(1).ToList().AsReadOnly(); earning.Periods[0].Period = deliveryPeriod; earning.Periods[0].Amount = previousPayment.Amount - 1; var requiredPayments = new List <RequiredPayment> { new RequiredPayment { Amount = -1, EarningType = EarningType.CoInvested, ApprenticeshipEmployerType = employerType, ApprenticeshipId = previousPayment.ApprenticeshipId, ApprenticeshipPriceEpisodeId = previousPayment.ApprenticeshipPriceEpisodeId, }, }; previousPayment.LearnAimReference = earningEvent.LearningAim.Reference; previousPayment.DeliveryPeriod = deliveryPeriod; previousPayment.TransactionType = (int)earning.Type; var paymentHistory = ConditionalValue.WithArray(previousPayment); paymentHistoryCacheMock .Setup(c => c.TryGet(It.Is <string>(key => key == CacheKeys.PaymentHistoryKey), It.IsAny <CancellationToken>())) .ReturnsAsync(paymentHistory); requiredPaymentService .Setup(p => p.GetRequiredPayments(It.IsAny <Earning>(), It.IsAny <List <Payment> >())) .Returns(requiredPayments); // act var actualRequiredPayment = await act2EarningEventProcessor.HandleEarningEvent(earningEvent, paymentHistoryCacheMock.Object, CancellationToken.None); // assert actualRequiredPayment.Should().BeEquivalentTo( new { previousPayment.ApprenticeshipEmployerType, previousPayment.ApprenticeshipId, previousPayment.ApprenticeshipPriceEpisodeId, }); }
public async Task TestHandleNormalEvent() { // arrange var period = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2); byte deliveryPeriod = 2; var earningEvent = new ApprenticeshipContractType2EarningEvent { Ukprn = 1, CollectionPeriod = period, CollectionYear = period.AcademicYear, Learner = EarningEventDataHelper.CreateLearner(), LearningAim = EarningEventDataHelper.CreateLearningAim(), OnProgrammeEarnings = new List <OnProgrammeEarning>() { new OnProgrammeEarning { Type = OnProgrammeEarningType.Learning, Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod>() { new EarningPeriod { Amount = 100, Period = deliveryPeriod, PriceEpisodeIdentifier = "2", SfaContributionPercentage = 0.9m, } }) } } }; var requiredPayments = new List <RequiredPayment> { new RequiredPayment { Amount = 1, EarningType = EarningType.CoInvested, }, }; var paymentHistoryEntities = new[] { new PaymentHistoryEntity { CollectionPeriod = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2), DeliveryPeriod = 2, LearnAimReference = earningEvent.LearningAim.Reference, TransactionType = (int)OnProgrammeEarningType.Learning } }; var paymentHistory = new ConditionalValue <PaymentHistoryEntity[]>(true, paymentHistoryEntities); paymentHistoryCacheMock.Setup(c => c.TryGet(It.Is <string>(key => key == CacheKeys.PaymentHistoryKey), It.IsAny <CancellationToken>())).ReturnsAsync(paymentHistory).Verifiable(); requiredPaymentService .Setup(p => p.GetRequiredPayments(It.Is <Earning>(x => x.Amount == 100), It.Is <List <Payment> >(x => x.Count == 1))) .Returns(requiredPayments) .Verifiable(); // act var actualRequiredPayment = await act2EarningEventProcessor.HandleEarningEvent(earningEvent, paymentHistoryCacheMock.Object, CancellationToken.None); // assert Assert.IsNotNull(actualRequiredPayment); Assert.AreEqual(1, actualRequiredPayment.Count); Assert.AreEqual(1, actualRequiredPayment.First().AmountDue); Assert.AreEqual(earningEvent.LearningAim.Reference, actualRequiredPayment.First().LearningAim.Reference); }
public async Task TestNormalEvent() { // arrange var period = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2); var earningEvent = new PayableEarningEvent { Ukprn = 1, CollectionPeriod = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2), CollectionYear = period.AcademicYear, Learner = EarningEventDataHelper.CreateLearner(), LearningAim = EarningEventDataHelper.CreateLearningAim(), OnProgrammeEarnings = new List <OnProgrammeEarning>() { new OnProgrammeEarning { Type = OnProgrammeEarningType.Learning, Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod>() { new EarningPeriod { Amount = 100, Period = period.Period, PriceEpisodeIdentifier = "2", SfaContributionPercentage = 0.9m, }, new EarningPeriod { Amount = 200, Period = (byte)(period.Period + 1), PriceEpisodeIdentifier = "2", SfaContributionPercentage = 0.9m, } }) } } }; var requiredPayments = new List <RequiredPayment> { new RequiredPayment { Amount = 100, EarningType = EarningType.Levy, }, }; var paymentHistoryEntities = new[] { new PaymentHistoryEntity { CollectionPeriod = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2), DeliveryPeriod = 2, LearnAimReference = earningEvent.LearningAim.Reference, TransactionType = (int)OnProgrammeEarningType.Learning } }; paymentHistoryCacheMock.Setup(c => c.TryGet(It.Is <string>(key => key == CacheKeys.PaymentHistoryKey), It.IsAny <CancellationToken>())) .ReturnsAsync(new ConditionalValue <PaymentHistoryEntity[]>(true, paymentHistoryEntities)) .Verifiable(); requiredPaymentsService.Setup(p => p.GetRequiredPayments(It.IsAny <Earning>(), It.IsAny <List <Payment> >())) .Returns(requiredPayments) .Verifiable(); // act var actualRequiredPayment = await processor.HandleEarningEvent(earningEvent, paymentHistoryCacheMock.Object, CancellationToken.None); // assert actualRequiredPayment.Should().HaveCount(1); }
public async Task TestGeneratesValidRequiredEventFundingLineType() { // arrange var period = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2); var earningEvent = new PayableEarningEvent { Ukprn = 1, CollectionPeriod = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2), CollectionYear = period.AcademicYear, Learner = EarningEventDataHelper.CreateLearner(), LearningAim = EarningEventDataHelper.CreateLearningAim(), OnProgrammeEarnings = new List <OnProgrammeEarning>() { new OnProgrammeEarning { Type = OnProgrammeEarningType.Learning, Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod>() { new EarningPeriod { Amount = 100, Period = period.Period, PriceEpisodeIdentifier = "1", SfaContributionPercentage = 0.9m, }, new EarningPeriod { Amount = 200, Period = (byte)(period.Period + 1), PriceEpisodeIdentifier = "2", SfaContributionPercentage = 0.9m, } }) } }, PriceEpisodes = new List <PriceEpisode> { new PriceEpisode { Identifier = "1", EffectiveTotalNegotiatedPriceStartDate = DateTime.UtcNow, PlannedEndDate = DateTime.UtcNow, ActualEndDate = DateTime.UtcNow, CompletionAmount = 100M, InstalmentAmount = 200M, NumberOfInstalments = 16, FundingLineType = "19+ Apprenticeship Non-Levy Contract (procured)" } } }; var requiredPayments = new List <RequiredPayment> { new RequiredPayment { Amount = 100, EarningType = EarningType.Levy, }, }; var paymentHistoryEntities = new[] { new PaymentHistoryEntity { CollectionPeriod = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2), DeliveryPeriod = 2, LearnAimReference = earningEvent.LearningAim.Reference, TransactionType = (int)OnProgrammeEarningType.Learning } }; paymentHistoryCacheMock.Setup(c => c.TryGet(It.Is <string>(key => key == CacheKeys.PaymentHistoryKey), It.IsAny <CancellationToken>())) .ReturnsAsync(new ConditionalValue <PaymentHistoryEntity[]>(true, paymentHistoryEntities)) .Verifiable(); requiredPaymentsService.Setup(p => p.GetRequiredPayments(It.IsAny <Earning>(), It.IsAny <List <Payment> >())) .Returns(requiredPayments) .Verifiable(); // act var actualRequiredPayment = await processor.HandleEarningEvent(earningEvent, paymentHistoryCacheMock.Object, CancellationToken.None); // assert actualRequiredPayment.Should().HaveCount(1); actualRequiredPayment[0].LearningAim.Should().NotBeNull(); actualRequiredPayment[0].LearningAim.FundingLineType.Should().Be(earningEvent.PriceEpisodes[0].FundingLineType); }
public async Task TestHoldingBackCompletionPayment() { // arrange var period = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2); var priceEpisodes = new List <PriceEpisode>(new [] { new PriceEpisode { Identifier = "1", EmployerContribution = 100, CompletionHoldBackExemptionCode = 0 }, new PriceEpisode { Identifier = "2", EmployerContribution = 1, CompletionHoldBackExemptionCode = 2 } }); var earningEvent = new PayableEarningEvent { Ukprn = 1, CollectionPeriod = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2), CollectionYear = period.AcademicYear, Learner = EarningEventDataHelper.CreateLearner(), LearningAim = EarningEventDataHelper.CreateLearningAim(), PriceEpisodes = priceEpisodes, OnProgrammeEarnings = new List <OnProgrammeEarning> { new OnProgrammeEarning { Type = OnProgrammeEarningType.Completion, Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod> { new EarningPeriod { Amount = 200, Period = period.Period, PriceEpisodeIdentifier = "2", SfaContributionPercentage = 0.9m, } }) } } }; var requiredPayments = new List <RequiredPayment> { new RequiredPayment { Amount = 100, EarningType = EarningType.Levy, }, }; var paymentHistoryEntities = new[] { new PaymentHistoryEntity { CollectionPeriod = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2), DeliveryPeriod = 2, LearnAimReference = "ZPROG001" } }; var key = new ApprenticeshipKey(); paymentHistoryCacheMock.Setup(c => c.TryGet(It.Is <string>(k => k == CacheKeys.PaymentHistoryKey), It.IsAny <CancellationToken>())) .ReturnsAsync(new ConditionalValue <PaymentHistoryEntity[]>(true, paymentHistoryEntities)) .Verifiable(); requiredPaymentsService.Setup(p => p.GetRequiredPayments(It.IsAny <Earning>(), It.IsAny <List <Payment> >())).Returns(requiredPayments).Verifiable(); apprenticeshipKeyProviderMock.Setup(a => a.GetCurrentKey()).Returns(key).Verifiable(); paymentHistoryRepositoryMock.Setup(repo => repo.GetEmployerCoInvestedPaymentHistoryTotal(key, It.IsAny <CancellationToken>())).ReturnsAsync(11).Verifiable(); holdingBackCompletionPaymentServiceMock.Setup(h => h.ShouldHoldBackCompletionPayment(11, priceEpisodes[1])).Returns(true).Verifiable(); // act var actualRequiredPayment = await processor.HandleEarningEvent(earningEvent, paymentHistoryCacheMock.Object, CancellationToken.None); // assert actualRequiredPayment.Should().HaveCount(1); }
public async Task Matching_Historic_Aim_To_Current_Aim_Should_Be_Case_InSensitive_On_Aim_Reference() { // arrange var period = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2); var earningEvent = new PayableEarningEvent { Ukprn = 1, CollectionPeriod = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2), CollectionYear = period.AcademicYear, Learner = EarningEventDataHelper.CreateLearner(), LearningAim = EarningEventDataHelper.CreateLearningAim(), OnProgrammeEarnings = new List <OnProgrammeEarning>() { new OnProgrammeEarning { Type = OnProgrammeEarningType.Learning, Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod>() { new EarningPeriod { Amount = 100, Period = period.Period, PriceEpisodeIdentifier = "2", SfaContributionPercentage = 0.9m, } }) } } }; var requiredPayments = new List <RequiredPayment> { }; earningEvent.LearningAim.Reference = "ZPROG001"; var paymentHistoryEntities = new[] { new PaymentHistoryEntity { CollectionPeriod = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2), DeliveryPeriod = period.Period, LearnAimReference = earningEvent.LearningAim.Reference.ToLower(), TransactionType = (int)OnProgrammeEarningType.Learning, Amount = 100, SfaContributionPercentage = 0.9m, PriceEpisodeIdentifier = "2" } }; paymentHistoryCacheMock.Setup(c => c.TryGet(It.Is <string>(key => key == CacheKeys.PaymentHistoryKey), It.IsAny <CancellationToken>())) .ReturnsAsync(new ConditionalValue <PaymentHistoryEntity[]>(true, paymentHistoryEntities)) .Verifiable(); requiredPaymentsService.Setup(p => p.GetRequiredPayments(It.IsAny <Earning>(), It.IsAny <List <Payment> >())) .Returns(requiredPayments) .Verifiable(); // act var actualRequiredPayment = await processor.HandleEarningEvent(earningEvent, paymentHistoryCacheMock.Object, CancellationToken.None); // assert actualRequiredPayment.Should().HaveCount(0); //Ideally this logic should be moved into a specific testable class requiredPaymentsService.Verify(x => x.GetRequiredPayments(It.IsAny <Earning>(), It.Is <List <Payment> >(lst => lst.Count == 1 && lst.Any(p => p.LearnAimReference == "zprog001")))); }
public async Task IgnoresDuplicateEvents() { // arrange var period = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2); byte deliveryPeriod = 2; var earningEvent = new Act2FunctionalSkillEarningsEvent { Ukprn = 1, CollectionPeriod = period, CollectionYear = period.AcademicYear, Learner = EarningEventDataHelper.CreateLearner(), LearningAim = EarningEventDataHelper.CreateLearningAim(), Earnings = new ReadOnlyCollection <FunctionalSkillEarning>(new List <FunctionalSkillEarning> { new FunctionalSkillEarning { Type = FunctionalSkillType.BalancingMathsAndEnglish, Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod> { new EarningPeriod { Period = deliveryPeriod, Amount = 100, PriceEpisodeIdentifier = "2", SfaContributionPercentage = 0.9m, } }) } }) }; var requiredPayments = new List <RequiredPayment> { new RequiredPayment { Amount = 100, EarningType = EarningType.Incentive, SfaContributionPercentage = 0.9m, PriceEpisodeIdentifier = "2", }, }; var paymentHistoryEntities = new[] { new PaymentHistoryEntity { CollectionPeriod = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 2), DeliveryPeriod = 2, LearnAimReference = earningEvent.LearningAim.Reference, TransactionType = (int)FunctionalSkillType.BalancingMathsAndEnglish } }; paymentHistoryCacheMock.Setup(c => c.TryGet(It.Is <string>(key => key == CacheKeys.PaymentHistoryKey), It.IsAny <CancellationToken>())) .ReturnsAsync(new ConditionalValue <PaymentHistoryEntity[]>(true, paymentHistoryEntities)); requiredPaymentsService.Setup(p => p.GetRequiredPayments(It.Is <Earning>(x => x.Amount == 100), It.IsAny <List <Payment> >())) .Returns(requiredPayments); mocker.Mock <IDuplicateEarningEventService>() .Setup(x => x.IsDuplicate(It.IsAny <IPaymentsEvent>(), It.IsAny <CancellationToken>())) .ReturnsAsync(true); // act var actualRequiredPayment = await eventProcessor.HandleEarningEvent(earningEvent, paymentHistoryCacheMock.Object, CancellationToken.None); // assert Assert.IsNotNull(actualRequiredPayment); Assert.AreEqual(0, actualRequiredPayment.Count); }