public async Task ChangeToSfaContributionShouldResultInPaymentAndRefund()
        {
            var earningEvent     = GeneratePayableDataLockEvent(1920, 2, 0m);
            var requiredPayments = new List <RequiredPayment>
            {
                new RequiredPayment
                {
                    Amount      = 100m,
                    EarningType = EarningType.Levy,
                    SfaContributionPercentage = 100,
                },
                new RequiredPayment
                {
                    Amount      = -100,
                    EarningType = EarningType.Levy,
                    SfaContributionPercentage = 95,
                }
            };

            var paymentHistoryEntities = new PaymentHistoryEntity[] {};

            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.IsAny <Earning>(), It.IsAny <List <Payment> >()))
            .Returns(requiredPayments);

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

            // assert
            actualRequiredPayment.Should().HaveCount(2);
            actualRequiredPayment.Sum(x => x.AmountDue).Should().Be(0);
        }
        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 ValidateMap()
        {
            var payment = new PaymentHistoryEntity
            {
                CollectionPeriod = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 11),
                DeliveryPeriod   = 10
            };

            mapper.Map <PaymentHistoryEntity, Payment>(payment);
        }
예제 #4
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();
        }
        public async Task TestNoEventProducedWhenZeroToPay()
        {
            // arrange
            var period = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 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.OnProgrammeMathsAndEnglish,
                        Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod>
                        {
                            new EarningPeriod
                            {
                                Period = 2,
                                Amount = 100,
                                PriceEpisodeIdentifier    = "2",
                                SfaContributionPercentage = 0.8m,
                            }
                        })
                    }
                })
            };

            var paymentHistoryEntities = new PaymentHistoryEntity[0];

            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.Is <Earning>(x => x.Amount == 100), It.IsAny <List <Payment> >()))
            .Returns(new List <RequiredPayment>())
            .Verifiable();

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

            // assert
            Assert.AreEqual(0, actualRequiredPayment.Count);
        }
        public void PaymentHistoryEntityMapsEarningsInfo()
        {
            var paymentHistoryEntity = new PaymentHistoryEntity
            {
                CollectionPeriod    = new CollectionPeriod(),
                StartDate           = DateTime.UtcNow,
                PlannedEndDate      = DateTime.UtcNow,
                ActualEndDate       = DateTime.UtcNow,
                CompletionAmount    = 100M,
                InstalmentAmount    = 200M,
                NumberOfInstalments = 16
            };

            var payment = mapper.Map <Payment>(paymentHistoryEntity);

            payment.StartDate.Should().Be(paymentHistoryEntity.StartDate);
            payment.PlannedEndDate.Should().Be(paymentHistoryEntity.PlannedEndDate);
            payment.ActualEndDate.Should().Be(paymentHistoryEntity.ActualEndDate);
            payment.CompletionStatus.Should().Be(0);
            payment.CompletionAmount.Should().Be(paymentHistoryEntity.CompletionAmount);
            payment.InstalmentAmount.Should().Be(paymentHistoryEntity.InstalmentAmount);
            payment.NumberOfInstalments.Should().Be(paymentHistoryEntity.NumberOfInstalments);
        }
예제 #7
0
 public static void ShouldBeMappedTo(this PeriodisedRequiredPaymentEvent paymentEvent, PaymentHistoryEntity historicPayment)
 {
     paymentEvent.EarningEventId.Should().Be(Guid.Empty);
     paymentEvent.EventId.Should().NotBe(Guid.Empty);
     paymentEvent.AccountId.Should().Be(historicPayment.AccountId);
     paymentEvent.ApprenticeshipEmployerType.Should().Be(historicPayment.ApprenticeshipEmployerType);
     paymentEvent.EventId.Should().NotBe(historicPayment.ExternalId);
     paymentEvent.EventId.Should().NotBe(Guid.Empty);
     paymentEvent.ActualEndDate.Should().Be(historicPayment.ActualEndDate);
     paymentEvent.CompletionAmount.Should().Be(historicPayment.CompletionAmount);
     paymentEvent.ContractType.Should().Be(historicPayment.ContractType);
     paymentEvent.CompletionStatus.Should().Be(historicPayment.CompletionStatus);
     paymentEvent.DeliveryPeriod.Should().Be(historicPayment.DeliveryPeriod);
     paymentEvent.InstalmentAmount.Should().Be(historicPayment.InstalmentAmount);
     paymentEvent.ActualEndDate.Should().Be(historicPayment.ActualEndDate);
     paymentEvent.Learner.Uln.Should().Be(historicPayment.LearnerUln);
 }
예제 #8
0
        public async Task TestFuturePeriodsCutOff()
        {
            // arrange
            var period = CollectionPeriodFactory.CreateFromAcademicYearAndPeriod(1819, 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 = period.Period,
                                PriceEpisodeIdentifier    = "2",
                                SfaContributionPercentage = 0.9m,
                            },
                            new EarningPeriod
                            {
                                Amount = 200,
                                Period = (byte)(period.Period + 1),
                                PriceEpisodeIdentifier    = "2",
                                SfaContributionPercentage = 0.9m,
                            }
                        })
                    }
                },
                PriceEpisodes = new List <PriceEpisode>
                {
                    new PriceEpisode
                    {
                        LearningAimSequenceNumber = 1234
                    }
                }
            };

            var requiredPayments = new List <RequiredPayment>
            {
                new RequiredPayment
                {
                    Amount      = 100,
                    EarningType = EarningType.CoInvested,
                },
            };

            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 == 100), 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(1, actualRequiredPayment.Count);
            Assert.AreEqual(100, actualRequiredPayment.First().AmountDue);
            Assert.AreEqual(earningEvent.LearningAim.Reference, actualRequiredPayment.First().LearningAim.Reference);
        }
예제 #9
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,
            });
        }
        public void MapsPaymentHistoryEntity_ApprenticeshipEmployerType_ToPayment(PaymentHistoryEntity testPaymentHistoryEntity, Payment payment)
        {
            mapper.Map(testPaymentHistoryEntity, payment);

            payment.ApprenticeshipEmployerType.Should().Be(testPaymentHistoryEntity.ApprenticeshipEmployerType);
        }
        public void MapsPaymentHistoryEntity_ApprenticeshipPriceEpisodeId_ToPayment(PaymentHistoryEntity testPaymentHistoryEntity, Payment payment)
        {
            mapper.Map(testPaymentHistoryEntity, payment);

            payment.ApprenticeshipPriceEpisodeId.Should().Be(testPaymentHistoryEntity.ApprenticeshipPriceEpisodeId);
        }
        public void SetUp()
        {
            mocker = AutoMock.GetLoose();
            var config = new MapperConfiguration(cfg => cfg.AddProfile <RequiredPaymentsProfile>());

            config.AssertConfigurationIsValid();
            mapper = new Mapper(config);


            identifiedLearningAim = new IdentifiedRemovedLearningAim
            {
                CollectionPeriod = new CollectionPeriod
                {
                    AcademicYear = 1819,
                    Period       = 1
                },
                EventId               = Guid.NewGuid(),
                EventTime             = DateTimeOffset.UtcNow,
                IlrSubmissionDateTime = DateTime.Now,
                JobId   = 1,
                Learner = new Learner
                {
                    ReferenceNumber = "learner-ref-123",
                    Uln             = 2
                },
                LearningAim = new LearningAim
                {
                    FrameworkCode   = 3,
                    FundingLineType = "funding line type",
                    PathwayCode     = 4,
                    ProgrammeType   = 5,
                    Reference       = "learning-ref-456",
                    StandardCode    = 6
                },
                Ukprn = 7
            };

            historicPayment = new PaymentHistoryEntity
            {
                Amount = 10,
                SfaContributionPercentage = .9M,
                TransactionType           = (int)OnProgrammeEarningType.Learning,
                CollectionPeriod          = new CollectionPeriod
                {
                    AcademicYear = 1819,
                    Period       = 1
                },
                LearnAimReference      = "aim-ref-123",
                LearnerReferenceNumber = "learning-ref-456",
                PriceEpisodeIdentifier = "pe-1",
                DeliveryPeriod         = 1,
                Ukprn               = 7,
                ActualEndDate       = null,
                CompletionAmount    = 3000,
                CompletionStatus    = 1,
                ExternalId          = Guid.NewGuid(),
                FundingSource       = FundingSourceType.Levy,
                InstalmentAmount    = 1000,
                NumberOfInstalments = 12,
                PlannedEndDate      = DateTime.Today,
                StartDate           = DateTime.Today.AddMonths(-12),
            };
        }