Example #1
0
        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);
        }
Example #5
0
 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)
            });
        }
Example #7
0
        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
     };
 }
Example #10
0
 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
     });
 }
Example #12
0
        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)));
        }
Example #14
0
        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);
            }
        }
Example #15
0
        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);
        }
Example #18
0
        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
     });
 }
Example #21
0
        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));
        }
Example #22
0
        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));
        }
Example #25
0
 private static bool NegativeEarningWillResultInARefund(EarningPeriod period, List <Payment> payments)
 {
     return(period.Amount < 0 && period.Amount < payments.Sum(x => x.Amount));
 }
Example #26
0
        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>());
        }
Example #27
0
 public void Setup()
 {
     period = new EarningPeriod();
     calculatePeriodStartAndEndDate = new Mock <ICalculatePeriodStartAndEndDate>(MockBehavior.Strict);
 }
Example #28
0
        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);
        }
Example #29
0
        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);
        }
Example #30
0
        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);
        }