Example #1
0
        protected async Task Arrange(string prefix)
        {
            var apprenticeshipResourceName = $"{prefix}.Apprenticeships.json";

            var apps = await Context.AddEntitiesFromJsonResource <ApprenticeshipModel>($"{prefix}.Apprenticeships.json");

            if (apps.Length == 0)
            {
                throw new Exception("There must be an apprenticeship to run these tests.");
            }

            Apprenticeship = apps.FirstOrDefault(x => x.Status == PaymentsApprenticeshipStatus.Active);
            var appid = Apprenticeship?.Id;

            await Context.AddEntitiesFromJsonResource <EarningEventModel>($"{prefix}.EarningEvents.json");

            var dlocks = JsonConvert.DeserializeObject <DataLockEventModel[]>(
                Resources.LoadAsString($"{prefix}.Datalocks.json"));

            foreach (var l in dlocks
                     .SelectMany(x => x.NonPayablePeriods)
                     .SelectMany(x => x.DataLockEventNonPayablePeriodFailures))
            {
                l.ApprenticeshipId = appid;
            }

            await Context.AddEntities(dlocks);

            TimeProvider.Today.Returns(new DateTime(2019, 08, 01));
        }
        public void SetUp()
        {
            mocker = AutoMock.GetLoose();
            mocker.Mock <IApprenticeshipRepository>()
            .Setup(x => x.Add(It.IsAny <ApprenticeshipModel>()))
            .Returns(Task.CompletedTask);
            mocker.Mock <IApprenticeshipRepository>()
            .Setup(x => x.GetDuplicates(It.IsAny <long>()))
            .ReturnsAsync(new List <ApprenticeshipDuplicateModel>
            {
                new ApprenticeshipDuplicateModel {
                    ApprenticeshipId = 321, Ukprn = 5678, Uln = 54321, Id = 1
                }
            });

            mocker.Mock <IApprenticeshipApprovedUpdatedService>()
            .Setup(x => x.UpdateApprenticeship(It.IsAny <UpdatedApprenticeshipApprovedModel>()))
            .ReturnsAsync(new ApprenticeshipModel());

            mocker.Mock <IApprenticeshipDataLockTriageService>()
            .Setup(x => x.UpdateApprenticeship(It.IsAny <UpdatedApprenticeshipDataLockTriageModel>()))
            .ReturnsAsync(new ApprenticeshipModel());

            apprenticeship = new ApprenticeshipModel
            {
                Id        = 1234,
                AccountId = 12345,
                Ukprn     = 123,
                Uln       = 54321
            };
        }
        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 async Task Builds_an_event_with_errors(
            DataLockErrorCode errorCode,
            string description,
            [Frozen] Mock <IApprenticeshipRepository> repository,
            PriceEpisodeStatusChangeBuilder sut,
            EarningFailedDataLockMatching dataLock,
            List <EarningPeriod> periods,
            List <DataLockFailure> dataLockFailures,
            ApprenticeshipModel apprenticeships)
        {
            CommonTestSetup(repository, dataLock, periods, new List <ApprenticeshipModel> {
                apprenticeships
            }, dataLockFailures);
            var priceEpisode = dataLock.PriceEpisodes[0];

            periods[0].DataLockFailures[0].DataLockError = errorCode;

            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().ContainEquivalentOf(new
            {
                DataLockEventId   = result[0].DataLock.DataLockEventId,
                ErrorCode         = errorCode.ToString(),
                SystemDescription = description,
            });
        }
Example #5
0
        private async Task PublishApprenticeshipUpdate(ApprenticeshipModel updatedApprenticeship)
        {
            var updatedEvent     = mapper.Map <ApprenticeshipUpdated>(updatedApprenticeship);
            var endpointInstance = await endpointInstanceFactory.GetEndpointInstance().ConfigureAwait(false);

            await endpointInstance.Publish(updatedEvent).ConfigureAwait(false);
        }
        public void ReturnsOnlyCommitmentsThatAreNotStopped(ApprenticeshipModel apprenticeshipA, ApprenticeshipModel apprenticeshipB, PriceEpisode priceEpisode)
        {
            priceEpisode.EffectiveTotalNegotiatedPriceStartDate = new DateTime(2018, 8, 1);
            priceEpisode.ActualEndDate = new DateTime(2020, 8, 30);

            apprenticeshipA.StopDate = new DateTime(2019, 8, 1);
            apprenticeshipA.Status   = ApprenticeshipStatus.Stopped;
            apprenticeshipA.ApprenticeshipPriceEpisodes[0].StartDate = new DateTime(2018, 8, 1);
            apprenticeshipA.ApprenticeshipPriceEpisodes[0].EndDate   = new DateTime(2019, 8, 30);

            apprenticeshipB.Status = ApprenticeshipStatus.Active;
            apprenticeshipB.ApprenticeshipPriceEpisodes[0].StartDate = new DateTime(2019, 8, 1);
            apprenticeshipB.ApprenticeshipPriceEpisodes[0].EndDate   = new DateTime(2020, 8, 30);

            var apprenticeships = new List <ApprenticeshipModel> {
                apprenticeshipA, apprenticeshipB
            };

            var validator = new CompletionStoppedValidator();
            var result    = validator.Validate(priceEpisode, apprenticeships, TransactionType.Completion);

            result.dataLockFailures.Should().BeEmpty();
            result.validApprenticeships.Should().NotBeNull();
            result.validApprenticeships.All(x => x.Id == apprenticeshipB.Id).Should().BeTrue();
        }
Example #7
0
 protected override void HandleUpdated(ApprenticeshipModel current, UpdatedApprenticeshipDataLockTriageModel updated)
 {
     current.AgreedOnDate  = updated.AgreedOnDate;
     current.StandardCode  = updated.StandardCode;
     current.ProgrammeType = updated.ProgrammeType;
     current.FrameworkCode = updated.FrameworkCode;
     current.PathwayCode   = updated.PathwayCode;
 }
Example #8
0
 protected abstract CourseValidationResult ValidateApprenticeship(
     long uln,
     TransactionType transactionType,
     LearningAim aim,
     int academicYear,
     EarningPeriod period,
     ApprenticeshipModel apprenticeship,
     List <PriceEpisode> priceEpisodes = null);
        private static DateTime GetApprenticeshipActualStartDate(ApprenticeshipModel apprenticeship)
        {
            var apprenticeshipActualStartDate = apprenticeship.ApprenticeshipPriceEpisodes
                                                .Where(x => !x.Removed)
                                                .OrderBy(x => x.StartDate)
                                                .First().StartDate;

            return(apprenticeshipActualStartDate);
        }
        private static DateTime GetApprenticeshipEstimatedEndDate(ApprenticeshipModel apprenticeship)
        {
            var latestApprenticeshipPriceEpisode = apprenticeship
                                                   .ApprenticeshipPriceEpisodes
                                                   .Where(x => !x.Removed)
                                                   .OrderByDescending(x => x.EndDate)
                                                   .First();

            return(latestApprenticeshipPriceEpisode.EndDate ?? DateTime.MaxValue);
        }
        public void Maps_IsLevyPayer_From_ApprenticeshipModel_To_ApprenticeshipUpdated_Correctly()
        {
            var apprenticeship = new ApprenticeshipModel
            {
                IsLevyPayer = true
            };
            var model = Mapper.Map <ApprenticeshipUpdated>(apprenticeship);

            model.IsLevyPayer.Should().BeTrue();
        }
Example #12
0
        protected override void UpdateHistory(ApprenticeshipModel current, UpdatedApprenticeshipPausedModel updated)
        {
            var newPauseModel = new ApprenticeshipPauseModel
            {
                ApprenticeshipId = updated.ApprenticeshipId,
                PauseDate        = updated.PauseDate
            };

            current.ApprenticeshipPauses.Add(newPauseModel);
        }
Example #13
0
 protected override void HandleUpdated(ApprenticeshipModel current, UpdatedApprenticeshipApprovedModel updated)
 {
     current.AgreedOnDate       = updated.AgreedOnDate;
     current.Uln                = updated.Uln;
     current.EstimatedStartDate = updated.EstimatedStartDate;
     current.EstimatedEndDate   = updated.EstimatedEndDate;
     current.StandardCode       = updated.StandardCode;
     current.ProgrammeType      = updated.ProgrammeType;
     current.FrameworkCode      = updated.FrameworkCode;
     current.PathwayCode        = updated.PathwayCode;
 }
Example #14
0
        private bool ApprenticeshipStartWithinPeriod(ApprenticeshipModel apprenticeship, byte deliveryPeriod, int academicYear)
        {
            var periodDates = calculatePeriodStartAndEndDate.GetPeriodDate(deliveryPeriod, academicYear);

            if (apprenticeship.EstimatedStartDate > periodDates.periodEndDate)
            {
                return(false);
            }

            return(true);
        }
Example #15
0
 public static CollectionPeriod ToCollectionPeriod(
     this EarningEventModel earning,
     ApprenticeshipModel apprenticeship,
     IEnumerable <DataLockEventModel> datalocks)
 =>
 new CollectionPeriod
 {
     Period         = new Period(earning.AcademicYear, earning.CollectionPeriod),
     DataLocks      = datalocks.ToDataLocks(earning),
     Apprenticeship = apprenticeship?.ToDataMatch(),
     Ilr            = earning.ToDataMatch(),
 };
Example #16
0
        public void ReturnsAllCommitmentsWhenDisableDatalocksAreOn(ApprenticeshipModel apprenticeshipA, ApprenticeshipModel apprenticeshipB, PriceEpisode priceEpisode)
        {
            priceEpisode.EffectiveTotalNegotiatedPriceStartDate = new DateTime(1930, 8, 1);
            var apprenticeshipModels = new List <ApprenticeshipModel> {
                apprenticeshipA, apprenticeshipB
            };

            var validator = new StartDateValidator(true);
            var result    = validator.Validate(priceEpisode, apprenticeshipModels);

            result.validApprenticeships.Should().BeEquivalentTo(apprenticeshipModels);
        }
Example #17
0
        private IEnumerable <EarningEventModel> Filter(
            ApprenticeshipModel activeApprenticeship,
            IEnumerable <EarningEventModel> earnings)
        {
            var filterProviders = AllEarningsAreForSameProvider(earnings)
                ? IncludeEverythingPredicate
                : IncludeApprenticeshipPredicate(activeApprenticeship);

            return(earnings
                   .Where(FilterInMainAim)
                   .Where(filterProviders));
        }
Example #18
0
 public EmployerWithdrawn(
     long accountId,
     long accountLegalEntityId,
     ApprenticeshipModel model,
     ServiceRequest serviceRequest)
     : base(
         IncentiveApplicationStatus.EmployerWithdrawn,
         accountId,
         accountLegalEntityId,
         model,
         serviceRequest)
 {
 }
Example #19
0
        protected override void HandleUpdated(ApprenticeshipModel current, UpdatedApprenticeshipStoppedModel updated)
        {
            current.Status   = ApprenticeshipStatus.Stopped;
            current.StopDate = updated.StopDate;

            foreach (var currentApprenticeshipPriceEpisode in current.ApprenticeshipPriceEpisodes)
            {
                if (!currentApprenticeshipPriceEpisode.Removed)
                {
                    currentApprenticeshipPriceEpisode.EndDate = updated.StopDate;
                }
            }
        }
Example #20
0
 protected ApplicationWithdrawn(
     IncentiveApplicationStatus withdrawalStatus,
     long accountId,
     long accountLegalEntityId,
     ApprenticeshipModel model,
     ServiceRequest serviceRequest)
 {
     WithdrawalStatus     = withdrawalStatus;
     AccountLegalEntityId = accountLegalEntityId;
     AccountId            = accountId;
     Model          = model;
     ServiceRequest = serviceRequest;
 }
        public async Task <List <ApprenticeshipDuplicateModel> > NewApprenticeship(ApprenticeshipModel newApprenticeship)
        {
            var apprenticeship = await repository.Get(newApprenticeship.Id);

            if (apprenticeship != null)
            {
                throw new ApprenticeshipAlreadyExistsException(newApprenticeship.Id);
            }

            using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions
            {
                IsolationLevel = IsolationLevel.ReadCommitted,
            }, TransactionScopeAsyncFlowOption.Enabled))
            {
                await repository.Add(newApprenticeship);

                var duplicates = await repository.GetDuplicates(newApprenticeship.Uln);

                var providers = duplicates
                                .Select(duplicate => duplicate.Ukprn)
                                .Distinct()
                                .ToList();

                var newDuplicates = providers
                                    .Select(ukprn => new ApprenticeshipDuplicateModel
                {
                    ApprenticeshipId = newApprenticeship.Id,
                    Ukprn            = ukprn,
                    Uln = newApprenticeship.Uln
                })
                                    .ToList();

                if (!providers.Contains(newApprenticeship.Ukprn))
                {
                    newDuplicates.Add(new ApprenticeshipDuplicateModel {
                        Ukprn = newApprenticeship.Ukprn, ApprenticeshipId = newApprenticeship.Id, Uln = newApprenticeship.Uln
                    });
                    newDuplicates.AddRange(duplicates.Select(duplicate => new ApprenticeshipDuplicateModel
                    {
                        ApprenticeshipId = duplicate.ApprenticeshipId,
                        Uln   = newApprenticeship.Uln,
                        Ukprn = newApprenticeship.Ukprn
                    }));
                }

                await repository.StoreDuplicates(newDuplicates);

                scope.Complete();
                return(duplicates);
            }
        }
        protected override void UpdateHistory(ApprenticeshipModel current, UpdatedApprenticeshipResumedModel updated)
        {
            var currentPauseModel = current
                                    .ApprenticeshipPauses
                                    .OrderByDescending(x => x.PauseDate)
                                    .FirstOrDefault();

            if (currentPauseModel == null)
            {
                throw new InvalidOperationException($"Can't find any currently paused Apprenticeship with Id: {updated.ApprenticeshipId}");
            }

            currentPauseModel.ResumeDate = updated.ResumedDate;
        }
        public async Task SetUp()
        {
            await Testing.Reset();

            var apps = await Testing.Context.AddEntitiesFromJsonResource <ApprenticeshipModel>("SFA.DAS.IdentifyDataLocks.IntegrationTests.TestData.LearnerWithMultipleProviders.Apprenticeship.json");

            if (apps.Length == 0)
            {
                throw new Exception("There must be an apprenticeship to run these tests.");
            }

            apprenticeship = apps.FirstOrDefault(x => x.Status == PaymentsApprenticeshipStatus.Active);

            await Testing.Context.AddEntitiesFromJsonResource <EarningEventModel>("SFA.DAS.IdentifyDataLocks.IntegrationTests.TestData.LearnerWithMultipleProviders.EarningEvents.json");
        }
        public async Task <List <ApprenticeshipDuplicateModel> > NewApprenticeship(ApprenticeshipModel newApprenticeship)
        {
            var apprenticeship = await repository.Get(newApprenticeship.Id);

            if (apprenticeship != null)
            {
                throw new InvalidOperationException($"Cannot store new apprenticeship as it already exists. Apprenticeship id: {newApprenticeship.Id}, employer: {newApprenticeship.AccountId}, ukprn: {newApprenticeship.Ukprn}");
            }

            using (var scope = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled))
            {
                await repository.Add(newApprenticeship);

                var duplicates = await repository.GetDuplicates(newApprenticeship.Uln);

                var providers = duplicates
                                .Select(duplicate => duplicate.Ukprn)
                                .Distinct()
                                .ToList();

                var newDuplicates = providers
                                    .Select(ukprn => new ApprenticeshipDuplicateModel
                {
                    ApprenticeshipId = newApprenticeship.Id,
                    Ukprn            = ukprn,
                    Uln = newApprenticeship.Uln
                })
                                    .ToList();

                if (!providers.Contains(newApprenticeship.Ukprn))
                {
                    newDuplicates.Add(new ApprenticeshipDuplicateModel {
                        Ukprn = newApprenticeship.Ukprn, ApprenticeshipId = newApprenticeship.Id, Uln = newApprenticeship.Uln
                    });
                    newDuplicates.AddRange(duplicates.Select(duplicate => new ApprenticeshipDuplicateModel
                    {
                        ApprenticeshipId = duplicate.ApprenticeshipId,
                        Uln   = newApprenticeship.Uln,
                        Ukprn = newApprenticeship.Ukprn
                    }));
                }

                await repository.StoreDuplicates(newDuplicates);

                scope.Complete();
                return(duplicates);
            }
        }
Example #25
0
 private static DataMatch ToDataMatch(this ApprenticeshipModel apprenticeship) =>
 new DataMatch
 {
     Ukprn            = apprenticeship.Ukprn,
     Uln              = apprenticeship.Uln,
     Standard         = (short?)apprenticeship.StandardCode,
     Framework        = (short?)apprenticeship.FrameworkCode,
     Program          = (short?)apprenticeship.ProgrammeType,
     Pathway          = (short?)apprenticeship.PathwayCode,
     Cost             = apprenticeship.ApprenticeshipPriceEpisodes.Sum(y => y.Cost),
     PriceStart       = apprenticeship.ApprenticeshipPriceEpisodes.FirstOrDefault()?.StartDate,
     StoppedOn        = apprenticeship.StopDate,
     CompletionStatus = (ApprenticeshipStatus)apprenticeship.Status,
     PausedOn         = GetPausedOnDate(apprenticeship),
     ResumedOn        = GetResumedOnDate(apprenticeship),
 };
Example #26
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));
        }
    }
Example #27
0
        public void ReturnsDLock09WhenNoCommitmentsStartOnOrBeforePriceEpisode(ApprenticeshipModel apprenticeshipA, ApprenticeshipModel apprenticeshipB, PriceEpisode priceEpisode)
        {
            priceEpisode.EffectiveTotalNegotiatedPriceStartDate = new DateTime(2018, 8, 1);

            apprenticeshipA.ApprenticeshipPriceEpisodes.ForEach(x => x.Removed = true);
            apprenticeshipA.ApprenticeshipPriceEpisodes[0].StartDate           = new DateTime(2018, 9, 1);
            apprenticeshipA.ApprenticeshipPriceEpisodes[0].EndDate             = new DateTime(2019, 9, 30);
            apprenticeshipA.ApprenticeshipPriceEpisodes[0].Removed             = false;

            apprenticeshipB.ApprenticeshipPriceEpisodes.ForEach(x => x.Removed = true);
            apprenticeshipB.ApprenticeshipPriceEpisodes[0].StartDate           = new DateTime(2019, 9, 1);
            apprenticeshipB.ApprenticeshipPriceEpisodes[0].EndDate             = new DateTime(2020, 9, 30);
            apprenticeshipB.ApprenticeshipPriceEpisodes[0].Removed             = false;

            List <ApprenticeshipModel> apprenticeshipModels = new List <ApprenticeshipModel> {
                apprenticeshipA, apprenticeshipB
            };

            var validator = new StartDateValidator(false);
            var result    = validator.Validate(priceEpisode, apprenticeshipModels);

            result.validApprenticeships.Should().BeEmpty();
            result.dataLockFailures.Should().HaveCount(2);
            result.dataLockFailures.Should().ContainEquivalentOf(
                new
            {
                ApprenticeshipId = apprenticeshipA.Id,
                ApprenticeshipPriceEpisodeIds = new List <long>()
                {
                    apprenticeshipA.ApprenticeshipPriceEpisodes[0].Id
                },
                DataLockError = DataLockErrorCode.DLOCK_09,
            });

            result.dataLockFailures.Should().ContainEquivalentOf(
                new
            {
                ApprenticeshipId = apprenticeshipB.Id,
                ApprenticeshipPriceEpisodeIds = new List <long>()
                {
                    apprenticeshipB.ApprenticeshipPriceEpisodes[0].Id
                },
                DataLockError = DataLockErrorCode.DLOCK_09,
            });
        }
        public async Task StoreOnprogPayableDataLockEvents(
            IReceivedDataLockEventStore receivedDataLockEventStore,
            PayableEarningEvent payableEarningEvent,
            List <EarningPeriod> periods,
            ApprenticeshipModel apprenticeship,
            ManageReceivedDataLockEvent manageReceivedDataLockEvent)
        {
            CommonTestSetup(payableEarningEvent, periods, apprenticeship);
            await manageReceivedDataLockEvent.ProcessDataLockEvent(payableEarningEvent);

            var result = (await receivedDataLockEventStore
                          .GetDataLocks(payableEarningEvent.JobId, payableEarningEvent.Ukprn)).ToList();

            result.Should().NotBeNull();
            result.Should().HaveCount(1);
            result[0].MessageType.Should().Be(typeof(PayableEarningEvent).AssemblyQualifiedName);
            result[0].Message.Should().Be(payableEarningEvent.ToJson());
        }
        public async Task StoreValidOnprogNonPayableDataLockEvents(
            IReceivedDataLockEventStore receivedDataLockEventStore,
            EarningFailedDataLockMatching nonPayableEarningEvent,
            List <EarningPeriod> periods,
            ApprenticeshipModel apprenticeship,
            List <DataLockFailure> dataLockFailures,
            ManageReceivedDataLockEvent manageReceivedDataLockEvent)
        {
            CommonTestSetup(nonPayableEarningEvent, periods, apprenticeship, dataLockFailures);
            await manageReceivedDataLockEvent.ProcessDataLockEvent(nonPayableEarningEvent);

            var result = (await receivedDataLockEventStore
                          .GetDataLocks(nonPayableEarningEvent.JobId, nonPayableEarningEvent.Ukprn)).ToList();

            result.Should().NotBeNull();
            result.Should().HaveCount(1);
            result[0].MessageType.Should().Be(nonPayableEarningEvent.GetType().AssemblyQualifiedName);
            result[0].Message.Should().Be(nonPayableEarningEvent.ToJson());
        }
Example #30
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));
        }