diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2.Api.Types/Responses/GetApprenticeshipStatisticsResponse.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.Api.Types/Responses/GetApprenticeshipStatisticsResponse.cs new file mode 100644 index 0000000000..90863987b1 --- /dev/null +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.Api.Types/Responses/GetApprenticeshipStatisticsResponse.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SFA.DAS.CommitmentsV2.Api.Types.Responses +{ + public class GetApprenticeshipStatisticsResponse + { + public long Approved { get; set; } + public long Paused { get; set; } + public long Stopped { get; set; } + } +} diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2.Api.UnitTests/Controllers/ApprenticeshipStatisticsControllerTests.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.Api.UnitTests/Controllers/ApprenticeshipStatisticsControllerTests.cs new file mode 100644 index 0000000000..c6206e9d9e --- /dev/null +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.Api.UnitTests/Controllers/ApprenticeshipStatisticsControllerTests.cs @@ -0,0 +1,101 @@ +using FluentAssertions; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Controllers; +using SFA.DAS.CommitmentsV2.Api.Types.Responses; +using SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatistics; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using System.Threading; +using System.Threading.Tasks; +using AutoFixture; + +namespace SFA.DAS.CommitmentsV2.Api.UnitTests.Controllers +{ + [TestFixture] + public class ApprenticeshipStatisticsControllerTests + { + private Fixture _fixture; + private int _lastNumberOfDays; + private Mock _mediatorMock; + private Mock _modelMapperMock; + private GetApprenticeshipStatisticsQueryResult _getApprenticeshipStatisticsQueryResult; + private GetApprenticeshipStatisticsResponse _getApprenticeshipStatisticsResponse; + private ApprenticeshipStatisticsController _sut; + + [SetUp] + public void SetUp() + { + _fixture = new Fixture(); + _lastNumberOfDays = _fixture.Create(); + _mediatorMock = new Mock(); + _modelMapperMock = new Mock(); + _getApprenticeshipStatisticsQueryResult = _fixture.Freeze(); + _getApprenticeshipStatisticsResponse = _fixture.Freeze(); + + _sut = new ApprenticeshipStatisticsController(_mediatorMock.Object, _modelMapperMock.Object); + + _mediatorMock + .Setup(x => x.Send(It.Is(x => x.LastNumberOfDays == _lastNumberOfDays), + CancellationToken.None)) + .ReturnsAsync(_getApprenticeshipStatisticsQueryResult); + + _modelMapperMock + .Setup(x => x.Map(_getApprenticeshipStatisticsQueryResult)) + .ReturnsAsync(_getApprenticeshipStatisticsResponse); + } + + [Test] + public async Task WhenCallingGetStatistics_ThenSendsMediatorQueryCorrectly() + { + //Act + await _sut.GetStatistics(_lastNumberOfDays); + + //Assert + _mediatorMock.Verify(x => x.Send(It.Is(x => x.LastNumberOfDays == _lastNumberOfDays), default), Times.Once); + } + + [Test] + public async Task WhenCallingGetStatistics_AndQueryReturnsNull_ThenReturnsNotFound() + { + //Arrange + _mediatorMock + .Setup(x => x.Send( + It.Is(x => x.LastNumberOfDays == _lastNumberOfDays), + CancellationToken.None)) + .Returns(Task.FromResult(null)); + + //Act + var result = await _sut.GetStatistics(_lastNumberOfDays); + + //Assert + Assert.True(result is NotFoundResult); + } + + [Test] + public async Task WhenCallingGetStatistics_ThenMapsResultToResponseDto() + { + //Act + var result = await _sut.GetStatistics(_lastNumberOfDays); + + //Assert + _modelMapperMock.Verify(x => x.Map(_getApprenticeshipStatisticsQueryResult)); + } + + [Test] + public async Task WhenCallingGetStatistics_ThenGeneratesOkResponse() + { + //Act + var result = await _sut.GetStatistics(_lastNumberOfDays) as OkObjectResult; + var resultResponse = result?.Value as GetApprenticeshipStatisticsResponse; + + //Assert + result.Should().NotBeNull(); + resultResponse.Should().NotBeNull(); + resultResponse.Paused.Should().Be(_getApprenticeshipStatisticsResponse.Paused); + resultResponse.Stopped.Should().Be(_getApprenticeshipStatisticsResponse.Stopped); + resultResponse.Approved.Should().Be(_getApprenticeshipStatisticsResponse.Approved); + } + } +} \ No newline at end of file diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2.Api/Controllers/ApprenticeshipStatisticsController.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.Api/Controllers/ApprenticeshipStatisticsController.cs new file mode 100644 index 0000000000..4cdc32ad3b --- /dev/null +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.Api/Controllers/ApprenticeshipStatisticsController.cs @@ -0,0 +1,41 @@ +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using SFA.DAS.CommitmentsV2.Api.Types.Responses; +using SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatistics; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using System.Threading.Tasks; + +namespace SFA.DAS.CommitmentsV2.Api.Controllers +{ + [ApiController] + [Authorize] + [Route("api/apprenticeshipstatistics")] + public class ApprenticeshipStatisticsController : ControllerBase + { + private readonly IMediator _mediator; + private readonly IModelMapper _modelMapper; + + public ApprenticeshipStatisticsController(IMediator mediator, IModelMapper modelMapper) + { + _mediator = mediator; + _modelMapper = modelMapper; + } + + [HttpGet] + [Route("/stats")] + public async Task GetStatistics(int lastNumberOfDays) + { + var result = await _mediator.Send(new GetApprenticeshipStatisticsQuery { LastNumberOfDays = lastNumberOfDays }); + + if (result == null) + { + return NotFound(); + } + + var response = await _modelMapper.Map(result); + + return Ok(response); + } + } +} \ No newline at end of file diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Application/Queries/GetApprenticeshipStatisticsTests/GetApprenticeshipStatisticsHandlerTests.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Application/Queries/GetApprenticeshipStatisticsTests/GetApprenticeshipStatisticsHandlerTests.cs new file mode 100644 index 0000000000..9d47dd3e93 --- /dev/null +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Application/Queries/GetApprenticeshipStatisticsTests/GetApprenticeshipStatisticsHandlerTests.cs @@ -0,0 +1,44 @@ +using System.Threading.Tasks; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatistics; +using SFA.DAS.CommitmentsV2.Domain.Interfaces; + +namespace SFA.DAS.CommitmentsV2.UnitTests.Application.Queries.GetApprenticeshipStatisticsTests +{ + [TestFixture] + public class GetApprenticeshipStatisticsHandlerTests + { + private GetApprenticeshipStatisticsQuery _query; + private GetApprenticeshipStatisticsQueryResult _result; + private Mock _apprenticeshipStatusSummaryServiceMock; + private GetApprenticeshipStatisticsQueryHandler _sut; + + [SetUp] + public void SetUp() + { + _query = new GetApprenticeshipStatisticsQuery(); + _result = new GetApprenticeshipStatisticsQueryResult(); + + _apprenticeshipStatusSummaryServiceMock = new Mock(); + _apprenticeshipStatusSummaryServiceMock + .Setup(x => x.GetApprenticeshipStatisticsFor(_query.LastNumberOfDays)) + .ReturnsAsync(_result); + + _sut = new GetApprenticeshipStatisticsQueryHandler(_apprenticeshipStatusSummaryServiceMock.Object); + } + + [Test] + public async Task WhenHandling_ThenCallsApprenticeshipStatusSummaryServiceWithCorrectValues() + { + //Arrange + _query.LastNumberOfDays = 30; + + //Act + await _sut.Handle(_query, default); + + //Assert + _apprenticeshipStatusSummaryServiceMock.Verify(x => x.GetApprenticeshipStatisticsFor(_query.LastNumberOfDays), Times.Once); + } + } +} \ No newline at end of file diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Application/Queries/GetApprenticeshipStatisticsTests/GetApprenticeshipStatisticsValidatorTests.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Application/Queries/GetApprenticeshipStatisticsTests/GetApprenticeshipStatisticsValidatorTests.cs new file mode 100644 index 0000000000..58856f4ba8 --- /dev/null +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Application/Queries/GetApprenticeshipStatisticsTests/GetApprenticeshipStatisticsValidatorTests.cs @@ -0,0 +1,26 @@ +using FluentAssertions; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatistics; + +namespace SFA.DAS.CommitmentsV2.UnitTests.Application.Queries.GetApprenticeshipStatisticsTests +{ + [TestFixture] + public class GetApprenticeshipStatisticsValidatorTests + { + [TestCase(-10, false)] + [TestCase(0, false)] + [TestCase(10, true)] + public void WhenCallingValidate_ThenCorrectlyValidatesLastNumberOfDays(int lastNumberOfDays, + bool expectedValid) + { + //Arrange + var validator = new GetApprenticeshipStatisticsQueryValidator(); + + //Act + var result = validator.Validate(new GetApprenticeshipStatisticsQuery { LastNumberOfDays = lastNumberOfDays }); + + //Assert + result.IsValid.Should().Be(expectedValid); + } + } +} \ No newline at end of file diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Mapping/ResponseMappers/GetApprenticeshipStatisticsResponseMapperTests.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Mapping/ResponseMappers/GetApprenticeshipStatisticsResponseMapperTests.cs new file mode 100644 index 0000000000..475656402e --- /dev/null +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Mapping/ResponseMappers/GetApprenticeshipStatisticsResponseMapperTests.cs @@ -0,0 +1,37 @@ +using AutoFixture; +using FluentAssertions; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatistics; +using SFA.DAS.CommitmentsV2.Mapping.ResponseMappers; +using System.Threading.Tasks; + +namespace SFA.DAS.CommitmentsV2.UnitTests.Mapping.ResponseMappers +{ + [TestFixture] + public class GetApprenticeshipStatisticsResponseMapperTests + { + private Fixture _fixture; + private GetApprenticeshipStatisticsQueryResult _queryResult; + private GetApprenticeshipStatisticsResponseMapper _sut; + + [SetUp] + public void SetUp() + { + _fixture = new Fixture(); + _queryResult = _fixture.Create(); + _sut = new GetApprenticeshipStatisticsResponseMapper(); + } + + [Test] + public async Task WhenMapIsCalled_ThenResponseIsMappedCorrectly() + { + //Act + var response = await _sut.Map(_queryResult); + + //Assert + response.Paused.Should().Be(_queryResult.PausedApprenticeshipCount); + response.Approved.Should().Be(_queryResult.ApprovedApprenticeshipCount); + response.Stopped.Should().Be(_queryResult.StoppedApprenticeshipCount); + } + } +} \ No newline at end of file diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Services/ApprenticeshipStatusSummaryServiceTests.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Services/ApprenticeshipStatusSummaryTests/ApprenticeshipStatusSummaryServiceTests.cs similarity index 98% rename from src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Services/ApprenticeshipStatusSummaryServiceTests.cs rename to src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Services/ApprenticeshipStatusSummaryTests/ApprenticeshipStatusSummaryServiceTests.cs index 62d01ac464..883098393c 100644 --- a/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Services/ApprenticeshipStatusSummaryServiceTests.cs +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Services/ApprenticeshipStatusSummaryTests/ApprenticeshipStatusSummaryServiceTests.cs @@ -1,4 +1,9 @@ -using AutoFixture; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using AutoFixture; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Logging; @@ -10,13 +15,8 @@ using SFA.DAS.CommitmentsV2.Services; using SFA.DAS.CommitmentsV2.Types; using SFA.DAS.Testing.Builders; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -namespace SFA.DAS.CommitmentsV2.UnitTests.Services +namespace SFA.DAS.CommitmentsV2.UnitTests.Services.ApprenticeshipStatusSummaryTests { [TestFixture] [Parallelizable(ParallelScope.None)] diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Services/ApprenticeshipStatusSummaryTests/WhenGettingApprenticeshipStatistics.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Services/ApprenticeshipStatusSummaryTests/WhenGettingApprenticeshipStatistics.cs new file mode 100644 index 0000000000..ddd42b1797 --- /dev/null +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Services/ApprenticeshipStatusSummaryTests/WhenGettingApprenticeshipStatistics.cs @@ -0,0 +1,124 @@ +using AutoFixture; +using FluentAssertions; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.Extensions.Logging; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Data; +using SFA.DAS.CommitmentsV2.Models; +using SFA.DAS.CommitmentsV2.Services; +using SFA.DAS.CommitmentsV2.Types; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace SFA.DAS.CommitmentsV2.UnitTests.Services.ApprenticeshipStatusSummaryTests +{ + [TestFixture] + public class WhenGettingApprenticeshipStatistics + { + private Fixture _fixture; + private Random _random; + private int _lastNumberOfDays; + + private Mock> _loggerMock; + private ProviderCommitmentsDbContext _context; + private Lazy _providerCommitmentsDbContextMock; + + private ApprenticeshipStatusSummaryService _sut; + + [SetUp] + public void SetUp() + { + _fixture = new Fixture(); + _fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + _random = new Random(); + _lastNumberOfDays = _fixture.Create(); + + _loggerMock = new Mock>(); + _context = new ProviderCommitmentsDbContext(new DbContextOptionsBuilder() + .UseInMemoryDatabase("TestDb", new InMemoryDatabaseRoot()) + .Options); + _providerCommitmentsDbContextMock = new Lazy(_context); + + _sut = new ApprenticeshipStatusSummaryService(_providerCommitmentsDbContextMock, _loggerMock.Object); + } + + [Test] + public async Task ThenCorrectlyReturnsApprovedCount() + { + //Arrange + var expectedApprovedApprenticeships = await AddApprenticeshipsToDb(_lastNumberOfDays, true, default, 10); + var unexpectedApprenticeships = await AddApprenticeshipsToDb(_lastNumberOfDays, false, default, 7); + + //Act + var result = await _sut.GetApprenticeshipStatisticsFor(_lastNumberOfDays); + + //Assert + result.ApprovedApprenticeshipCount.Should().Be(expectedApprovedApprenticeships.Count); + } + + [Test] + public async Task ThenCorrectlyReturnsPausedCount() + { + //Arrange + var expectedPausedApprenticeships = await AddApprenticeshipsToDb(_lastNumberOfDays, true, PaymentStatus.Paused, 12); + var unexpectedApprenticeships = await AddApprenticeshipsToDb(_lastNumberOfDays, false, PaymentStatus.Paused, 8); + + //Act + var result = await _sut.GetApprenticeshipStatisticsFor(_lastNumberOfDays); + + //Assert + result.PausedApprenticeshipCount.Should().Be(expectedPausedApprenticeships.Count); + } + + [Test] + public async Task ThenCorrectlyReturnsStoppedCount() + { + //Arrange + var expectedStoppedApprenticeships = await AddApprenticeshipsToDb(_lastNumberOfDays, true, PaymentStatus.Withdrawn, 6); + var unexpectedApprenticeships = await AddApprenticeshipsToDb(_lastNumberOfDays, false, PaymentStatus.Withdrawn, 4); + + //Act + var result = await _sut.GetApprenticeshipStatisticsFor(_lastNumberOfDays); + + //Assert + result.StoppedApprenticeshipCount.Should().Be(expectedStoppedApprenticeships.Count); + } + + private async Task> AddApprenticeshipsToDb(int lastNumberOfDays, bool isExpectedInCount, PaymentStatus paymentStatus, int amountToCreate) + { + var fromDate = DateTime.UtcNow.AddDays(Math.Abs(lastNumberOfDays) * -1).Date; + var testFromDate = isExpectedInCount ? fromDate.AddDays(1) : fromDate.AddDays(-1); + + var apprenticeships = new List(); + + for (int i = 0; i < amountToCreate; i++) + { + var randomNum = _random.Next(2); + var apprenticeship = new Apprenticeship(); + + var cohort = new Cohort(); + cohort.EmployerAndProviderApprovedOn = testFromDate; + cohort.Approvals = randomNum == 1 ? (Party)3 : (Party)7; + + apprenticeship.Cohort = cohort; + apprenticeship.CommitmentId = cohort.Id; + apprenticeship.StopDate = testFromDate; + apprenticeship.PauseDate = testFromDate; + apprenticeship.PaymentStatus = paymentStatus; + apprenticeship.IsApproved = true; + + apprenticeships.Add(apprenticeship); + } + + _context.Apprenticeships.AddRange(apprenticeships); + + await _context.SaveChangesAsync(); + + return apprenticeships.ToList(); + } + } +} \ No newline at end of file diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Queries/GetApprenticeshipStatistics/GetApprenticeshipStatisticsQuery.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Queries/GetApprenticeshipStatistics/GetApprenticeshipStatisticsQuery.cs new file mode 100644 index 0000000000..5e59fa1b92 --- /dev/null +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Queries/GetApprenticeshipStatistics/GetApprenticeshipStatisticsQuery.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MediatR; + +namespace SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatistics +{ + public class GetApprenticeshipStatisticsQuery : IRequest + { + public int LastNumberOfDays { get; set; } + } +} diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Queries/GetApprenticeshipStatistics/GetApprenticeshipStatisticsQueryHandler.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Queries/GetApprenticeshipStatistics/GetApprenticeshipStatisticsQueryHandler.cs new file mode 100644 index 0000000000..c598c21ba5 --- /dev/null +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Queries/GetApprenticeshipStatistics/GetApprenticeshipStatisticsQueryHandler.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MediatR; +using SFA.DAS.CommitmentsV2.Domain.Interfaces; + +namespace SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatistics +{ + public class GetApprenticeshipStatisticsQueryHandler : IRequestHandler + { + private readonly IApprenticeshipStatusSummaryService _apprenticeshipStatusSummaryService; + + public GetApprenticeshipStatisticsQueryHandler(IApprenticeshipStatusSummaryService apprenticeshipStatusSummaryService) + { + _apprenticeshipStatusSummaryService = apprenticeshipStatusSummaryService; + } + + public async Task Handle(GetApprenticeshipStatisticsQuery request, CancellationToken cancellationToken) + { + return await _apprenticeshipStatusSummaryService.GetApprenticeshipStatisticsFor(request.LastNumberOfDays); + } + } +} diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Queries/GetApprenticeshipStatistics/GetApprenticeshipStatisticsQueryResult.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Queries/GetApprenticeshipStatistics/GetApprenticeshipStatisticsQueryResult.cs new file mode 100644 index 0000000000..869699cb82 --- /dev/null +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Queries/GetApprenticeshipStatistics/GetApprenticeshipStatisticsQueryResult.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatistics +{ + public class GetApprenticeshipStatisticsQueryResult + { + public long ApprovedApprenticeshipCount { get; set; } + public long PausedApprenticeshipCount { get; set; } + public long StoppedApprenticeshipCount { get; set; } + } +} diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Queries/GetApprenticeshipStatistics/GetApprenticeshipStatisticsQueryValidator.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Queries/GetApprenticeshipStatistics/GetApprenticeshipStatisticsQueryValidator.cs new file mode 100644 index 0000000000..ede77fd73d --- /dev/null +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Queries/GetApprenticeshipStatistics/GetApprenticeshipStatisticsQueryValidator.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using FluentValidation; + +namespace SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatistics +{ + public class GetApprenticeshipStatisticsQueryValidator : AbstractValidator + { + public GetApprenticeshipStatisticsQueryValidator() + { + RuleFor(x => x.LastNumberOfDays).GreaterThan(0); + } + } +} diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Domain/Interfaces/IApprenticeshipStatusSummaryService.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Domain/Interfaces/IApprenticeshipStatusSummaryService.cs index 9d15545c1f..b9bb11659c 100644 --- a/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Domain/Interfaces/IApprenticeshipStatusSummaryService.cs +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Domain/Interfaces/IApprenticeshipStatusSummaryService.cs @@ -1,11 +1,13 @@ using SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatusSummary; using System.Threading; using System.Threading.Tasks; +using SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatistics; namespace SFA.DAS.CommitmentsV2.Domain.Interfaces { public interface IApprenticeshipStatusSummaryService { Task GetApprenticeshipStatusSummary(long employerAccountId, CancellationToken cancellationToken); + Task GetApprenticeshipStatisticsFor(int lastNumberOfDays); } } diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Mapping/ResponseMappers/GetApprenticeshipStatisticsResponseMapper.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Mapping/ResponseMappers/GetApprenticeshipStatisticsResponseMapper.cs new file mode 100644 index 0000000000..f7f10c5def --- /dev/null +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Mapping/ResponseMappers/GetApprenticeshipStatisticsResponseMapper.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using SFA.DAS.CommitmentsV2.Api.Types.Responses; +using SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatistics; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; + +namespace SFA.DAS.CommitmentsV2.Mapping.ResponseMappers +{ + public class GetApprenticeshipStatisticsResponseMapper : IMapper + { + public Task Map(GetApprenticeshipStatisticsQueryResult source) + { + return Task.FromResult(new GetApprenticeshipStatisticsResponse + { + Paused = source.PausedApprenticeshipCount, + Stopped = source.StoppedApprenticeshipCount, + Approved = source.ApprovedApprenticeshipCount + }); + } + } +} diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Services/ApprenticeshipStatusSummaryService.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Services/ApprenticeshipStatusSummaryService.cs index 818e33cf08..4a4688c368 100644 --- a/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Services/ApprenticeshipStatusSummaryService.cs +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Services/ApprenticeshipStatusSummaryService.cs @@ -1,15 +1,15 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; +using SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatistics; using SFA.DAS.CommitmentsV2.Application.Queries.GetApprenticeshipStatusSummary; using SFA.DAS.CommitmentsV2.Data; using SFA.DAS.CommitmentsV2.Domain.Interfaces; +using SFA.DAS.CommitmentsV2.Models; using SFA.DAS.CommitmentsV2.Types; using System; -using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using SFA.DAS.CommitmentsV2.Models; namespace SFA.DAS.CommitmentsV2.Services { @@ -58,6 +58,38 @@ public async Task GetApprenticeshipS }; } + + public async Task GetApprenticeshipStatisticsFor(int lastNumberOfDays) + { + var fromDate = DateTime.UtcNow.AddDays(Math.Abs(lastNumberOfDays) * -1).Date; + + var commitmentsApprovedCount = await _dbContext.Value + .Apprenticeships + .Include(x => x.Cohort) + .CountAsync(x => + x.Cohort.EmployerAndProviderApprovedOn > fromDate && + (x.Cohort.Approvals == (Party)3 || x.Cohort.Approvals == (Party)7)); + + var commitmentsStoppedCount = await _dbContext.Value + .Apprenticeships + .CountAsync(x => + x.StopDate > fromDate && + x.PaymentStatus == PaymentStatus.Withdrawn); + + var commitmentsPausedCount = await _dbContext.Value + .Apprenticeships + .CountAsync(x => + x.IsApproved && + x.PauseDate > fromDate && + x.PaymentStatus == PaymentStatus.Paused); + + return new GetApprenticeshipStatisticsQueryResult + { + ApprovedApprenticeshipCount = commitmentsApprovedCount, + StoppedApprenticeshipCount = commitmentsStoppedCount, + PausedApprenticeshipCount = commitmentsPausedCount + }; + } } public class ApprenticeshipSummary @@ -70,4 +102,4 @@ public class ApprenticeshipSummary public int Count { get; set; } } -} +} \ No newline at end of file