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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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"))));
        }
Ejemplo n.º 7
0
        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);
        }