public async Task TestSfaContributionIsCalculatedForZeroEarningRefunds()
        {
            // arrange
            var  period         = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 3);
            byte deliveryPeriod = 2;

            var earningEvent = new ApprenticeshipContractType2EarningEvent
            {
                Ukprn = 1,
                SfaContributionPercentage = 0,
                CollectionPeriod          = period,
                CollectionYear            = period.AcademicYear,
                Learner             = EarningEventDataHelper.CreateLearner(),
                LearningAim         = EarningEventDataHelper.CreateLearningAim(),
                OnProgrammeEarnings = new List <OnProgrammeEarning>
                {
                    new OnProgrammeEarning
                    {
                        Type    = OnProgrammeEarningType.Balancing,
                        Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod>
                        {
                            new EarningPeriod
                            {
                                Period = deliveryPeriod,
                                Amount = 0,
                                PriceEpisodeIdentifier    = "priceEpisodeIdentifier",
                                SfaContributionPercentage = 0
                            }
                        })
                    }
                }
            };

            var requiredPayments = new List <RequiredPayment>
            {
                new RequiredPayment
                {
                    Amount      = 1,
                    EarningType = EarningType.CoInvested,
                    SfaContributionPercentage = 0.77m,
                },
            };

            var paymentHistoryEntities = new List <PaymentHistoryEntity>();
            var paymentHistory         = new ConditionalValue <PaymentHistoryEntity[]>(true, paymentHistoryEntities.ToArray());

            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 == 0), It.Is <List <Payment> >(x => x.Count == 0)))
            .Returns(requiredPayments)
            .Verifiable();

            // act
            var actualRequiredPayment = await act2EarningEventProcessor.HandleEarningEvent(earningEvent, paymentHistoryCacheMock.Object, CancellationToken.None);

            // assert
            Assert.IsNotEmpty(actualRequiredPayment);
            Assert.AreEqual(.77m, ((CalculatedRequiredCoInvestedAmount)actualRequiredPayment[0]).SfaContributionPercentage);
        }
        public async Task TestPriceEpisodeIdentifierPickedFromHistoryForRefunds(decimal amount, string priceEpisodeIdentifier)
        {
            // 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>()
                {
                    new OnProgrammeEarning
                    {
                        Type    = OnProgrammeEarningType.Balancing,
                        Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod>()
                        {
                            new EarningPeriod
                            {
                                Amount = amount,
                                Period = deliveryPeriod,
                                PriceEpisodeIdentifier    = priceEpisodeIdentifier,
                                SfaContributionPercentage = 0.9m,
                            }
                        })
                    }
                }
            };

            var paymentHistoryEntities = new PaymentHistoryEntity[0];
            var requiredPayments       = new List <RequiredPayment>
            {
                new RequiredPayment
                {
                    Amount      = 1,
                    EarningType = EarningType.CoInvested,
                    SfaContributionPercentage = 0.8m,
                    PriceEpisodeIdentifier    = "2",
                },
            };
            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 == amount), It.Is <List <Payment> >(x => x.Count == 0)))
            .Returns(requiredPayments)
            .Verifiable();

            // act
            var actualRequiredPayment = await act2EarningEventProcessor.HandleEarningEvent(earningEvent, paymentHistoryCacheMock.Object, CancellationToken.None);

            // assert
            Assert.IsNotNull(actualRequiredPayment);
            Assert.AreEqual("2", actualRequiredPayment.First().PriceEpisodeIdentifier);
        }
        public void ContractTypeIsCorrectForNotLevyEvent(Type requiredPaymentEventType)
        {
            var requiredPaymentEvent = Activator.CreateInstance(requiredPaymentEventType) as PeriodisedRequiredPaymentEvent;
            var earningEvent         = new ApprenticeshipContractType2EarningEvent {
                PriceEpisodes = new List <PriceEpisode>(), LearningAim = new LearningAim()
            };

            var actual = mapper.Map(earningEvent, requiredPaymentEvent);

            actual.ContractType.Should().Be(ContractType.Act2);
        }
        public void CreateRedundancyContractType_ForAct2ContractType_ShouldCreateANewEventId()
        {
            var factory      = new RedundancyEarningEventFactory(Mapper.Instance);
            var earningEvent = new ApprenticeshipContractType2EarningEvent {
                EventId = Guid.NewGuid()
            };

            var createdEvent = factory.CreateRedundancyContractTypeEarningsEvent(earningEvent);

            earningEvent.EventId.Should().NotBe(createdEvent.EventId);
            createdEvent.EventId.Should().NotBe(Guid.Empty);
        }
Ejemplo n.º 5
0
        public async Task TestHandleZeroEvent()
        {
            // 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.Completion,
                        Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod>()
                        {
                            new EarningPeriod
                            {
                                Amount = 0,
                                Period = deliveryPeriod,
                                PriceEpisodeIdentifier    = null,
                                SfaContributionPercentage = 0m,
                            }
                        })
                    }
                }
            };

            var requiredPayments = new List <RequiredPayment>();

            var paymentHistoryEntities = new PaymentHistoryEntity[0];

            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 == 0), It.Is <List <Payment> >(x => x.Count == 0)))
            .Returns(requiredPayments)
            .Verifiable();

            // act
            var actualRequiredPayment = await act2EarningEventProcessor.HandleEarningEvent(earningEvent, paymentHistoryCacheMock.Object, CancellationToken.None);

            // assert
            Assert.IsNotNull(actualRequiredPayment);
            actualRequiredPayment.Should().BeEmpty();
        }
Ejemplo n.º 6
0
        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,
                            }
                        })
                    }
                },
                PriceEpisodes = new List <PriceEpisode>
                {
                    new PriceEpisode
                    {
                        LearningAimSequenceNumber = 2,
                        Identifier = "2"
                    }
                }
            };

            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);
            Assert.AreEqual(2, actualRequiredPayment.First().LearningAimSequenceNumber);
        }
Ejemplo n.º 7
0
        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,
                },
                PriceEpisodes = new List <PriceEpisode>
                {
                    new PriceEpisode
                    {
                        LearningAimSequenceNumber = 1234
                    }
                }
            };

            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,
            });
        }
Ejemplo n.º 8
0
        public async Task <ReadOnlyCollection <PeriodisedRequiredPaymentEvent> > HandleApprenticeship2ContractTypeEarningsEvent(ApprenticeshipContractType2EarningEvent earningEvent, CancellationToken cancellationToken)
        {
            paymentLogger.LogVerbose($"Handling ApprenticeshipContractType2EarningEvent for jobId:{earningEvent.JobId} with apprenticeship key based on {logSafeApprenticeshipKeyString}");

            using (var operation = telemetry.StartOperation("RequiredPaymentsService.HandleApprenticeship2ContractTypeEarningsEvent", earningEvent.EventId.ToString()))
            {
                var stopwatch = Stopwatch.StartNew();
                await ResetPaymentHistoryCacheIfDifferentCollectionPeriod(earningEvent.CollectionPeriod)
                .ConfigureAwait(false);

                await Initialise(earningEvent.CollectionPeriod.Period).ConfigureAwait(false);

                var requiredPaymentEvents = await contractType2EarningsEventProcessor.HandleEarningEvent(earningEvent, paymentHistoryCache, cancellationToken).ConfigureAwait(false);

                Log(requiredPaymentEvents);
                telemetry.TrackDuration("RequiredPaymentsService.HandleApprenticeship2ContractTypeEarningsEvent", stopwatch, earningEvent);
                telemetry.StopOperation(operation);
                return(requiredPaymentEvents);
            }
        }