diff --git a/src/SFA.DAS.LearnerData.Api.UnitTests/Controllers/LearnersController/WhenIGetById.cs b/src/SFA.DAS.LearnerData.Api.UnitTests/Controllers/LearnersController/WhenIGetById.cs index ca0189f..7f36cff 100644 --- a/src/SFA.DAS.LearnerData.Api.UnitTests/Controllers/LearnersController/WhenIGetById.cs +++ b/src/SFA.DAS.LearnerData.Api.UnitTests/Controllers/LearnersController/WhenIGetById.cs @@ -32,7 +32,6 @@ [Greedy] Api.Controllers.ProviderLearnersController sut okResult.Should().NotBeNull(); var response = okResult.Value as GetLearnerByIdResponse; - response.Should().NotBeNull(); response.Id.Should().Be(learner.Id); response.Uln.Should().Be(learner.Uln); @@ -47,7 +46,6 @@ [Greedy] Api.Controllers.ProviderLearnersController sut response.EpaoPrice.Should().Be(learner.EpaoPrice); response.TrainingPrice.Should().Be(learner.TrainingPrice); response.AgreementId.Should().Be(learner.AgreementId); - response.StandardCode.Should().Be(learner.StandardCode); response.TrainingCode.Should().Be(learner.TrainingCode); response.TrainingName.Should().Be(learner.TrainingName); response.LearningType.Should().Be(learner.LearningType); diff --git a/src/SFA.DAS.LearnerData.Api.UnitTests/Controllers/LearnersController/WhenIGetCourseCodesByUkprn.cs b/src/SFA.DAS.LearnerData.Api.UnitTests/Controllers/LearnersController/WhenIGetCourseCodesByUkprn.cs deleted file mode 100644 index 271a8cd..0000000 --- a/src/SFA.DAS.LearnerData.Api.UnitTests/Controllers/LearnersController/WhenIGetCourseCodesByUkprn.cs +++ /dev/null @@ -1,34 +0,0 @@ -using AutoFixture.NUnit3; -using FluentAssertions; -using MediatR; -using Microsoft.AspNetCore.Mvc; -using Moq; -using NUnit.Framework; -using SFA.DAS.LearnerData.Application.Queries.GetCourseCodesByUkprn; -using SFA.DAS.Testing.AutoFixture; - -namespace SFA.DAS.LearnerData.Api.UnitTests.Controllers.LearnersController; - -public class WhenIGetCourseCodesByUkprn -{ - [Test, MoqAutoData] - public async Task Then_Ok_Response_Is_Returned_When_Course_Codes_Returned( - long ukprn, - GetCourseCodesByUkprnResult queryResult, - [Frozen] Mock sender, - [Greedy] Api.Controllers.ProviderLearnersController sut) - { - sender - .Setup(x => x.Send(It.Is(ctx => ctx.Ukprn == ukprn), It.IsAny())).ReturnsAsync(queryResult) - .Verifiable(); - - var result = await sut.GetCourseCodesByUkprn(ukprn) as OkObjectResult; - - result.Should().NotBeNull(); - - var response = result.Value as GetCourseCodesByUkprnResult; - response.Should().BeEquivalentTo(queryResult); - - sender.Verify(); - } -} \ No newline at end of file diff --git a/src/SFA.DAS.LearnerData.Api.UnitTests/Controllers/LearnersController/WhenISave.cs b/src/SFA.DAS.LearnerData.Api.UnitTests/Controllers/LearnersController/WhenISave.cs index 697e029..dacf3c9 100644 --- a/src/SFA.DAS.LearnerData.Api.UnitTests/Controllers/LearnersController/WhenISave.cs +++ b/src/SFA.DAS.LearnerData.Api.UnitTests/Controllers/LearnersController/WhenISave.cs @@ -110,7 +110,6 @@ [Greedy] Api.Controllers.ProviderLearnersController sut && ctx.ConsumerReference == request.ConsumerReference && ctx.CorrelationId == request.CorrelationId && ctx.ReceivedDate == request.ReceivedDate - && ctx.StandardCode == request.StandardCode && ctx.TrainingCode == request.LarsCode && ctx.TrainingName == request.TrainingName && ctx.LearningType == request.LearningType @@ -164,7 +163,6 @@ [Greedy] Api.Controllers.ProviderLearnersController sut && ctx.ConsumerReference == request.ConsumerReference && ctx.CorrelationId == request.CorrelationId && ctx.ReceivedDate == request.ReceivedDate - && ctx.StandardCode == request.StandardCode && ctx.TrainingCode == request.LarsCode && ctx.TrainingName == request.TrainingName && ctx.LearningType == request.LearningType diff --git a/src/SFA.DAS.LearnerData.Api.UnitTests/Models/Responses/GetAllLearnersResponseTests.cs b/src/SFA.DAS.LearnerData.Api.UnitTests/Models/Responses/GetAllLearnersResponseTests.cs index 46ee4a8..5ebe436 100644 --- a/src/SFA.DAS.LearnerData.Api.UnitTests/Models/Responses/GetAllLearnersResponseTests.cs +++ b/src/SFA.DAS.LearnerData.Api.UnitTests/Models/Responses/GetAllLearnersResponseTests.cs @@ -53,7 +53,7 @@ List resultItems firstResponseItem.ConsumerReference.Should().Be(firstResultItem.ConsumerReference); firstResponseItem.CorrelationId.Should().Be(firstResultItem.CorrelationId); firstResponseItem.ReceivedDate.Should().Be(firstResultItem.ReceivedDate); - firstResponseItem.StandardCode.Should().Be(firstResultItem.StandardCode); + firstResponseItem.TrainingCode.Should().Be(firstResultItem.TrainingCode); firstResponseItem.IsFlexiJob.Should().Be(firstResultItem.IsFlexiJob); firstResponseItem.PlannedOTJTrainingHours.Should().Be(firstResultItem.PlannedOTJTrainingHours); } diff --git a/src/SFA.DAS.LearnerData.Api/Controllers/ProviderLearnersController.cs b/src/SFA.DAS.LearnerData.Api/Controllers/ProviderLearnersController.cs index d9258f6..9d22a7e 100644 --- a/src/SFA.DAS.LearnerData.Api/Controllers/ProviderLearnersController.cs +++ b/src/SFA.DAS.LearnerData.Api/Controllers/ProviderLearnersController.cs @@ -7,7 +7,6 @@ using SFA.DAS.LearnerData.Api.Models.Responses; using SFA.DAS.LearnerData.Application.Commands.AssignApprenticeshipId; using SFA.DAS.LearnerData.Application.Commands.SaveLearner; -using SFA.DAS.LearnerData.Application.Queries.GetCourseCodesByUkprn; using SFA.DAS.LearnerData.Application.Queries.GetLearnerById; using SFA.DAS.LearnerData.Application.Queries.GetSearch; using SFA.DAS.LearnerData.Services; @@ -67,7 +66,6 @@ public async Task Save(long ukprn, long uln, [FromBody] SaveLearn ConsumerReference = request.ConsumerReference, CorrelationId = request.CorrelationId, ReceivedDate = request.ReceivedDate, - StandardCode = request.StandardCode, TrainingCode = request.LarsCode, TrainingName = request.TrainingName, LearningType = request.LearningType.Value, @@ -135,16 +133,4 @@ public async Task PatchApprenticeshipId(long ukprn, long id, [Fro return Ok(); } - - [HttpGet] - [ProducesResponseType((int)HttpStatusCode.OK)] - [Route("coursecodes")] - public async Task GetCourseCodesByUkprn(long ukprn) - { - var query = new GetCourseCodesByUkprnQuery(ukprn); - - var result = await sender.Send(query); - - return Ok(result); - } } \ No newline at end of file diff --git a/src/SFA.DAS.LearnerData.Api/Models/Requests/SaveLearnerRequest.cs b/src/SFA.DAS.LearnerData.Api/Models/Requests/SaveLearnerRequest.cs index 5be91fd..c2484e3 100644 --- a/src/SFA.DAS.LearnerData.Api/Models/Requests/SaveLearnerRequest.cs +++ b/src/SFA.DAS.LearnerData.Api/Models/Requests/SaveLearnerRequest.cs @@ -17,7 +17,6 @@ public record SaveLearnerRequest public int EpaoPrice { get; set; } public int TrainingPrice { get; set; } public string? AgreementId { get; set; } - public int StandardCode { get; set; } public string? LarsCode { get; set; } public string? TrainingName { get; set; } public LearningType? LearningType { get; set; } diff --git a/src/SFA.DAS.LearnerData.Api/Models/Responses/GetAllLearnersResponse.cs b/src/SFA.DAS.LearnerData.Api/Models/Responses/GetAllLearnersResponse.cs index 50fd41f..da2e3a2 100644 --- a/src/SFA.DAS.LearnerData.Api/Models/Responses/GetAllLearnersResponse.cs +++ b/src/SFA.DAS.LearnerData.Api/Models/Responses/GetAllLearnersResponse.cs @@ -34,7 +34,6 @@ public static GetAllLearnersResponse MapFrom(GetAllLearnersResult result) ConsumerReference = item.ConsumerReference, CorrelationId = item.CorrelationId, ReceivedDate = item.ReceivedDate, - StandardCode = item.StandardCode, TrainingCode = item.TrainingCode, TrainingName = item.TrainingName, LearningType = item.LearningType?.GetEnumDescription(), @@ -70,7 +69,6 @@ public class GetAllLearnersResponseItem public string ConsumerReference { get; set; } = string.Empty; public Guid CorrelationId { get; set; } public DateTime ReceivedDate { get; set; } - public int StandardCode { get; set; } public string? TrainingCode { get; set; } public string? TrainingName { get; set; } public string? LearningType { get; set; } diff --git a/src/SFA.DAS.LearnerData.Api/Models/Responses/GetLearnerByIdResponse.cs b/src/SFA.DAS.LearnerData.Api/Models/Responses/GetLearnerByIdResponse.cs index 96fad42..424f523 100644 --- a/src/SFA.DAS.LearnerData.Api/Models/Responses/GetLearnerByIdResponse.cs +++ b/src/SFA.DAS.LearnerData.Api/Models/Responses/GetLearnerByIdResponse.cs @@ -21,7 +21,6 @@ public record GetLearnerByIdResponse : LearnerResponse public int EpaoPrice { get; set; } public int TrainingPrice { get; set; } public string? AgreementId { get; set; } - public int StandardCode { get; set; } public string? TrainingCode { get; set; } public string? TrainingName { get; set; } @@ -57,7 +56,6 @@ public static GetLearnerByIdResponse MapFrom(GetLearnerByIdResult result) ConsumerReference = result.ConsumerReference, CorrelationId = result.CorrelationId, ReceivedDate = result.ReceivedDate, - StandardCode = result.StandardCode, TrainingCode = result.TrainingCode, TrainingName = result.TrainingName, LearningType = result.LearningType, diff --git a/src/SFA.DAS.LearnerData.Api/Models/Responses/GetSearchResponse.cs b/src/SFA.DAS.LearnerData.Api/Models/Responses/GetSearchResponse.cs index 6c0cf52..658b223 100644 --- a/src/SFA.DAS.LearnerData.Api/Models/Responses/GetSearchResponse.cs +++ b/src/SFA.DAS.LearnerData.Api/Models/Responses/GetSearchResponse.cs @@ -1,6 +1,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Converters; using SFA.DAS.LearnerData.Application.Queries.GetSearch; +using SFA.DAS.LearnerData.Data.Entities; using SFA.DAS.LearnerData.Extensions; using SFA.DAS.LearnerData.Messages; @@ -9,12 +10,14 @@ namespace SFA.DAS.LearnerData.Api.Models.Responses; public record GetSearchResponse : PagedResponse { public DateTime? LastSubmissionDate { get; set; } - + public List Courses { get; set; } = []; + public static GetSearchResponse MapFrom(GetSearchResult result) { return new GetSearchResponse { LastSubmissionDate = result.LastSubmissionDate, + Courses = result.Courses, Data = result.Items.Select(item => new GetSearchResponseItem { Id = item.Id, @@ -36,7 +39,6 @@ public static GetSearchResponse MapFrom(GetSearchResult result) ConsumerReference = item.ConsumerReference, CorrelationId = item.CorrelationId, ReceivedDate = item.ReceivedDate, - StandardCode = item.StandardCode, TrainingCode = item.TrainingCode, TrainingName = item.TrainingName, LearningType = item.LearningType, @@ -66,7 +68,6 @@ public record GetSearchResponseItem : LearnerResponse public int EpaoPrice { get; set; } public int TrainingPrice { get; set; } public string? AgreementId { get; set; } - public int StandardCode { get; set; } public string? TrainingCode { get; set; } public string? TrainingName { get; set; } diff --git a/src/SFA.DAS.LearnerData.Database/PostDeployment/Script.PostDeployment.sql b/src/SFA.DAS.LearnerData.Database/PostDeployment/Script.PostDeployment.sql index 58a0dd7..eef25e4 100644 --- a/src/SFA.DAS.LearnerData.Database/PostDeployment/Script.PostDeployment.sql +++ b/src/SFA.DAS.LearnerData.Database/PostDeployment/Script.PostDeployment.sql @@ -14,19 +14,4 @@ Post-Deployment Script Template IF OBJECT_ID('dbo.Learner', 'U') IS NOT NULL BEGIN DROP TABLE dbo.Learner; -END - --- Migrate existing TrainingCode data from StandardCode -UPDATE dbo.LearnerData SET - TrainingCode = CAST(StandardCode AS NVARCHAR(20)) -WHERE TrainingCode IS NULL; - --- update LearningType for existing records - FoundationApprenticeship -UPDATE dbo.LearnerData SET - LearningType = 1 -WHERE LearningType IS NULL AND TrainingCode in ('805','806','807','808','809','810','811'); - --- update LearningType for existing records - Apprenticeship -UPDATE dbo.LearnerData SET - LearningType = 0 -WHERE LearningType IS NULL; \ No newline at end of file +END \ No newline at end of file diff --git a/src/SFA.DAS.LearnerData.Database/Tables/LearnerData.sql b/src/SFA.DAS.LearnerData.Database/Tables/LearnerData.sql index 46f36ac..06d2e2a 100644 --- a/src/SFA.DAS.LearnerData.Database/Tables/LearnerData.sql +++ b/src/SFA.DAS.LearnerData.Database/Tables/LearnerData.sql @@ -13,7 +13,6 @@ CREATE TABLE [dbo].[LearnerData]( [EpaoPrice] [int] NOT NULL, [TrainingPrice] [int] NOT NULL, [AgreementId] [nvarchar](20) NULL, - [StandardCode] [int] NOT NULL, [TrainingCode] [nvarchar](20) NULL, [TrainingName] [nvarchar](126) NULL, [LearningType] [tinyint] NULL, diff --git a/src/SFA.DAS.LearnerData.Messages/ChangeSummary.cs b/src/SFA.DAS.LearnerData.Messages/ChangeSummary.cs index 4f9ecf8..c2f4253 100644 --- a/src/SFA.DAS.LearnerData.Messages/ChangeSummary.cs +++ b/src/SFA.DAS.LearnerData.Messages/ChangeSummary.cs @@ -20,7 +20,6 @@ public enum ChangeType PlannedEndDateChange, EpaoPriceChange, TrainingPriceChange, - StandardCodeChange, TrainingCodeChange, LearningTypeChange, IsFlexiJob @@ -88,13 +87,6 @@ public class TrainingPriceChange : IChange public int? NewValue { get; init; } } -public class StandardCodeChange : IChange -{ - public ChangeType ChangeType => ChangeType.StandardCodeChange; - public int? OldValue { get; init; } - public int? NewValue { get; init; } -} - public class TrainingCodeChange : IChange { public ChangeType ChangeType => ChangeType.TrainingCodeChange; @@ -141,7 +133,6 @@ public class ChangeJsonConverter : JsonConverter ChangeType.PlannedEndDateChange => JsonSerializer.Deserialize(root.GetRawText(), options), ChangeType.EpaoPriceChange => JsonSerializer.Deserialize(root.GetRawText(), options), ChangeType.TrainingPriceChange => JsonSerializer.Deserialize(root.GetRawText(), options), - ChangeType.StandardCodeChange => JsonSerializer.Deserialize(root.GetRawText(), options), ChangeType.IsFlexiJob => JsonSerializer.Deserialize(root.GetRawText(), options), _ => throw new JsonException($"Unknown change type: {changeType}") }; diff --git a/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetAllLearners/GetAllLearnersQueryHandlerTests.cs b/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetAllLearners/GetAllLearnersQueryHandlerTests.cs index a16af40..56e85d7 100644 --- a/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetAllLearners/GetAllLearnersQueryHandlerTests.cs +++ b/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetAllLearners/GetAllLearnersQueryHandlerTests.cs @@ -6,6 +6,7 @@ using SFA.DAS.LearnerData.Data; using SFA.DAS.LearnerData.Data.Entities; using SFA.DAS.LearnerData.Data.Repositories; +using SFA.DAS.LearnerData.Extensions; using SFA.DAS.Testing.AutoFixture; namespace SFA.DAS.LearnerData.UnitTests.Application.Queries.GetAllLearners; @@ -70,7 +71,6 @@ GetAllLearnersQueryHandler sut firstResultItem.ConsumerReference.Should().Be(firstLearner.ConsumerReference); firstResultItem.CorrelationId.Should().Be(firstLearner.CorrelationId); firstResultItem.ReceivedDate.Should().Be(firstLearner.ReceivedDate); - firstResultItem.StandardCode.Should().Be(firstLearner.StandardCode); firstResultItem.TrainingCode.Should().Be(firstLearner.TrainingCode); firstResultItem.TrainingName.Should().Be(firstLearner.TrainingName); firstResultItem.LearningType.Should().Be(firstLearner.LearningType); diff --git a/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetCourseCodesByUkprn/GetCourseCodesByUkprnHandlerTests.cs b/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetCourseCodesByUkprn/GetCourseCodesByUkprnHandlerTests.cs deleted file mode 100644 index a91ce27..0000000 --- a/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetCourseCodesByUkprn/GetCourseCodesByUkprnHandlerTests.cs +++ /dev/null @@ -1,47 +0,0 @@ -using AutoFixture.NUnit3; -using FluentAssertions; -using Moq; -using NUnit.Framework; -using SFA.DAS.LearnerData.Application.Queries.GetCourseCodesByUkprn; -using SFA.DAS.LearnerData.Data.Repositories; -using SFA.DAS.Testing.AutoFixture; - -namespace SFA.DAS.LearnerData.UnitTests.Application.Queries.GetCourseCodesByUkprn; - -public class GetCourseCodesByUkprnHandlerTests -{ - [Test, MoqAutoData] - public async Task Handle_GetCourseCodesByUkprn( - GetCourseCodesByUkprnQuery query, - List courseCodes, - [Frozen] Mock repository, - GetCourseCodesByUkprnQueryHandler sut) - { - repository - .Setup(x => x.GetCourseCodesByUkprn(It.Is(t => t == query.Ukprn), - default)).ReturnsAsync(courseCodes) - .Verifiable(); - - var result = await sut.Handle(query, default); - result.Should().NotBeNull(); - result.CourseCodes.Should().BeEquivalentTo(courseCodes); - repository.Verify(); - } - - [Test, MoqAutoData] - public async Task Handle_Returns_Empty_Result_When_Nocourses_Exists( - GetCourseCodesByUkprnQuery query, - [Frozen] Mock repository, - GetCourseCodesByUkprnQueryHandler sut) - { - repository - .Setup(x => x.GetCourseCodesByUkprn(It.Is(t => t == query.Ukprn), - default)).ReturnsAsync([]) - .Verifiable(); - - var result = await sut.Handle(query, default); - result.Should().NotBeNull(); - result.CourseCodes.Count.Should().Be(0); - repository.Verify(); - } -} \ No newline at end of file diff --git a/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetLearnerById/GetLearnerByIdQueryHandlerTests.cs b/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetLearnerById/GetLearnerByIdQueryHandlerTests.cs index 44534b0..6784a1b 100644 --- a/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetLearnerById/GetLearnerByIdQueryHandlerTests.cs +++ b/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetLearnerById/GetLearnerByIdQueryHandlerTests.cs @@ -40,7 +40,6 @@ GetLearnerByIdQueryHandler sut result.EpaoPrice.Should().Be(learner.EpaoPrice); result.TrainingPrice.Should().Be(learner.TrainingPrice); result.AgreementId.Should().Be(learner.AgreementId); - result.StandardCode.Should().Be(learner.StandardCode); result.TrainingCode.Should().Be(learner.TrainingCode); result.TrainingName.Should().Be(learner.TrainingName); result.LearningType.Should().Be(learner.LearningType); diff --git a/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetSearch/GetSearchQueryHandlerTests.cs b/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetSearch/GetSearchQueryHandlerTests.cs index 99e2026..205e437 100644 --- a/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetSearch/GetSearchQueryHandlerTests.cs +++ b/src/SFA.DAS.LearnerData.UnitTests/Application/Queries/GetSearch/GetSearchQueryHandlerTests.cs @@ -17,6 +17,7 @@ public async Task Handle_GetForProvider_When_Learners_Exist( GetSearchQuery query, PagedResult learners, DateTime? lastSubmissionDate, + List courses, [Frozen] Mock repository, GetSearchQueryHandler sut ) @@ -35,6 +36,10 @@ GetSearchQueryHandler sut .Setup(x => x.GetLastSubmissionDate(query.UkPrn, It.IsAny())).ReturnsAsync(lastSubmissionDate) .Verifiable(); + repository + .Setup(x => x.GetCourseList(query.UkPrn, query.ExcludeApproved, query.MaxStartDate, query.ExcludeUlns, It.IsAny())).ReturnsAsync(courses) + .Verifiable(); + var result = await sut.Handle(query, CancellationToken.None); result.Should().NotBeNull(); result.Items.Should().BeEquivalentTo(learners.Data, options => options.ExcludingMissingMembers()); @@ -43,6 +48,7 @@ GetSearchQueryHandler sut result.PageSize.Should().Be(query.PageSize); result.TotalItems.Should().Be(learners.TotalItems); result.LastSubmissionDate.Should().Be(lastSubmissionDate); + result.Courses.Should().BeEquivalentTo(courses); repository.Verify(); } diff --git a/src/SFA.DAS.LearnerData.UnitTests/Extensions/StringExtensionsTests.cs b/src/SFA.DAS.LearnerData.UnitTests/Extensions/StringExtensionsTests.cs new file mode 100644 index 0000000..42ef1cf --- /dev/null +++ b/src/SFA.DAS.LearnerData.UnitTests/Extensions/StringExtensionsTests.cs @@ -0,0 +1,18 @@ +using FluentAssertions; +using NUnit.Framework; +using SFA.DAS.LearnerData.Extensions; + +namespace SFA.DAS.LearnerData.UnitTests.Extensions; + +public class StringExtensionsTests +{ + [TestCase(null, 0)] + [TestCase("123", 123)] + [TestCase("X123", 0)] + public void Convert_String_ToLongOrDefault(string? input, long expectedOutput) + { + var result = input.ToLongOrDefault(); + + result.Should().Be(expectedOutput); + } +} \ No newline at end of file diff --git a/src/SFA.DAS.LearnerData.UnitTests/Repositories/WhenIGetCourseCodesByUkprn.cs b/src/SFA.DAS.LearnerData.UnitTests/Repositories/WhenIGetCourseCodesByUkprn.cs deleted file mode 100644 index b634d0c..0000000 --- a/src/SFA.DAS.LearnerData.UnitTests/Repositories/WhenIGetCourseCodesByUkprn.cs +++ /dev/null @@ -1,74 +0,0 @@ -using FluentAssertions; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Diagnostics; -using Microsoft.Extensions.Logging; -using Moq; -using NUnit.Framework; -using SFA.DAS.LearnerData.Data; -using SFA.DAS.LearnerData.Data.Entities; -using SFA.DAS.LearnerData.Data.Repositories; -using SFA.DAS.Testing.AutoFixture; - -namespace SFA.DAS.LearnerData.UnitTests.Repositories; - -public class WhenIGetCourseCodesByUkprn -{ - private LearnerRepository _repository; - private LearnerDataDbContext _dbContext; - private CancellationToken _cancellationToken; - - [SetUp] - public void Setup() - { - _dbContext = new LearnerDataDbContext(new DbContextOptionsBuilder() - .UseInMemoryDatabase(Guid.NewGuid().ToString(), b => b.EnableNullChecks(false)) - .EnableSensitiveDataLogging() - .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)) - .Options); - - _repository = new LearnerRepository(_dbContext, Mock.Of>()); - _cancellationToken = CancellationToken.None; - } - - [TearDown] - public void TearDown() - { - _dbContext.Dispose(); - } - - [Test, MoqAutoData] - public async Task Then_Returns_Empty_Result_When_No_CourseCodes_Exist( - long ukprn) - { - // Act - var result = await _repository.GetCourseCodesByUkprn(ukprn, _cancellationToken); - - // Assert - result.Should().NotBeNull(); - result.Count.Should().Be(0); - } - - [Test, MoqAutoData] - public async Task Then_Returns_CourseCodes_Give_Ukprn( - long ukprn) - { - var learners = new List() - { - new() { Ukprn = ukprn , StandardCode = 1}, - new() { Ukprn = ukprn , StandardCode = 1}, - new() { Ukprn = ukprn , StandardCode = 2}, - new() { Ukprn = ukprn , StandardCode = 3}, - }; - - learners.ForEach(t => t.Ukprn = ukprn); - _dbContext.Learners.AddRange(learners); - await _dbContext.SaveChangesAsync(); - - // Act - var result = await _repository.GetCourseCodesByUkprn(ukprn, _cancellationToken); - - // Assert - result.Should().NotBeNull(); - result.Should().BeEquivalentTo(learners.Where(t => t.Ukprn == ukprn).Select(t => t.StandardCode).Distinct()); - } -} \ No newline at end of file diff --git a/src/SFA.DAS.LearnerData.UnitTests/Repositories/WhenIGetCourseListForUkprn.cs b/src/SFA.DAS.LearnerData.UnitTests/Repositories/WhenIGetCourseListForUkprn.cs new file mode 100644 index 0000000..39dfabb --- /dev/null +++ b/src/SFA.DAS.LearnerData.UnitTests/Repositories/WhenIGetCourseListForUkprn.cs @@ -0,0 +1,111 @@ +using FluentAssertions; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Logging; +using Moq; +using NUnit.Framework; +using SFA.DAS.LearnerData.Data; +using SFA.DAS.LearnerData.Data.Entities; +using SFA.DAS.LearnerData.Data.Repositories; +using SFA.DAS.Testing.AutoFixture; + +namespace SFA.DAS.LearnerData.UnitTests.Repositories; + +public class WhenIGetCourseListForUkprn +{ + private LearnerRepository _repository; + private LearnerDataDbContext _dbContext; + private CancellationToken _cancellationToken; + + [SetUp] + public void Setup() + { + _dbContext = new LearnerDataDbContext(new DbContextOptionsBuilder() + .UseInMemoryDatabase(Guid.NewGuid().ToString(), b => b.EnableNullChecks(false)) + .EnableSensitiveDataLogging() + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)) + .Options); + + _repository = new LearnerRepository(_dbContext, Mock.Of>()); + _cancellationToken = CancellationToken.None; + } + + [TearDown] + public void TearDown() + { + _dbContext.Dispose(); + } + + [Test, MoqAutoData] + public async Task Then_Returns_Empty_Result_When_No_CourseCodes_Exist( + long ukprn, bool excludeApproved, string maxStartDate, List excludeUlns) + { + // Act + var result = await _repository.GetCourseList(ukprn, excludeApproved, maxStartDate, excludeUlns, _cancellationToken); + + // Assert + result.Should().NotBeNull(); + result.Count.Should().Be(0); + } + + [TestCase(100, true, null, null, 3)] + [TestCase(100, false, null, null, 4)] + [TestCase(100, false, null, null, 4)] + [TestCase(100, false, "2026-08-01", null, 4)] + [TestCase(100, false, null, "123456789,123456788", 3)] + public async Task Then_Returns_Courses_For_Query( + long ukprn, bool excludeApproved, string? maxStartDate, string? stringExcludeUlns, int expectedCount) + { + var excludeUlns = stringExcludeUlns == null ? new List() : stringExcludeUlns.Split(',').Select(long.Parse).ToList(); + + var learners = new List() + { + new() { Ukprn = ukprn , TrainingCode = "1", TrainingName = "Course1", StartDate = new DateTime(2027,01,01), Uln = 123456789 }, + new() { Ukprn = ukprn , TrainingCode = "1", TrainingName = "Course1", StartDate = new DateTime(2026, 01,01), Uln = 123456788 }, + new() { Ukprn = ukprn , TrainingCode = "2", TrainingName = "Course2", StartDate = new DateTime(2026,01,01)}, + new() { Ukprn = ukprn , TrainingCode = "2A", TrainingName = "Course2A", StartDate = new DateTime(2026,04,01), ApprenticeshipId = 999}, + new() { Ukprn = ukprn , TrainingCode = "3", TrainingName = "Course3", StartDate = new DateTime(2026, 01, 01)}, + new() { Ukprn = ukprn+1 , TrainingCode = "3", TrainingName = "Course3", StartDate = new DateTime(2027,01,01)}, + }; + + learners.ForEach(t => t.Ukprn = ukprn); + _dbContext.Learners.AddRange(learners); + await _dbContext.SaveChangesAsync(); + + // Act + var result = await _repository.GetCourseList(ukprn, excludeApproved, maxStartDate, excludeUlns, _cancellationToken); + + // Assert + result.Count.Should().Be(expectedCount); + } + + [Test, MoqAutoData] + public async Task Then_Returns_CourseCodes_And_Names_If_Present( + long ukprn) + { + + var learners = new List() + { + new() { Ukprn = ukprn , TrainingCode = "1", TrainingName = null, StartDate = new DateTime(2027,01,01), Uln = 123456789 }, + new() { Ukprn = ukprn , TrainingCode = "1", TrainingName = "Course1", StartDate = new DateTime(2026, 01,01), Uln = 123456788 }, + new() { Ukprn = ukprn , TrainingCode = "2", TrainingName = "Course2", StartDate = new DateTime(2026,01,01)}, + new() { Ukprn = ukprn , TrainingCode = "2A", TrainingName = "Course2A", StartDate = new DateTime(2026,04,01), ApprenticeshipId = 999}, + new() { Ukprn = ukprn , TrainingCode = "3", TrainingName = "Course3", StartDate = new DateTime(2026, 01, 01)}, + new() { Ukprn = ukprn , TrainingCode = "4", TrainingName = null, StartDate = new DateTime(2026, 01, 01)}, + new() { Ukprn = ukprn+1 , TrainingCode = "3", TrainingName = "Course3", StartDate = new DateTime(2027,01,01)}, + }; + + learners.ForEach(t => t.Ukprn = ukprn); + _dbContext.Learners.AddRange(learners); + await _dbContext.SaveChangesAsync(); + + // Act + var result = await _repository.GetCourseList(ukprn, false, null, null, _cancellationToken); + + // Assert + result.Should().NotBeNull(); + result.Count.Should().Be(5); + result.First(x => x.TrainingCode == "1").TrainingName.Should().Be("Course1"); + result.First(x => x.TrainingCode == "4").TrainingName.Should().BeNull(); + } +} \ No newline at end of file diff --git a/src/SFA.DAS.LearnerData.UnitTests/Repositories/WhenISearchExcludeUlns.cs b/src/SFA.DAS.LearnerData.UnitTests/Repositories/WhenISearchExcludeUlns.cs index 0b26906..6b3e948 100644 --- a/src/SFA.DAS.LearnerData.UnitTests/Repositories/WhenISearchExcludeUlns.cs +++ b/src/SFA.DAS.LearnerData.UnitTests/Repositories/WhenISearchExcludeUlns.cs @@ -76,7 +76,7 @@ private static Learner CreateLearner(long ukprn, long uln) => PlannedEndDate = new DateTime(2026, 7, 1), EpaoPrice = 0, TrainingPrice = 0, - StandardCode = 1, + TrainingCode = "1", ReceivedDate = DateTime.UtcNow, CorrelationId = Guid.NewGuid(), }; diff --git a/src/SFA.DAS.LearnerData.UnitTests/Services/ChangeTrackingServiceTests.cs b/src/SFA.DAS.LearnerData.UnitTests/Services/ChangeTrackingServiceTests.cs index 3c68d1d..b3ebb34 100644 --- a/src/SFA.DAS.LearnerData.UnitTests/Services/ChangeTrackingServiceTests.cs +++ b/src/SFA.DAS.LearnerData.UnitTests/Services/ChangeTrackingServiceTests.cs @@ -30,7 +30,6 @@ public void DetectChanges_WhenNoChanges_ShouldReturnEmptyChanges(ChangeTrackingS EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = DateTime.UtcNow, @@ -54,7 +53,6 @@ public void DetectChanges_WhenNoChanges_ShouldReturnEmptyChanges(ChangeTrackingS EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = existingLearner.ReceivedDate, @@ -91,7 +89,6 @@ public void DetectChanges_WhenAllFieldsChanged_ShouldReturnAllChanges(ChangeTrac EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, TrainingCode = "123", LearningType = LearningType.Apprenticeship, IsFlexiJob = false, @@ -117,7 +114,6 @@ public void DetectChanges_WhenAllFieldsChanged_ShouldReturnAllChanges(ChangeTrac EpaoPrice = 600, TrainingPrice = 16000, AgreementId = "XYZ789", - StandardCode = 456, TrainingCode = "456", LearningType = LearningType.ApprenticeshipUnit, IsFlexiJob = true, @@ -133,7 +129,7 @@ public void DetectChanges_WhenAllFieldsChanged_ShouldReturnAllChanges(ChangeTrac // Assert result.Should().NotBeNull(); result.HasLearnerChanges.Should().BeTrue(); - result.Changes.Should().HaveCount(12); + result.Changes.Should().HaveCount(11); // Verify each change type result.Changes.Should().ContainSingle(c => c.ChangeType == ChangeType.FirstNameChange); @@ -144,7 +140,6 @@ public void DetectChanges_WhenAllFieldsChanged_ShouldReturnAllChanges(ChangeTrac result.Changes.Should().ContainSingle(c => c.ChangeType == ChangeType.PlannedEndDateChange); result.Changes.Should().ContainSingle(c => c.ChangeType == ChangeType.EpaoPriceChange); result.Changes.Should().ContainSingle(c => c.ChangeType == ChangeType.TrainingPriceChange); - result.Changes.Should().ContainSingle(c => c.ChangeType == ChangeType.StandardCodeChange); result.Changes.Should().ContainSingle(c => c.ChangeType == ChangeType.TrainingCodeChange); result.Changes.Should().ContainSingle(c => c.ChangeType == ChangeType.LearningTypeChange); result.Changes.Should().ContainSingle(c => c.ChangeType == ChangeType.IsFlexiJob); @@ -172,7 +167,6 @@ public void DetectChanges_WhenOnlyNonTrackedFieldsChanged_ShouldReturnEmptyChang EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = DateTime.UtcNow, @@ -196,7 +190,6 @@ public void DetectChanges_WhenOnlyNonTrackedFieldsChanged_ShouldReturnEmptyChang EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = DateTime.UtcNow.AddDays(1), @@ -233,7 +226,6 @@ public void DetectChanges_WhenNonLearnerFieldsChanged_ShouldReturnEmptyLearnerCh EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1100, ReceivedDate = DateTime.UtcNow, @@ -257,7 +249,6 @@ public void DetectChanges_WhenNonLearnerFieldsChanged_ShouldReturnEmptyLearnerCh EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = DateTime.UtcNow.AddDays(1), @@ -295,7 +286,6 @@ public void DetectChanges_WhenSingleFieldChanged_ShouldReturnOnlyThatChange(Chan EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = DateTime.UtcNow, @@ -319,7 +309,6 @@ public void DetectChanges_WhenSingleFieldChanged_ShouldReturnOnlyThatChange(Chan EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = existingLearner.ReceivedDate, @@ -358,7 +347,6 @@ public void DetectChanges_WhenMultipleFieldsChanged_ShouldReturnAllChanges(Chang EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = DateTime.UtcNow, @@ -382,7 +370,6 @@ public void DetectChanges_WhenMultipleFieldsChanged_ShouldReturnAllChanges(Chang EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = existingLearner.ReceivedDate, @@ -428,7 +415,6 @@ public void DetectChanges_WhenNullableFieldChangedFromNullToValue_ShouldDetectCh EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = DateTime.UtcNow, @@ -452,7 +438,6 @@ public void DetectChanges_WhenNullableFieldChangedFromNullToValue_ShouldDetectCh EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = existingLearner.ReceivedDate, @@ -492,7 +477,6 @@ public void DetectChanges_WhenNullableFieldChangedFromValueToNull_ShouldDetectCh EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = DateTime.UtcNow, @@ -516,7 +500,6 @@ public void DetectChanges_WhenNullableFieldChangedFromValueToNull_ShouldDetectCh EpaoPrice = 500, TrainingPrice = 15000, AgreementId = "ABC123", - StandardCode = 123, IsFlexiJob = false, PlannedOTJTrainingHours = 1200, ReceivedDate = existingLearner.ReceivedDate, diff --git a/src/SFA.DAS.LearnerData/Application/Commands/SaveLearner/SaveLearnerNewCommand.cs b/src/SFA.DAS.LearnerData/Application/Commands/SaveLearner/SaveLearnerNewCommand.cs index 3d0938a..4f0ab1a 100644 --- a/src/SFA.DAS.LearnerData/Application/Commands/SaveLearner/SaveLearnerNewCommand.cs +++ b/src/SFA.DAS.LearnerData/Application/Commands/SaveLearner/SaveLearnerNewCommand.cs @@ -18,7 +18,6 @@ public record SaveLearnerNewCommand : IRequest public int EpaoPrice { get; set; } public int TrainingPrice { get; set; } public string? AgreementId { get; set; } - public int StandardCode { get; set; } public string TrainingCode { get; set; } public string TrainingName { get; set; } public LearningType LearningType { get; set; } diff --git a/src/SFA.DAS.LearnerData/Application/Queries/GetAll/GetForProviderQueryHandler.cs b/src/SFA.DAS.LearnerData/Application/Queries/GetAll/GetForProviderQueryHandler.cs index e0e22c1..4c3f36d 100644 --- a/src/SFA.DAS.LearnerData/Application/Queries/GetAll/GetForProviderQueryHandler.cs +++ b/src/SFA.DAS.LearnerData/Application/Queries/GetAll/GetForProviderQueryHandler.cs @@ -39,7 +39,6 @@ public async Task Handle(GetForProviderQuery request, Canc ConsumerReference = learner.ConsumerReference, CorrelationId = learner.CorrelationId, ReceivedDate = learner.ReceivedDate, - StandardCode = learner.StandardCode, IsFlexiJob = learner.IsFlexiJob, PlannedOTJTrainingHours = learner.PlannedOTJTrainingHours }).ToList() diff --git a/src/SFA.DAS.LearnerData/Application/Queries/GetAll/GetForProviderResult.cs b/src/SFA.DAS.LearnerData/Application/Queries/GetAll/GetForProviderResult.cs index 1256442..4c3f706 100644 --- a/src/SFA.DAS.LearnerData/Application/Queries/GetAll/GetForProviderResult.cs +++ b/src/SFA.DAS.LearnerData/Application/Queries/GetAll/GetForProviderResult.cs @@ -22,7 +22,6 @@ public record GetForProviderResultItem : LearnerResult public int EpaoPrice { get; set; } public int TrainingPrice { get; set; } public string? AgreementId { get; set; } - public int StandardCode { get; set; } public bool IsFlexiJob { get; set; } public int PlannedOTJTrainingHours { get; set; } public DateTime ReceivedDate { get; set; } diff --git a/src/SFA.DAS.LearnerData/Application/Queries/GetAllLearners/GetAllLearnersQueryHandler.cs b/src/SFA.DAS.LearnerData/Application/Queries/GetAllLearners/GetAllLearnersQueryHandler.cs index 4b2541c..c971b79 100644 --- a/src/SFA.DAS.LearnerData/Application/Queries/GetAllLearners/GetAllLearnersQueryHandler.cs +++ b/src/SFA.DAS.LearnerData/Application/Queries/GetAllLearners/GetAllLearnersQueryHandler.cs @@ -1,5 +1,6 @@ using MediatR; using SFA.DAS.LearnerData.Data.Repositories; +using SFA.DAS.LearnerData.Extensions; namespace SFA.DAS.LearnerData.Application.Queries.GetAllLearners; @@ -38,7 +39,6 @@ public async Task Handle(GetAllLearnersQuery request, Canc ConsumerReference = learner.ConsumerReference, CorrelationId = learner.CorrelationId, ReceivedDate = learner.ReceivedDate, - StandardCode = learner.StandardCode, TrainingCode = learner.TrainingCode, TrainingName = learner.TrainingName, LearningType = learner.LearningType, diff --git a/src/SFA.DAS.LearnerData/Application/Queries/GetAllLearners/GetAllLearnersResult.cs b/src/SFA.DAS.LearnerData/Application/Queries/GetAllLearners/GetAllLearnersResult.cs index 246ddaa..541ad22 100644 --- a/src/SFA.DAS.LearnerData/Application/Queries/GetAllLearners/GetAllLearnersResult.cs +++ b/src/SFA.DAS.LearnerData/Application/Queries/GetAllLearners/GetAllLearnersResult.cs @@ -20,7 +20,6 @@ public record GetAllLearnersResultItem : LearnerResult public int EpaoPrice { get; set; } public int TrainingPrice { get; set; } public string? AgreementId { get; set; } - public int StandardCode { get; set; } public string? TrainingCode { get; set; } public string? TrainingName { get; set; } public LearningType? LearningType { get; set; } diff --git a/src/SFA.DAS.LearnerData/Application/Queries/GetCourseCodesByUkprn/GetCourseCodesByUkprnQueryHandler.cs b/src/SFA.DAS.LearnerData/Application/Queries/GetCourseCodesByUkprn/GetCourseCodesByUkprnQueryHandler.cs deleted file mode 100644 index 90d1038..0000000 --- a/src/SFA.DAS.LearnerData/Application/Queries/GetCourseCodesByUkprn/GetCourseCodesByUkprnQueryHandler.cs +++ /dev/null @@ -1,19 +0,0 @@ -using MediatR; -using SFA.DAS.LearnerData.Data.Repositories; - -namespace SFA.DAS.LearnerData.Application.Queries.GetCourseCodesByUkprn; - -public record GetCourseCodesByUkprnQuery(long Ukprn) : IRequest; - -public class GetCourseCodesByUkprnQueryHandler(ILearnerRepository repository) : IRequestHandler -{ - public async Task Handle(GetCourseCodesByUkprnQuery request, CancellationToken cancellationToken) - { - var codes = await repository.GetCourseCodesByUkprn(request.Ukprn, cancellationToken); - - return new GetCourseCodesByUkprnResult() - { - CourseCodes = codes - }; - } -} \ No newline at end of file diff --git a/src/SFA.DAS.LearnerData/Application/Queries/GetCourseCodesByUkprn/GetCourseCodesByUkprnResult.cs b/src/SFA.DAS.LearnerData/Application/Queries/GetCourseCodesByUkprn/GetCourseCodesByUkprnResult.cs deleted file mode 100644 index b5c0cc9..0000000 --- a/src/SFA.DAS.LearnerData/Application/Queries/GetCourseCodesByUkprn/GetCourseCodesByUkprnResult.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace SFA.DAS.LearnerData.Application.Queries.GetCourseCodesByUkprn; - -public class GetCourseCodesByUkprnResult -{ - public List CourseCodes { get; set; } -} \ No newline at end of file diff --git a/src/SFA.DAS.LearnerData/Application/Queries/GetLearnerById/GetLearnerByIdQueryHandler.cs b/src/SFA.DAS.LearnerData/Application/Queries/GetLearnerById/GetLearnerByIdQueryHandler.cs index 98ddbfe..e51de19 100644 --- a/src/SFA.DAS.LearnerData/Application/Queries/GetLearnerById/GetLearnerByIdQueryHandler.cs +++ b/src/SFA.DAS.LearnerData/Application/Queries/GetLearnerById/GetLearnerByIdQueryHandler.cs @@ -38,7 +38,6 @@ public async Task Handle(GetLearnerByIdQuery request, Canc ConsumerReference = learner.ConsumerReference, CorrelationId = learner.CorrelationId, ReceivedDate = learner.ReceivedDate, - StandardCode = learner.StandardCode, TrainingCode = learner.TrainingCode, TrainingName = learner.TrainingName, LearningType = learner.LearningType, diff --git a/src/SFA.DAS.LearnerData/Application/Queries/GetLearnerById/GetLearnerByIdResult.cs b/src/SFA.DAS.LearnerData/Application/Queries/GetLearnerById/GetLearnerByIdResult.cs index 6e797f0..51f2e09 100644 --- a/src/SFA.DAS.LearnerData/Application/Queries/GetLearnerById/GetLearnerByIdResult.cs +++ b/src/SFA.DAS.LearnerData/Application/Queries/GetLearnerById/GetLearnerByIdResult.cs @@ -18,7 +18,6 @@ public record GetLearnerByIdResult : LearnerResult public int EpaoPrice { get; set; } public int TrainingPrice { get; set; } public string? AgreementId { get; set; } - public int StandardCode { get; set; } public string? TrainingCode { get; set; } public string? TrainingName { get; set; } public LearningType? LearningType { get; set; } diff --git a/src/SFA.DAS.LearnerData/Application/Queries/GetSearch/GetSearchQueryHandler.cs b/src/SFA.DAS.LearnerData/Application/Queries/GetSearch/GetSearchQueryHandler.cs index b695d36..090151c 100644 --- a/src/SFA.DAS.LearnerData/Application/Queries/GetSearch/GetSearchQueryHandler.cs +++ b/src/SFA.DAS.LearnerData/Application/Queries/GetSearch/GetSearchQueryHandler.cs @@ -63,11 +63,13 @@ public async Task Handle(GetSearchQuery request, CancellationTo DateTime? lastSubmissionDate = null; lastSubmissionDate = await repository.GetLastSubmissionDate(request.UkPrn, cancellationToken); + var courses = await repository.GetCourseList(request.UkPrn, request.ExcludeApproved, request.MaxStartDate, request.ExcludeUlns, cancellationToken); return new GetSearchResult { - LastSubmissionDate = lastSubmissionDate, - Items = result.Data.Select(learner => new GetByAcademicYearResultItem + LastSubmissionDate = lastSubmissionDate, + Courses = courses, + Items = result.Data.Select(learner => new GetByAcademicYearResultItem { Id = learner.Id, CreatedDate = learner.CreatedDate, @@ -88,7 +90,6 @@ public async Task Handle(GetSearchQuery request, CancellationTo ConsumerReference = learner.ConsumerReference, CorrelationId = learner.CorrelationId, ReceivedDate = learner.ReceivedDate, - StandardCode = learner.StandardCode, TrainingCode = learner.TrainingCode, TrainingName = learner.TrainingName, LearningType = learner.LearningType, diff --git a/src/SFA.DAS.LearnerData/Application/Queries/GetSearch/GetSearchResult.cs b/src/SFA.DAS.LearnerData/Application/Queries/GetSearch/GetSearchResult.cs index 92b7bc1..1d5e882 100644 --- a/src/SFA.DAS.LearnerData/Application/Queries/GetSearch/GetSearchResult.cs +++ b/src/SFA.DAS.LearnerData/Application/Queries/GetSearch/GetSearchResult.cs @@ -1,3 +1,4 @@ +using SFA.DAS.LearnerData.Data.Entities; using SFA.DAS.LearnerData.Messages; namespace SFA.DAS.LearnerData.Application.Queries.GetSearch; @@ -5,6 +6,7 @@ namespace SFA.DAS.LearnerData.Application.Queries.GetSearch; public record GetSearchResult : PagedQueryResult { public DateTime? LastSubmissionDate { get; set; } + public List Courses { get; set; } = []; } public record GetByAcademicYearResultItem : LearnerResult @@ -23,7 +25,6 @@ public record GetByAcademicYearResultItem : LearnerResult public int EpaoPrice { get; set; } public int TrainingPrice { get; set; } public string? AgreementId { get; set; } - public int StandardCode { get; set; } public string? TrainingCode { get; set; } public string? TrainingName { get; set; } public LearningType? LearningType { get; set; } diff --git a/src/SFA.DAS.LearnerData/Data/Entities/Course.cs b/src/SFA.DAS.LearnerData/Data/Entities/Course.cs new file mode 100644 index 0000000..af65204 --- /dev/null +++ b/src/SFA.DAS.LearnerData/Data/Entities/Course.cs @@ -0,0 +1,7 @@ +namespace SFA.DAS.LearnerData.Data.Entities; + +public class Course +{ + public string TrainingCode { get; set; } + public string? TrainingName { get; set; } +} \ No newline at end of file diff --git a/src/SFA.DAS.LearnerData/Data/Entities/Learner.cs b/src/SFA.DAS.LearnerData/Data/Entities/Learner.cs index 73de901..76c4dd3 100644 --- a/src/SFA.DAS.LearnerData/Data/Entities/Learner.cs +++ b/src/SFA.DAS.LearnerData/Data/Entities/Learner.cs @@ -18,8 +18,7 @@ public class Learner : Entity public int EpaoPrice { get; set; } public int TrainingPrice { get; set; } public string? AgreementId { get; set; } - public int StandardCode { get; set; } - public string? TrainingCode { get; set; } + public string TrainingCode { get; set; } public string? TrainingName { get; set; } public LearningType? LearningType { get; set; } public bool IsFlexiJob { get; set; } @@ -49,7 +48,6 @@ public static Learner From(SaveLearnerNewCommand command) ConsumerReference = command.ConsumerReference, CorrelationId = command.CorrelationId, ReceivedDate = command.ReceivedDate, - StandardCode = command.StandardCode, TrainingCode = command.TrainingCode, TrainingName = command.TrainingName, LearningType = command.LearningType, diff --git a/src/SFA.DAS.LearnerData/Data/Repositories/LearnerRepository.cs b/src/SFA.DAS.LearnerData/Data/Repositories/LearnerRepository.cs index d79d369..943589c 100644 --- a/src/SFA.DAS.LearnerData/Data/Repositories/LearnerRepository.cs +++ b/src/SFA.DAS.LearnerData/Data/Repositories/LearnerRepository.cs @@ -12,26 +12,18 @@ namespace SFA.DAS.LearnerData.Data.Repositories; public interface ILearnerRepository { Task GetById(long id, CancellationToken cancellationToken); - Task Get(long ukPrn, long uln, CancellationToken cancellationToken); - Task> GetForProvider(long ukprn, CancellationToken cancellationToken); - Task> Search(long ukprn, int page, int? pageSize, int limit, int offset, string sortColumn, bool sortDescending, string filter, bool excludeApproved, int? startMonth, int startYear, string maxStartDate, List excludeUlns, string courseCode, LearningType? learningType, CancellationToken cancellationToken); Task> GetAllLearners(int page, int? pageSize, int limit, int offset, bool excludeApproved, CancellationToken cancellationToken); - Task GetLastSubmissionDate(long ukprn, CancellationToken cancellationToken); - Task AddLearner(SaveLearnerNewCommand request, CancellationToken cancellationToken); - Task UpdateLearner(Learner existingLearner, SaveLearnerNewCommand request, CancellationToken cancellationToken); - Task AssignApprenticeshipId(AssignApprenticeshipIdCommand request, CancellationToken cancellationToken); - - Task> GetCourseCodesByUkprn(long ukprn, CancellationToken cancellationToken); + Task> GetCourseList(long ukprn, bool excludeApproved, string maxStartDate, List excludeUlns, CancellationToken cancellationToken); } public class LearnerRepository(LearnerDataDbContext dbContext, ILogger logger) : ILearnerRepository @@ -70,11 +62,15 @@ public async Task> Search(long ukprn, int page, int? pageSi query = query.Where(x => !excludeUlns.Contains(x.Uln)); } + query = ExcludeUlnsFromQuery(query, excludeUlns); + if (excludeApproved) { query = query.Where(x => x.ApprenticeshipId == null); } + query = ExcludeLearnerAfterStartDate(query, maxStartDate); + if (!string.IsNullOrEmpty(filter)) { query = query.Where(x => x.LastName.Contains(filter) || x.FirstName.Contains(filter) || x.Uln.ToString() == filter); @@ -186,7 +182,7 @@ private static string GetOrderNamesByField(string fieldName, bool sortDescending nameof(Learner.PlannedOTJTrainingHours) => $"PlannedOTJTrainingHours {sort}", nameof(Learner.PlannedEndDate) => $"PlannedEndDate {sort}", nameof(Learner.ReceivedDate) => $"ReceivedDate {sort}", - nameof(Learner.StandardCode) => $"StandardCode {sort}", + nameof(Learner.TrainingCode) => $"TrainingCode {sort}", nameof(Learner.StartDate) => $"StartDate {sort}, Firstname {sort}, Lastname {sort}, ULN {sort}", nameof(Learner.TrainingPrice) => $"TrainingPrice {sort}", nameof(Learner.Uln) => $"Uln {sort}", @@ -239,7 +235,6 @@ public async Task UpdateLearner(Learner existingL existingLearner.ConsumerReference = request.ConsumerReference; existingLearner.CorrelationId = request.CorrelationId; existingLearner.ReceivedDate = request.ReceivedDate; - existingLearner.StandardCode = request.StandardCode; existingLearner.TrainingCode = request.TrainingCode; existingLearner.TrainingName = request.TrainingName; existingLearner.LearningType = request.LearningType; @@ -272,9 +267,41 @@ public async Task AssignApprenticeshipId(AssignApprenticeshipIdCommand request, await dbContext.SaveChangesAsync(cancellationToken); } - public async Task> GetCourseCodesByUkprn(long ukprn, CancellationToken cancellationToken) + public async Task> GetCourseList(long ukprn, bool excludeApproved, string maxStartDate, List excludeUlns, CancellationToken cancellationToken) + { + var query = dbContext.Learners + .AsNoTracking() + .Where(x => x.Ukprn == ukprn); + + query = ExcludeUlnsFromQuery(query, excludeUlns); + + if (excludeApproved) + { + query = query.Where(x => x.ApprenticeshipId == null); + } + + query = ExcludeLearnerAfterStartDate(query, maxStartDate); + + return await query.GroupBy(l => l.TrainingCode).Select(g => new Course { TrainingCode = g.Key, TrainingName = g.Max(t => t.TrainingName) }).ToListAsync(cancellationToken); + } + + private static IQueryable ExcludeUlnsFromQuery(IQueryable query, List excludeUlns) + { + query = query.Where(x => !excludeUlns.Contains(x.Uln)); + return query; + } + + private static IQueryable ExcludeLearnerAfterStartDate(IQueryable query, string maxStartDate) { - return await dbContext.Learners.AsNoTracking().Where(t => t.Ukprn == ukprn). - Select(t => t.StandardCode).Distinct().ToListAsync(cancellationToken); + if (!string.IsNullOrEmpty(maxStartDate)) + { + DateTime maxDate; + if (DateTime.TryParse(maxStartDate, CultureInfo.InvariantCulture, out maxDate)) + { + query = query.Where(x => x.StartDate < maxDate); + } + } + return query; } + } \ No newline at end of file diff --git a/src/SFA.DAS.LearnerData/Extensions/StringExtensions.cs b/src/SFA.DAS.LearnerData/Extensions/StringExtensions.cs new file mode 100644 index 0000000..62c482e --- /dev/null +++ b/src/SFA.DAS.LearnerData/Extensions/StringExtensions.cs @@ -0,0 +1,12 @@ +namespace SFA.DAS.LearnerData.Extensions; + +public static class StringExtensions +{ + public static long ToLongOrDefault(this string? input) + { + if (input != null && long.TryParse(input, out long result)) + return result; + + return 0; + } +} \ No newline at end of file diff --git a/src/SFA.DAS.LearnerData/Services/ChangeTrackingService.cs b/src/SFA.DAS.LearnerData/Services/ChangeTrackingService.cs index 1e60abb..56fc765 100644 --- a/src/SFA.DAS.LearnerData/Services/ChangeTrackingService.cs +++ b/src/SFA.DAS.LearnerData/Services/ChangeTrackingService.cs @@ -49,11 +49,6 @@ public ChangeSummary DetectChanges(Learner existingLearner, Learner newLearner) changes.Add(new TrainingPriceChange { OldValue = existingLearner.TrainingPrice, NewValue = newLearner.TrainingPrice }); } - if (!Equals(existingLearner.StandardCode, newLearner.StandardCode)) - { - changes.Add(new StandardCodeChange { OldValue = existingLearner.StandardCode, NewValue = newLearner.StandardCode }); - } - if (!Equals(existingLearner.TrainingCode, newLearner.TrainingCode)) { changes.Add(new TrainingCodeChange { OldValue = existingLearner.TrainingCode, NewValue = newLearner.TrainingCode });