private FunctionalSkillEarning CreateEarning(IGrouping <string, LearningDeliveryPeriodisedValues> groupItem) { if (groupItem.Count() > 1) { throw new ArgumentException($"More than one functional skill earning of type {groupItem.Key}"); } const byte earningPeriods = 12; var periods = new EarningPeriod[earningPeriods]; for (byte i = 1; i <= earningPeriods; i++) { var periodValues = groupItem.Select(p => p.GetPeriodValue(i)).ToArray(); var periodValue = periodValues.SingleOrDefault(v => v.GetValueOrDefault(0) != 0).GetValueOrDefault(0); periods[i - 1] = new EarningPeriod { Period = i, Amount = periodValue.AsRounded(), SfaContributionPercentage = 1, }; } return(new FunctionalSkillEarning { Type = TypeMap[groupItem.Key], Periods = new ReadOnlyCollection <EarningPeriod>(periods), }); }
public async Task OnprogPayableDataLockEventWithNoApprenticeshipIdShouldNotBeStored( IReceivedDataLockEventStore receivedDataLockEventStore, PayableEarningEvent payableEarningEvent, EarningPeriod period, ApprenticeshipModel apprenticeship, List <DataLockFailure> dataLockFailures, ManageReceivedDataLockEvent manageReceivedDataLockEvent) { period.ApprenticeshipId = default(long?); period.AccountId = default(long?); payableEarningEvent.OnProgrammeEarnings = new List <OnProgrammeEarning> { new OnProgrammeEarning { Periods = (new List <EarningPeriod> { period }).AsReadOnly(), Type = OnProgrammeEarningType.Learning, CensusDate = DateTime.UtcNow } }; await manageReceivedDataLockEvent.ProcessDataLockEvent(payableEarningEvent); var result = (await receivedDataLockEventStore .GetDataLocks(payableEarningEvent.JobId, payableEarningEvent.Ukprn)).ToList(); result.Should().BeEmpty(); }
public void TestEarningPeriodMap() { var earningPeriod = new EarningPeriod { ApprenticeshipId = 101, ApprenticeshipPriceEpisodeId = 102, Period = 1, AccountId = 103, Priority = 104, SfaContributionPercentage = 1m, PriceEpisodeIdentifier = "123-01", Amount = 1000000, AgreedOnDate = DateTime.Today }; var requiredPayment = new CalculatedRequiredLevyAmount { SfaContributionPercentage = .9m, OnProgrammeEarningType = OnProgrammeEarningType.Balancing }; // act mapper.Map(earningPeriod, requiredPayment); var act1RequiredPayment = requiredPayment; Assert.AreEqual(earningPeriod.Period, act1RequiredPayment.DeliveryPeriod); Assert.AreEqual(earningPeriod.ApprenticeshipId, act1RequiredPayment.ApprenticeshipId); Assert.AreEqual(earningPeriod.ApprenticeshipPriceEpisodeId, act1RequiredPayment.ApprenticeshipPriceEpisodeId); Assert.AreEqual(earningPeriod.AgreedOnDate, act1RequiredPayment.AgreedOnDate); Assert.AreEqual(earningPeriod.Priority, act1RequiredPayment.Priority); Assert.AreEqual(earningPeriod.SfaContributionPercentage, act1RequiredPayment.SfaContributionPercentage); Assert.AreEqual(OnProgrammeEarningType.Balancing, act1RequiredPayment.OnProgrammeEarningType); }
private IncentiveEarning CreateIncentiveEarning(List <PriceEpisode> priceEpisodes, IncentiveEarningType incentiveType) { var attributeName = IncentiveEarningTypeToFM36AttributeName(incentiveType); var allPeriods = priceEpisodes.Select(p => p.PriceEpisodePeriodisedValues.SingleOrDefault(v => v.AttributeName == attributeName)) .Where(p => p != null) .ToArray(); var periods = new EarningPeriod[12]; for (byte i = 1; i <= 12; i++) { var periodValues = allPeriods.Select(p => p.GetPeriodValue(i)).ToArray(); var periodValue = periodValues.SingleOrDefault(v => v.GetValueOrDefault(0) != 0).GetValueOrDefault(0); var priceEpisodeIdentifier = periodValue == 0 ? null : priceEpisodes[periodValues.IndexOf(periodValue)].PriceEpisodeIdentifier; var sfaContributionPercentage = priceEpisodes.CalculateSfaContributionPercentage(i, priceEpisodeIdentifier); periods[i - 1] = new EarningPeriod { Period = i, Amount = periodValue.AsRounded(), PriceEpisodeIdentifier = priceEpisodeIdentifier, SfaContributionPercentage = sfaContributionPercentage, }; } var result = new IncentiveEarning { Type = incentiveType, Periods = new ReadOnlyCollection <EarningPeriod>(periods) }; return(result); }
ValidateApprenticeships (long ukprn, List <ApprenticeshipModel> apprenticeships, int academicYear, EarningPeriod period, TransactionType transactionType1, List <PriceEpisode> priceEpisodes);
private OnProgrammeEarning CreateOnProgrammeEarning(IntermediateLearningAim source, OnProgrammeEarningType onProgrammeEarningType) { var attributeName = OnProgrammeEarningTypeToFM36AttributeName(onProgrammeEarningType); var allPeriods = source.PriceEpisodes.Select(p => p.PriceEpisodePeriodisedValues.SingleOrDefault(v => v.AttributeName == attributeName)) .Where(p => p != null) .ToArray(); var periods = new EarningPeriod[12]; for (byte i = 1; i <= 12; i++) { var periodValues = allPeriods.Select(p => p.GetPeriodValue(i)).ToArray(); var periodValue = periodValues.SingleOrDefault(v => v.GetValueOrDefault(0) != 0).GetValueOrDefault(0); var priceEpisodeIdentifier = periodValue == 0 ? null : source.PriceEpisodes[periodValues.IndexOf(periodValue)].PriceEpisodeIdentifier; var sfaContributionPercentage = source.PriceEpisodes.CalculateSfaContributionPercentage(i, priceEpisodeIdentifier); periods[i - 1] = new EarningPeriod { Period = i, Amount = periodValue.AsRounded(), PriceEpisodeIdentifier = priceEpisodeIdentifier, SfaContributionPercentage = sfaContributionPercentage, }; } return(new OnProgrammeEarning { Type = onProgrammeEarningType, Periods = new ReadOnlyCollection <EarningPeriod>(periods) }); }
private FunctionalSkillEarning CreateEarning(IntermediateLearningAim source, FunctionalSkillType functionalSkillEarningType) { var attributeName = FunctionalSkillEarningTypeToFM36AttributeName(functionalSkillEarningType); var allPeriods = source.Aims.Select(p => p.LearningDeliveryPeriodisedValues.SingleOrDefault(v => v.AttributeName == attributeName)) .Where(p => p != null) .ToArray(); var periods = new EarningPeriod[12]; for (byte i = 1; i <= 12; i++) { var periodValues = allPeriods.Select(p => p.GetPeriodValue(i)).ToArray(); var periodValue = periodValues.SingleOrDefault(v => v.GetValueOrDefault(0) != 0).GetValueOrDefault(0); periods[i - 1] = new EarningPeriod { Period = i, Amount = periodValue.AsRounded(), SfaContributionPercentage = 1 }; } return(new FunctionalSkillEarning { Type = functionalSkillEarningType, Periods = new ReadOnlyCollection <EarningPeriod>(periods) }); }
public void TestEarningPeriodToCalculatedRequiredIncentiveAmountMapping() { var earningPeriod = new EarningPeriod { ApprenticeshipId = 101, ApprenticeshipPriceEpisodeId = 102, Period = 1, ApprenticeshipEmployerType = ApprenticeshipEmployerType.Levy }; var requiredPayment = new CalculatedRequiredIncentiveAmount { Type = IncentivePaymentType.OnProgrammeMathsAndEnglish }; // act mapper.Map(earningPeriod, requiredPayment); var mathsAndEnglishPayment = requiredPayment; Assert.AreEqual(earningPeriod.Period, mathsAndEnglishPayment.DeliveryPeriod); Assert.AreEqual(earningPeriod.ApprenticeshipId, mathsAndEnglishPayment.ApprenticeshipId); Assert.AreEqual(earningPeriod.ApprenticeshipPriceEpisodeId, mathsAndEnglishPayment.ApprenticeshipPriceEpisodeId); Assert.AreEqual(earningPeriod.ApprenticeshipEmployerType, mathsAndEnglishPayment.ApprenticeshipEmployerType); Assert.AreEqual(IncentivePaymentType.OnProgrammeMathsAndEnglish, mathsAndEnglishPayment.Type); }
public void Setup() { period = new EarningPeriod { Period = 1 }; }
protected abstract CourseValidationResult ValidateApprenticeship( long uln, TransactionType transactionType, LearningAim aim, int academicYear, EarningPeriod period, ApprenticeshipModel apprenticeship, List <PriceEpisode> priceEpisodes = null);
private EarningPeriod CreateEarningPeriod(EarningPeriod period) { return(new EarningPeriod { Period = period.Period, Amount = period.Amount, PriceEpisodeIdentifier = period.PriceEpisodeIdentifier, SfaContributionPercentage = period.SfaContributionPercentage }); }
protected override (List <ApprenticeshipModel> validApprenticeships, List <DataLockFailure> dataLockFailures) ValidateApprenticeships( long ukprn, List <ApprenticeshipModel> apprenticeships, int academicYear, EarningPeriod period, TransactionType transactionType, List <PriceEpisode> priceEpisodes) { var apprenticeshipsToUseThisPeriod = GetApprenticeshipsToUseThisPeriod(ukprn, apprenticeships, academicYear, period); return(apprenticeshipsToUseThisPeriod, new List <DataLockFailure>()); }
public void Setup() { period = new EarningPeriod { Period = 1 }; calculatePeriodStartAndEndDate = new Mock <ICalculatePeriodStartAndEndDate>(); calculatePeriodStartAndEndDate .Setup(x => x.GetPeriodDate(1, 1819)) .Returns(() => (new DateTime(2018, 8, 1), new DateTime(2018, 8, 31))); }
private void PopulateNonPayablePeriodFailures(EarningPeriod model, Guid parentId) { foreach (var modelDataLockFailure in model.DataLockFailures) { var row = nonPayablePeriodFailures.NewRow(); row["DataLockEventNonPayablePeriodId"] = parentId; row["DataLockFailureId"] = (byte)modelDataLockFailure.DataLockError; row["ApprenticeshipId"] = modelDataLockFailure.ApprenticeshipId ?? (object)DBNull.Value; nonPayablePeriodFailures.Rows.Add(row); } }
private EarningPeriod BuildEarningPeriodWithApprenticeship(EarningPeriod period, ApprenticeshipModel apprenticeship, CourseValidationResult validationResult) { var newEarningPeriod = CreateEarningPeriod(period); newEarningPeriod.AccountId = apprenticeship.AccountId; newEarningPeriod.ApprenticeshipId = apprenticeship.Id; newEarningPeriod.ApprenticeshipPriceEpisodeId = validationResult.MatchedPriceEpisode.Id; newEarningPeriod.TransferSenderAccountId = apprenticeship.TransferSendingEmployerAccountId; newEarningPeriod.Priority = apprenticeship.Priority; newEarningPeriod.AgreedOnDate = apprenticeship.AgreedOnDate; newEarningPeriod.ApprenticeshipEmployerType = apprenticeship.ApprenticeshipEmployerType; return(newEarningPeriod); }
public void ApprenticeshipsNotWithinADeliveryPeriodShouldReturnDLock09() { period = new EarningPeriod { Period = 1 }; var validation = new DataLockValidationModel { PriceEpisode = new PriceEpisode { EffectiveTotalNegotiatedPriceStartDate = startDate, Identifier = priceEpisodeIdentifier }, EarningPeriod = period, Apprenticeship = new ApprenticeshipModel { Id = 1, AccountId = 21, ApprenticeshipPriceEpisodes = new List <ApprenticeshipPriceEpisodeModel> { new ApprenticeshipPriceEpisodeModel { Id = 90 }, new ApprenticeshipPriceEpisodeModel { Id = 91 }, new ApprenticeshipPriceEpisodeModel { Id = 92 }, new ApprenticeshipPriceEpisodeModel { Id = 93 }, }, EstimatedStartDate = new DateTime(2018, 9, 15) } }; calculatePeriodStartAndEndDate .Setup(x => x.GetPeriodDate(1, 1819)) .Returns(() => (new DateTime(2018, 8, 1), new DateTime(2018, 8, 31))); var validator = new StartDateValidator(calculatePeriodStartAndEndDate.Object); var result = validator.Validate(validation); result.DataLockErrorCode.Should().NotBeNull(); result.DataLockErrorCode.Should().Be(DataLockErrorCode.DLOCK_09); result.ApprenticeshipPriceEpisodes.Should().BeEmpty(); }
public void Prepare() { mocker = AutoMock.GetStrict(); var earningPeriod = new EarningPeriod { Period = 1 }; dataLockValidationModel = new DataLockValidationModel { EarningPeriod = earningPeriod, PriceEpisode = new PriceEpisode(), Apprenticeship = new ApprenticeshipModel { Id = 1, Uln = 100, ApprenticeshipPriceEpisodes = new List <ApprenticeshipPriceEpisodeModel> { new ApprenticeshipPriceEpisodeModel { Id = 99, ApprenticeshipId = 1, Cost = 100, StartDate = DateTime.Today } } } }; mocker.Mock <IOnProgrammeAndIncentiveStoppedValidator>() .Setup(validator => validator.Validate(It.IsAny <DataLockValidationModel>())) .Returns(() => new ValidationResult()); mocker.Mock <ICompletionStoppedValidator>() .Setup(validator => validator.Validate(It.IsAny <DataLockValidationModel>())) .Returns(() => new ValidationResult()); mocker.Mock <IStartDateValidator>() .Setup(validator => validator.Validate(It.IsAny <DataLockValidationModel>())) .Returns(() => new ValidationResult()) .Verifiable(); negotiatedPriceValidator = new Mock <ICourseValidator>(); apprenticeshipPauseValidator = new Mock <ICourseValidator>(); courseValidators = new List <ICourseValidator> { negotiatedPriceValidator.Object, apprenticeshipPauseValidator.Object, }; mocker.Provide <List <ICourseValidator> >(courseValidators); }
protected override CourseValidationResult ValidateApprenticeship(long uln, TransactionType transactionType, LearningAim aim, int academicYear, EarningPeriod period, ApprenticeshipModel apprenticeship, List <PriceEpisode> priceEpisodes = null) { var validationModel = new DataLockValidationModel { EarningPeriod = period, Apprenticeship = apprenticeship, PriceEpisode = priceEpisodes.SingleOrDefault(o => o.Identifier.Equals(period.PriceEpisodeIdentifier, StringComparison.OrdinalIgnoreCase)) ?? throw new InvalidOperationException($"Failed to find price episode: {period.PriceEpisodeIdentifier} for uln: {uln}, earning: {transactionType:G}, period: {period.Period}"), TransactionType = transactionType, Aim = aim, AcademicYear = academicYear }; return(courseValidationProcessor.ValidateCourse(validationModel)); } }
public async Task When_job_succeeded_builds_approval_event_for_new_and_updated_price_episodes( ICurrentPriceEpisodeForJobStore currentContext, IReceivedDataLockEventStore receivedContext, TestCaseData testCaseData, PriceEpisode newPriceEpisode, EarningPeriod newPeriod, PriceEpisodesReceivedService sut) { // Given testCaseData.earning.PriceEpisodes.Add(newPriceEpisode); newPeriod.ApprenticeshipId = testCaseData.apprenticeship.Id; newPeriod.AccountId = testCaseData.apprenticeship.AccountId; newPeriod.PriceEpisodeIdentifier = newPriceEpisode.Identifier; testCaseData.earning.OnProgrammeEarnings[0].Periods = testCaseData.earning.OnProgrammeEarnings[0].Periods.Append(newPeriod).ToList().AsReadOnly(); await currentContext.Add(CreateCurrentPriceEpisodeFor(testCaseData.earning)); await testCaseData.AddDataLockEventToContext(receivedContext); // When var changeMessages = await sut.GetPriceEpisodeChanges(testCaseData.earning.JobId, testCaseData.earning.Ukprn, testCaseData.earning.CollectionYear); // Then changeMessages.Should().ContainEquivalentOf( new { DataLock = new { PriceEpisodeIdentifier = testCaseData.earning.PriceEpisodes[0].Identifier, Status = PriceEpisodeStatus.Updated, }, }); changeMessages.Should().ContainEquivalentOf( new { DataLock = new { PriceEpisodeIdentifier = newPriceEpisode.Identifier, Status = PriceEpisodeStatus.New, }, }); }
private static DataLockFailureEntity CreateEntity(DataLockEvent dataLockEvent, TransactionType transactionType, byte deliveryPeriod, EarningPeriod period) { return(new DataLockFailureEntity { Ukprn = dataLockEvent.Ukprn, CollectionPeriod = dataLockEvent.CollectionPeriod.Period, AcademicYear = dataLockEvent.CollectionYear, TransactionType = transactionType, DeliveryPeriod = deliveryPeriod, LearnerReferenceNumber = dataLockEvent.Learner.ReferenceNumber, LearnerUln = dataLockEvent.Learner.Uln, LearningAimFrameworkCode = dataLockEvent.LearningAim.FrameworkCode, LearningAimPathwayCode = dataLockEvent.LearningAim.PathwayCode, LearningAimProgrammeType = dataLockEvent.LearningAim.ProgrammeType, LearningAimReference = dataLockEvent.LearningAim.Reference, LearningAimStandardCode = dataLockEvent.LearningAim.StandardCode, EarningPeriod = period }); }
protected override CourseValidationResult ValidateApprenticeship( long uln, TransactionType transactionType, LearningAim aim, int academicYear, EarningPeriod period, ApprenticeshipModel apprenticeship, List <PriceEpisode> priceEpisodes = null) { var validationModel = new DataLockValidationModel { EarningPeriod = period, Apprenticeship = apprenticeship, TransactionType = transactionType, Aim = aim, AcademicYear = academicYear }; return(functionalSkillValidationProcessor.ValidateCourse(validationModel)); }
public void Prepare() { mocker = AutoMock.GetStrict(); var earningPeriod = new EarningPeriod { Period = 1 }; dataLockValidationModel = new DataLockValidationModel { EarningPeriod = earningPeriod, PriceEpisode = new PriceEpisode(), Apprenticeship = new ApprenticeshipModel { Id = 1, Uln = 100, ApprenticeshipPriceEpisodes = new List <ApprenticeshipPriceEpisodeModel> { new ApprenticeshipPriceEpisodeModel { Id = 99, ApprenticeshipId = 1, Cost = 100, StartDate = DateTime.Today } } } }; negotiatedPriceValidator = new Mock <ICourseValidator>(); apprenticeshipPauseValidator = new Mock <ICourseValidator>(); courseValidators = new List <ICourseValidator> { negotiatedPriceValidator.Object, apprenticeshipPauseValidator.Object, }; mocker.Provide <List <ICourseValidator> >(courseValidators); }
public async Task TestCreatesMultipleEventsForPeriodsAndTypes(DataLockEvent failureEvent) { // arrange // change of dlock code var oldTT2P5 = new DataLockFailureEntity { Id = 1, DeliveryPeriod = 5, TransactionType = TransactionType.Completion, EarningPeriod = new EarningPeriod { Period = 5, DataLockFailures = new List <DataLockFailure> { new DataLockFailure { DataLockError = DataLockErrorCode.DLOCK_06 } } } }; var newTT2p5 = new EarningPeriod { Period = 5, Amount = 1, DataLockFailures = new List <DataLockFailure> { new DataLockFailure { DataLockError = DataLockErrorCode.DLOCK_04 } } }; // no new - changed to pass var oldTT3p3 = new DataLockFailureEntity { Id = 2, DeliveryPeriod = 3, TransactionType = TransactionType.Balancing, EarningPeriod = new EarningPeriod { Period = 3, DataLockFailures = new List <DataLockFailure> { new DataLockFailure { DataLockError = DataLockErrorCode.DLOCK_06 } } } }; var newTT3p3 = new EarningPeriod { Period = 3, Amount = 1, ApprenticeshipId = 4, ApprenticeshipPriceEpisodeId = 4 }; // no change var oldTT2p6 = new DataLockFailureEntity { Id = 3, DeliveryPeriod = 6, TransactionType = TransactionType.Completion, EarningPeriod = new EarningPeriod { Period = 6, DataLockFailures = new List <DataLockFailure> { new DataLockFailure { DataLockError = DataLockErrorCode.DLOCK_04 } } } }; var newTT2p6 = new EarningPeriod { Period = 6, Amount = 1, DataLockFailures = new List <DataLockFailure> { new DataLockFailure { DataLockError = DataLockErrorCode.DLOCK_04 } } }; // change of dlock code var oldTT16p5 = new DataLockFailureEntity { Id = 4, DeliveryPeriod = 5, TransactionType = TransactionType.CareLeaverApprenticePayment, EarningPeriod = new EarningPeriod { Period = 5, DataLockFailures = new List <DataLockFailure> { new DataLockFailure { DataLockError = DataLockErrorCode.DLOCK_06 } } } }; var newTT16p5 = new EarningPeriod { Period = 5, Amount = 1, DataLockFailures = new List <DataLockFailure> { new DataLockFailure { DataLockError = DataLockErrorCode.DLOCK_04 } } }; // no new - change to pass var oldTT10p3 = new DataLockFailureEntity { Id = 5, DeliveryPeriod = 3, TransactionType = TransactionType.Balancing16To18FrameworkUplift, EarningPeriod = new EarningPeriod { Period = 3, DataLockFailures = new List <DataLockFailure> { new DataLockFailure { DataLockError = DataLockErrorCode.DLOCK_06 } } } }; var newTT10p3 = new EarningPeriod { Period = 3, Amount = 1, ApprenticeshipId = 10, ApprenticeshipPriceEpisodeId = 10, DataLockFailures = new List <DataLockFailure>() }; // no change var oldTT16p6 = new DataLockFailureEntity { Id = 6, DeliveryPeriod = 6, TransactionType = TransactionType.CareLeaverApprenticePayment, EarningPeriod = new EarningPeriod { Period = 6, DataLockFailures = new List <DataLockFailure> { new DataLockFailure { DataLockError = DataLockErrorCode.DLOCK_04 } } } }; var newTT16p6 = new EarningPeriod { Period = 6, Amount = 1, DataLockFailures = new List <DataLockFailure> { new DataLockFailure { DataLockError = DataLockErrorCode.DLOCK_04 } } }; // no old - change to fail var newTT2p1 = new EarningPeriod { Period = 1, Amount = 1, DataLockFailures = new List <DataLockFailure> { new DataLockFailure { DataLockError = DataLockErrorCode.DLOCK_03 } } }; var newTT2p2 = new EarningPeriod { Period = 2, Amount = 1 }; var newTT16p1 = new EarningPeriod { Period = 1, Amount = 1, DataLockFailures = new List <DataLockFailure> { new DataLockFailure { DataLockError = DataLockErrorCode.DLOCK_03 } } }; var newTT16p2 = new EarningPeriod { Period = 2, Amount = 1 }; failureEvent.Ukprn = 1; failureEvent.Learner = new Learner { ReferenceNumber = "2", Uln = 3 }; failureEvent.LearningAim = new LearningAim { FrameworkCode = 4, StandardCode = 5, Reference = "6", PathwayCode = 7, ProgrammeType = 8, FundingLineType = "9" }; failureEvent.CollectionYear = 1819; failureEvent.CollectionPeriod = new CollectionPeriod { AcademicYear = 7, Period = 8 }; failureEvent.OnProgrammeEarnings = new List <OnProgrammeEarning> { new OnProgrammeEarning { Type = OnProgrammeEarningType.Completion, // TT2 Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod> { // changed to fail newTT2p1, // no change newTT2p2, // change of dlock code newTT2p5, // no change newTT2p6, newTT10p3 }) }, new OnProgrammeEarning { Type = OnProgrammeEarningType.Balancing, Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod> { newTT3p3 }) } }; failureEvent.IncentiveEarnings = new List <IncentiveEarning> { new IncentiveEarning { Type = IncentiveEarningType.CareLeaverApprenticePayment, // TT16 Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod> { // changed to fail newTT16p1, // no change newTT16p2, // change of dlock code newTT16p5, // no change newTT16p6, }) }, new IncentiveEarning { Type = IncentiveEarningType.Balancing16To18FrameworkUplift, Periods = new ReadOnlyCollection <EarningPeriod>(new List <EarningPeriod> { newTT10p3 }) } }; var oldFailures = new List <DataLockFailureEntity> { oldTT2P5, oldTT3p3, oldTT2p6, oldTT16p5, oldTT10p3, oldTT16p6, }; repositoryMock.Setup(r => r.GetFailures(1, "2", 4, 7, 8, 5, "6", 1819)).ReturnsAsync(oldFailures).Verifiable(); repositoryMock.Setup(r => r.ReplaceFailures(It.Is <List <long> >(old => old.Count == 4), It.Is <List <DataLockFailureEntity> >(newF => newF.Count == 4), It.IsAny <Guid>(), It.IsAny <Guid>())).Returns(Task.CompletedTask).Verifiable(); // TT2 // P1 dataLockStatusServiceMock.Setup(s => s.GetStatusChange(null, newTT2p1.DataLockFailures)).Returns(DataLockStatusChange.ChangedToFailed).Verifiable(); // P2 //dataLockStatusServiceMock.Setup(s => s.GetStatusChange(null, newTT2p2.DataLockFailures)).Returns(DataLockStatusChange.NoChange).Verifiable(); // P5 dataLockStatusServiceMock.Setup(s => s.GetStatusChange(oldTT2P5.EarningPeriod.DataLockFailures, newTT2p5.DataLockFailures)).Returns(DataLockStatusChange.FailureChanged).Verifiable(); // P6 dataLockStatusServiceMock.Setup(s => s.GetStatusChange(oldTT2p6.EarningPeriod.DataLockFailures, newTT2p6.DataLockFailures)).Returns(DataLockStatusChange.NoChange).Verifiable(); // TT3 P3 dataLockStatusServiceMock.Setup(s => s.GetStatusChange(oldTT3p3.EarningPeriod.DataLockFailures, newTT3p3.DataLockFailures)).Returns(DataLockStatusChange.ChangedToPassed).Verifiable(); // TT10 P3 dataLockStatusServiceMock.Setup(s => s.GetStatusChange(oldTT10p3.EarningPeriod.DataLockFailures, newTT10p3.DataLockFailures)).Returns(DataLockStatusChange.ChangedToPassed).Verifiable(); // TT16 // P1 dataLockStatusServiceMock.Setup(s => s.GetStatusChange(null, newTT16p1.DataLockFailures)).Returns(DataLockStatusChange.ChangedToFailed).Verifiable(); // P2 //dataLockStatusServiceMock.Setup(s => s.GetStatusChange(null, newTT16p2.DataLockFailures)).Returns(DataLockStatusChange.NoChange).Verifiable(); // P5 dataLockStatusServiceMock.Setup(s => s.GetStatusChange(oldTT16p5.EarningPeriod.DataLockFailures, newTT16p5.DataLockFailures)).Returns(DataLockStatusChange.FailureChanged).Verifiable(); // P6 dataLockStatusServiceMock.Setup(s => s.GetStatusChange(oldTT16p6.EarningPeriod.DataLockFailures, newTT16p6.DataLockFailures)).Returns(DataLockStatusChange.NoChange).Verifiable(); var statusChangedEvents = await processor.ProcessDataLockFailure(failureEvent).ConfigureAwait(false); // assert statusChangedEvents.Should().NotBeNull(); statusChangedEvents.Should().HaveCount(3); var changedToFail = statusChangedEvents.SingleOrDefault(e => e is DataLockStatusChangedToFailed); changedToFail.Should().NotBeNull(); changedToFail.TransactionTypesAndPeriods.Should().HaveCount(2); changedToFail.TransactionTypesAndPeriods.Should().ContainKey(TransactionType.Completion); changedToFail.TransactionTypesAndPeriods[TransactionType.Completion].Should().HaveCount(1); changedToFail.TransactionTypesAndPeriods[TransactionType.Completion][0].Period.Should().Be(1); changedToFail.TransactionTypesAndPeriods.Should().ContainKey(TransactionType.CareLeaverApprenticePayment); changedToFail.TransactionTypesAndPeriods[TransactionType.CareLeaverApprenticePayment].Should().HaveCount(1); changedToFail.TransactionTypesAndPeriods[TransactionType.CareLeaverApprenticePayment][0].Period.Should().Be(1); var changedToPass = statusChangedEvents.SingleOrDefault(e => e is DataLockStatusChangedToPassed); changedToPass.Should().NotBeNull(); changedToPass.TransactionTypesAndPeriods.Should().HaveCount(2); changedToPass.TransactionTypesAndPeriods.Should().ContainKey(TransactionType.Balancing); changedToPass.TransactionTypesAndPeriods[TransactionType.Balancing].Should().HaveCount(1); changedToPass.TransactionTypesAndPeriods[TransactionType.Balancing][0].Period.Should().Be(3); changedToPass.TransactionTypesAndPeriods.Should().ContainKey(TransactionType.Balancing16To18FrameworkUplift); changedToPass.TransactionTypesAndPeriods[TransactionType.Balancing16To18FrameworkUplift].Should().HaveCount(1); changedToPass.TransactionTypesAndPeriods[TransactionType.Balancing16To18FrameworkUplift][0].Period.Should().Be(3); var changedCode = statusChangedEvents.SingleOrDefault(e => e is DataLockFailureChanged); changedCode.Should().NotBeNull(); changedCode.TransactionTypesAndPeriods.Should().HaveCount(2); changedCode.TransactionTypesAndPeriods.Should().ContainKey(TransactionType.Completion); changedCode.TransactionTypesAndPeriods[TransactionType.Completion].Should().HaveCount(1); changedCode.TransactionTypesAndPeriods[TransactionType.Completion][0].Period.Should().Be(5); changedCode.TransactionTypesAndPeriods.Should().ContainKey(TransactionType.CareLeaverApprenticePayment); changedCode.TransactionTypesAndPeriods[TransactionType.CareLeaverApprenticePayment].Should().HaveCount(1); changedCode.TransactionTypesAndPeriods[TransactionType.CareLeaverApprenticePayment][0].Period.Should().Be(5); }
public async Task Built_event_should_have_distinct_errors( [Frozen] Mock <IApprenticeshipRepository> repository, PriceEpisodeStatusChangeBuilder sut, EarningFailedDataLockMatching dataLock, EarningPeriod period, ApprenticeshipModel apprenticeships) { var periods = new List <EarningPeriod> { period }; var dLockFailures = new List <DataLockFailure> { new DataLockFailure { ApprenticeshipId = apprenticeships.Id, DataLockError = DataLockErrorCode.DLOCK_03, ApprenticeshipPriceEpisodeIds = new List <long> { apprenticeships.ApprenticeshipPriceEpisodes[0].Id } }, new DataLockFailure { ApprenticeshipId = apprenticeships.Id, DataLockError = DataLockErrorCode.DLOCK_07, ApprenticeshipPriceEpisodeIds = apprenticeships.ApprenticeshipPriceEpisodes.Select(x => x.Id).ToList(), }, new DataLockFailure { ApprenticeshipId = apprenticeships.Id, DataLockError = DataLockErrorCode.DLOCK_06, ApprenticeshipPriceEpisodeIds = apprenticeships.ApprenticeshipPriceEpisodes.Select(x => x.Id).ToList(), }, }; dataLock.OnProgrammeEarnings = new List <OnProgrammeEarning> { new OnProgrammeEarning { Type = OnProgrammeEarningType.Learning, }, new OnProgrammeEarning { Type = OnProgrammeEarningType.Completion, } }; CommonTestSetup(repository, dataLock, periods, new List <ApprenticeshipModel> { apprenticeships }, dLockFailures); var priceEpisode = dataLock.PriceEpisodes[0]; dataLock.OnProgrammeEarnings[1].Periods = periods.AsReadOnly(); var result = await sut.Build( new List <DataLockEvent> { dataLock }, new List <(string identifier, PriceEpisodeStatus status)> { (priceEpisode.Identifier, PriceEpisodeStatus.New) }, new List <PriceEpisodeStatusChange>(), dataLock.CollectionPeriod.AcademicYear); result.Should().NotBeEmpty(); result[0].Errors.Should().HaveCount(3); result[0].Errors.Should().BeEquivalentTo(new List <LegacyDataLockEventError> { new LegacyDataLockEventError { DataLockEventId = result[0].DataLock.DataLockEventId, ErrorCode = DataLockErrorCode.DLOCK_03.ToString(), }, new LegacyDataLockEventError { DataLockEventId = result[0].DataLock.DataLockEventId, ErrorCode = DataLockErrorCode.DLOCK_07.ToString(), }, new LegacyDataLockEventError { DataLockEventId = result[0].DataLock.DataLockEventId, ErrorCode = DataLockErrorCode.DLOCK_06.ToString(), }, }, options => options.Excluding(o => o.SystemDescription)); }
private static bool NegativeEarningWillResultInARefund(EarningPeriod period, List <Payment> payments) { return(period.Amount < 0 && period.Amount < payments.Sum(x => x.Amount)); }
protected override (List <ApprenticeshipModel> validApprenticeships, List <DataLockFailure> dataLockFailures) ValidateApprenticeships(long ukprn, List <ApprenticeshipModel> apprenticeships, int academicYear, EarningPeriod period, TransactionType transactionType, List <PriceEpisode> priceEpisodes) { var ilrPriceEpisode = priceEpisodes.SingleOrDefault(o => o.Identifier.Equals(period.PriceEpisodeIdentifier, StringComparison.OrdinalIgnoreCase)) ?? throw new InvalidOperationException($"Failed to find price episode: {period.PriceEpisodeIdentifier} for ukprn: {ukprn}, earning: {transactionType:G}, period: {period.Period}"); var startDateValidationResult = startDateValidator.Validate(ilrPriceEpisode, apprenticeships); if (startDateValidationResult.dataLockFailures.Any()) { return(new List <ApprenticeshipModel>(), startDateValidationResult.dataLockFailures); } var onProgrammeValidationResult = onProgrammeAndIncentiveStoppedValidator.Validate(startDateValidationResult.validApprenticeships, transactionType, period, academicYear); if (onProgrammeValidationResult.dataLockFailures.Any()) { return(new List <ApprenticeshipModel>(), onProgrammeValidationResult.dataLockFailures); } var completionStoppedResult = completionStoppedValidator.Validate(ilrPriceEpisode, onProgrammeValidationResult.validApprenticeships, transactionType); if (completionStoppedResult.dataLockFailures.Any()) { return(new List <ApprenticeshipModel>(), completionStoppedResult.dataLockFailures); } return(completionStoppedResult.validApprenticeships, new List <DataLockFailure>()); }
public void Setup() { period = new EarningPeriod(); calculatePeriodStartAndEndDate = new Mock <ICalculatePeriodStartAndEndDate>(MockBehavior.Strict); }
private List <ApprenticeshipModel> GetApprenticeshipsToUseThisPeriod(long ukprn, List <ApprenticeshipModel> apprenticeships, int academicYear, EarningPeriod period) { var apprenticeshipsToUseThisPeriod = new List <ApprenticeshipModel>(); var apprenticeshipsWithinPeriod = apprenticeships .Where(a => a.Ukprn == ukprn && ApprenticeshipStartWithinPeriod(a, period.Period, academicYear)) .ToList(); var activeApprenticeships = apprenticeshipsWithinPeriod .Where(x => x.Status == ApprenticeshipStatus.Active) .ToList(); if (!activeApprenticeships.Any()) { var mostRecentApprenticeship = apprenticeshipsWithinPeriod .OrderByDescending(x => x.Id) .FirstOrDefault(); if (mostRecentApprenticeship != null) { apprenticeshipsToUseThisPeriod.Add(mostRecentApprenticeship); } } else { var mostRecentApprenticeship = activeApprenticeships .OrderByDescending(x => x.EstimatedStartDate) .FirstOrDefault(); apprenticeshipsToUseThisPeriod.Add(mostRecentApprenticeship); } if (apprenticeshipsToUseThisPeriod.Count == 0) { apprenticeshipsToUseThisPeriod = apprenticeships .OrderByDescending(x => x.EstimatedStartDate) .Take(1) .ToList(); } return(apprenticeshipsToUseThisPeriod); }
private async Task <LegacyDataLockEvent> SaveDataLockEvent(CancellationToken cancellationToken, DataLockStatusChanged dataLockStatusChangedEvent, EarningPeriod earningPeriod, long?apprenticeshipId) { var priceEpisode = dataLockStatusChangedEvent.PriceEpisodes.Single(e => e.Identifier == earningPeriod.PriceEpisodeIdentifier); var hasTnp3 = priceEpisode.TotalNegotiatedPrice3.GetValueOrDefault(0) > 0; var dataLockEvent = new LegacyDataLockEvent // commitment ID { AcademicYear = dataLockStatusChangedEvent.CollectionPeriod.AcademicYear.ToString(), UKPRN = dataLockStatusChangedEvent.Ukprn, DataLockEventId = dataLockStatusChangedEvent.EventId, EventSource = 1, // submission HasErrors = !(dataLockStatusChangedEvent is DataLockStatusChangedToPassed), ULN = dataLockStatusChangedEvent.Learner.Uln, Status = dataLockStatusChangedEvent is DataLockStatusChangedToPassed ? 3 : dataLockStatusChangedEvent is DataLockStatusChangedToFailed ? 1 : 2, ProcessDateTime = DateTime.UtcNow, LearnRefNumber = dataLockStatusChangedEvent.Learner.ReferenceNumber, IlrFrameworkCode = dataLockStatusChangedEvent.LearningAim.FrameworkCode, IlrPathwayCode = dataLockStatusChangedEvent.LearningAim.PathwayCode, IlrProgrammeType = dataLockStatusChangedEvent.LearningAim.ProgrammeType, IlrStandardCode = dataLockStatusChangedEvent.LearningAim.StandardCode, SubmittedDateTime = dataLockStatusChangedEvent.IlrSubmissionDateTime, PriceEpisodeIdentifier = earningPeriod.PriceEpisodeIdentifier, CommitmentId = apprenticeshipId.GetValueOrDefault(0), EmployerAccountId = earningPeriod.AccountId.GetValueOrDefault(0), AimSeqNumber = dataLockStatusChangedEvent.LearningAim.SequenceNumber, IlrPriceEffectiveFromDate = priceEpisode.EffectiveTotalNegotiatedPriceStartDate, IlrPriceEffectiveToDate = priceEpisode.ActualEndDate.GetValueOrDefault(priceEpisode.PlannedEndDate), IlrEndpointAssessorPrice = hasTnp3 ? priceEpisode.TotalNegotiatedPrice4 : priceEpisode.TotalNegotiatedPrice2, IlrFileName = TrimUkprnFromIlrFileNameLimitToValidLength(dataLockStatusChangedEvent.IlrFileName), IlrStartDate = priceEpisode.CourseStartDate, IlrTrainingPrice = hasTnp3 ? priceEpisode.TotalNegotiatedPrice3 : priceEpisode.TotalNegotiatedPrice1, }; logger.LogVerbose($"Saving legacy DataLockEvent {dataLockStatusChangedEvent.EventId} for UKPRN {dataLockStatusChangedEvent.Ukprn}"); await dataLockEventWriter.Write(dataLockEvent, cancellationToken).ConfigureAwait(false); return(dataLockEvent); }
Validate(List <ApprenticeshipModel> apprenticeships, TransactionType transactionType, EarningPeriod earningPeriod, int academicYear) { // Only deal with Transaction Type 1 OnProgramme and incentives if (transactionType == TransactionType.Balancing || transactionType == TransactionType.Completion) { return(apprenticeships, new List <DataLockFailure>()); } var periodDate = calculatePeriodStartAndEndDate.GetPeriodDate(earningPeriod.Period, academicYear); var matchedApprenticeships = apprenticeships .Where(a => { if (a.Status != ApprenticeshipStatus.Stopped) { return(true); } if (a.StopDate >= periodDate.periodEndDate) { return(true); } return(false); }) .ToList(); if (matchedApprenticeships.Any()) { return(matchedApprenticeships, new List <DataLockFailure>()); } var dataLockFailures = apprenticeships.Select(a => new DataLockFailure { ApprenticeshipId = a.Id, ApprenticeshipPriceEpisodeIds = a.ApprenticeshipPriceEpisodes .Where(o => !o.Removed) .Select(x => x.Id).ToList(), DataLockError = DataLockErrorCode.DLOCK_10 }).ToList(); return(new List <ApprenticeshipModel>(), dataLockFailures); }