diff --git a/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/CompliancePaymentRequest.cs b/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/CompliancePaymentRequest.cs index 006f7ebc0..42e047414 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/CompliancePaymentRequest.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/CompliancePaymentRequest.cs @@ -23,5 +23,7 @@ public class ComplianceSchemeMemberRequest public int NumberOfSubsidiaries { get; set; } + public int NumberOfLateSubsidiaries { get; set; } + public int NoOfSubsidiariesOnlineMarketplace { get; set; } } \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/FacadeCommonData/CsoMembershipDetailsDto.cs b/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/FacadeCommonData/CsoMembershipDetailsDto.cs index f28f66800..9fcb258c6 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/FacadeCommonData/CsoMembershipDetailsDto.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/FacadeCommonData/CsoMembershipDetailsDto.cs @@ -9,6 +9,7 @@ public class CsoMembershipDetailsDto public bool IsOnlineMarketPlace { get; set; } public bool IsLateFeeApplicable { get; set; } public int NumberOfSubsidiaries { get; set; } + public int NumberOfLateSubsidiaries { get; set; } [JsonPropertyName("NumberOfSubsidiariesOnlineMarketPlace")] public int NoOfSubsidiariesOnlineMarketplace { get; set; } @@ -23,6 +24,7 @@ public class CsoMembershipDetailsDto IsOnlineMarketplace = dto.IsOnlineMarketPlace, IsLateFeeApplicable = dto.IsLateFeeApplicable, NoOfSubsidiariesOnlineMarketplace = dto.NoOfSubsidiariesOnlineMarketplace, - NumberOfSubsidiaries = dto.NumberOfSubsidiaries + NumberOfSubsidiaries = dto.NumberOfSubsidiaries, + NumberOfLateSubsidiaries = dto.NumberOfLateSubsidiaries }; } diff --git a/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/FacadeCommonData/ProducerDetailsDto.cs b/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/FacadeCommonData/ProducerDetailsDto.cs index 742726930..dcca64f89 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/FacadeCommonData/ProducerDetailsDto.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/FacadeCommonData/ProducerDetailsDto.cs @@ -8,6 +8,8 @@ public class ProducerDetailsDto public int NoOfSubsidiaries { get; set; } + public int NoOfLateSubsidiaries { get; set; } + public bool IsLateFeeApplicable { get; set; } public bool IsProducerOnlineMarketplace { get; set; } diff --git a/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/FacadeCommonData/RegistrationSubmissionOrganisationDetailsResponse.cs b/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/FacadeCommonData/RegistrationSubmissionOrganisationDetailsResponse.cs index f9f6e0f27..bc7753998 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/FacadeCommonData/RegistrationSubmissionOrganisationDetailsResponse.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/FacadeCommonData/RegistrationSubmissionOrganisationDetailsResponse.cs @@ -44,6 +44,7 @@ public class RegistrationSubmissionOrganisationDetailsResponse public bool IsOnlineMarketPlace { get; set; } public int NumberOfSubsidiaries { get; set; } public int NumberOfOnlineSubsidiaries { get; set; } + public int NumberOfLateSubsidiaries { get; set; } public bool IsLateSubmission { get; set; } public string OrganisationSize { get; set; } public bool IsComplianceScheme { get; set; } diff --git a/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/ProducerPaymentRequest.cs b/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/ProducerPaymentRequest.cs index b3c219c14..7fff6dd96 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/ProducerPaymentRequest.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/ProducerPaymentRequest.cs @@ -8,6 +8,8 @@ public class ProducerPaymentRequest public int NumberOfSubsidiaries { get; set; } + public int NoOfLateSubsidiaries { get; set; } + public bool IsLateFeeApplicable { get; set; } public bool IsProducerOnlineMarketplace { get; set; } diff --git a/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/RegistrationSubmissionOrganisationDetails.cs b/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/RegistrationSubmissionOrganisationDetails.cs index d27b3a4dc..6852c89a1 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/RegistrationSubmissionOrganisationDetails.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Models/RegistrationSubmissions/RegistrationSubmissionOrganisationDetails.cs @@ -163,6 +163,7 @@ public static implicit operator RegistrationSubmissionOrganisationDetails(Regist IsProducerOnlineMarketplace = response.IsOnlineMarketPlace, NoOfSubsidiaries = response.NumberOfSubsidiaries, NoOfSubsidiariesOnlineMarketPlace = response.NumberOfOnlineSubsidiaries, + NoOfLateSubsidiaries = response.NumberOfLateSubsidiaries, ProducerType = response.OrganisationSize } }; diff --git a/src/EPR.RegulatorService.Frontend.Core/Models/Submissions/PackagingProducerPaymentRequest.cs b/src/EPR.RegulatorService.Frontend.Core/Models/Submissions/PackagingProducerPaymentRequest.cs index 698f22c6f..a2ad89bf1 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Models/Submissions/PackagingProducerPaymentRequest.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Models/Submissions/PackagingProducerPaymentRequest.cs @@ -7,4 +7,6 @@ public class PackagingProducerPaymentRequest public required string Regulator { get; set; } public required DateTime ResubmissionDate { get; set; } + + public required int MemberCount { get; set; } } \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/SubmissionDetailsTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/SubmissionDetailsTests.cs index cd21a7475..e5abd5ba9 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/SubmissionDetailsTests.cs +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/SubmissionDetailsTests.cs @@ -1,11 +1,9 @@ using EPR.RegulatorService.Frontend.Core.Sessions; +using EPR.RegulatorService.Frontend.UnitTests.TestData; using EPR.RegulatorService.Frontend.Web.Constants; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; - using EPR.RegulatorService.Frontend.Web.ViewModels.Submissions; -using EPR.RegulatorService.Frontend.UnitTests.TestData; -using EPR.RegulatorService.Frontend.Core.Models.Submissions; + +using Microsoft.AspNetCore.Http; namespace EPR.RegulatorService.Frontend.UnitTests.Web.Controllers { diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Web/ViewComponents/PackagingProducerPaymentDetailsViewComponentTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Web/ViewComponents/PackagingProducerPaymentDetailsViewComponentTests.cs index 3fc5974e5..709a05c79 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/Web/ViewComponents/PackagingProducerPaymentDetailsViewComponentTests.cs +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Web/ViewComponents/PackagingProducerPaymentDetailsViewComponentTests.cs @@ -1,12 +1,9 @@ -using EPR.RegulatorService.Frontend.Core.Models.Submissions; -using EPR.RegulatorService.Frontend.Core.Services; using EPR.RegulatorService.Frontend.Web.Configs; using EPR.RegulatorService.Frontend.Web.ViewComponents.Submissions; using EPR.RegulatorService.Frontend.Web.ViewModels.Submissions; using Microsoft.AspNetCore.Mvc.ViewComponents; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; +using Microsoft.FeatureManagement; namespace EPR.RegulatorService.Frontend.UnitTests.Web.ViewComponents; @@ -18,6 +15,7 @@ public class PackagingProducerPaymentDetailsViewComponentTests : ViewComponentsT private readonly Mock _paymentFacadeServiceMock = new(); private readonly Mock> _loggerMock = new(); private readonly Mock> _paymentDetailsOptionsMock = new(); + private readonly Mock _mockFeatureManager = new(); [TestInitialize] public void TestInitialize() @@ -29,7 +27,15 @@ public void TestInitialize() }; _loggerMock.Setup(x => x.IsEnabled(It.IsAny())).Returns(true); _paymentDetailsOptionsMock.Setup(r => r.Value).Returns(new PaymentDetailsOptions()); - _sut = new PackagingProducerPaymentDetailsViewComponent(_paymentDetailsOptionsMock.Object, _paymentFacadeServiceMock.Object, _loggerMock.Object); + _mockFeatureManager.Setup(fm => + fm.IsEnabledAsync(FeatureFlags.IncludeSubsidiariesInFeeCalculationsForRegulators)) + .ReturnsAsync(false); + + _sut = new PackagingProducerPaymentDetailsViewComponent( + _paymentDetailsOptionsMock.Object, + _paymentFacadeServiceMock.Object, + _mockFeatureManager.Object, + _loggerMock.Object); } [TestMethod] @@ -119,7 +125,7 @@ public async Task InvokeAsync_Returns_CorrectView_With_Model() } [TestMethod] - public async Task WhenpPoducerPaidInExcessOfTheAmountRequiredThenOutstandingPaymentShouldShowZero() + public async Task WhenProducerPaidInExcessOfTheAmountRequiredThenOutstandingPaymentShouldShowZero() { // Arrange _paymentFacadeServiceMock.Setup(x => x.GetProducerPaymentDetailsForResubmissionAsync( @@ -132,7 +138,11 @@ public async Task WhenpPoducerPaidInExcessOfTheAmountRequiredThenOutstandingPaym }); _loggerMock.Setup(x => x.IsEnabled(It.IsAny())).Returns(true); _paymentDetailsOptionsMock.Setup(r => r.Value).Returns(new PaymentDetailsOptions { ShowZeroFeeForTotalOutstanding = true }); - _sut = new PackagingProducerPaymentDetailsViewComponent(_paymentDetailsOptionsMock.Object, _paymentFacadeServiceMock.Object, _loggerMock.Object); + _sut = new PackagingProducerPaymentDetailsViewComponent( + _paymentDetailsOptionsMock.Object, + _paymentFacadeServiceMock.Object, + _mockFeatureManager.Object, + _loggerMock.Object); // Act var result = await _sut.InvokeAsync(_submissionDetailsViewModel); @@ -179,4 +189,54 @@ public async Task InvokeAsync_Logs_Error_And_Returns_CorrectView_With_DefaultMod It.IsAny>()), Times.Once); } + + [TestMethod] + public async Task InvokeAsync_WhenFeatureFlagDisabled_PassesMemberCountAsOne() + { + // Arrange + _submissionDetailsViewModel.MemberCount = 25; // should be ignored when flag disabled + _paymentFacadeServiceMock + .Setup(s => s.GetProducerPaymentDetailsForResubmissionAsync(It.IsAny())) + .ReturnsAsync(new PackagingProducerPaymentResponse + { + ResubmissionFee = 0, + PreviousPaymentsReceived = 0, + TotalOutstanding = 0 + }); + + // Act + await _sut.InvokeAsync(_submissionDetailsViewModel); + + // Assert + _paymentFacadeServiceMock.Verify(s => + s.GetProducerPaymentDetailsForResubmissionAsync( + It.Is(r => r.MemberCount == 1)), Times.Once); + } + + [TestMethod] + public async Task InvokeAsync_WhenFeatureFlagEnabled_Passes_ViewModel_MemberCount() + { + // Arrange + _submissionDetailsViewModel.MemberCount = 37; + _mockFeatureManager.Setup(fm => + fm.IsEnabledAsync(FeatureFlags.IncludeSubsidiariesInFeeCalculationsForRegulators)) + .ReturnsAsync(true); + + _paymentFacadeServiceMock + .Setup(s => s.GetProducerPaymentDetailsForResubmissionAsync(It.IsAny())) + .ReturnsAsync(new PackagingProducerPaymentResponse + { + ResubmissionFee = 0, + PreviousPaymentsReceived = 0, + TotalOutstanding = 0 + }); + + // Act + await _sut.InvokeAsync(_submissionDetailsViewModel); + + // Assert + _paymentFacadeServiceMock.Verify(s => + s.GetProducerPaymentDetailsForResubmissionAsync( + It.Is(r => r.MemberCount == 37)), Times.Once); + } } \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/Configs/FeatureFlags.cs b/src/EPR.RegulatorService.Frontend.Web/Configs/FeatureFlags.cs index 1c2c0dbb7..1661d2573 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Configs/FeatureFlags.cs +++ b/src/EPR.RegulatorService.Frontend.Web/Configs/FeatureFlags.cs @@ -27,4 +27,6 @@ public static class FeatureFlags public const string ShowFeesWaiveButton = "ShowFeesWaiveButton"; public const string ShowComplianceSchemeMembership = "ShowComplianceSchemeMembership"; + + public const string IncludeSubsidiariesInFeeCalculationsForRegulators = "IncludeSubsidiariesInFeeCalculationsForRegulators"; } \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/ViewComponents/RegistrationSubmissions/ProducerPaymentDetailsViewComponent.cs b/src/EPR.RegulatorService.Frontend.Web/ViewComponents/RegistrationSubmissions/ProducerPaymentDetailsViewComponent.cs index b00bda6c6..852195884 100644 --- a/src/EPR.RegulatorService.Frontend.Web/ViewComponents/RegistrationSubmissions/ProducerPaymentDetailsViewComponent.cs +++ b/src/EPR.RegulatorService.Frontend.Web/ViewComponents/RegistrationSubmissions/ProducerPaymentDetailsViewComponent.cs @@ -28,6 +28,7 @@ public async Task InvokeAsync(RegistrationSubmissionDet ApplicationReferenceNumber = viewModel.ReferenceNumber, NoOfSubsidiariesOnlineMarketplace = viewModel.ProducerDetails.NoOfSubsidiariesOnlineMarketPlace, NumberOfSubsidiaries = viewModel.ProducerDetails.NoOfSubsidiaries, + NoOfLateSubsidiaries = viewModel.ProducerDetails.NoOfLateSubsidiaries, IsLateFeeApplicable = viewModel.ProducerDetails.IsLateFeeApplicable, IsProducerOnlineMarketplace = viewModel.ProducerDetails.IsProducerOnlineMarketplace, ProducerType = viewModel.ProducerDetails.ProducerType, diff --git a/src/EPR.RegulatorService.Frontend.Web/ViewComponents/Submissions/PackagingProducerPaymentDetailsViewComponent.cs b/src/EPR.RegulatorService.Frontend.Web/ViewComponents/Submissions/PackagingProducerPaymentDetailsViewComponent.cs index 12ff20bf4..0af4c2a25 100644 --- a/src/EPR.RegulatorService.Frontend.Web/ViewComponents/Submissions/PackagingProducerPaymentDetailsViewComponent.cs +++ b/src/EPR.RegulatorService.Frontend.Web/ViewComponents/Submissions/PackagingProducerPaymentDetailsViewComponent.cs @@ -7,10 +7,15 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ViewComponents; using Microsoft.Extensions.Options; +using Microsoft.FeatureManagement; namespace EPR.RegulatorService.Frontend.Web.ViewComponents.Submissions; -public class PackagingProducerPaymentDetailsViewComponent(IOptions options, IPaymentFacadeService paymentFacadeService, ILogger logger) : ViewComponent +public class PackagingProducerPaymentDetailsViewComponent( + IOptions options, + IPaymentFacadeService paymentFacadeService, + IFeatureManager featureManager, + ILogger logger) : ViewComponent { private static readonly Action _logViewComponentError = LoggerMessage.Define( @@ -34,11 +39,17 @@ public async Task InvokeAsync(SubmissionDetailsViewMode return View(default(PackagingProducerPaymentDetailsViewModel)); } + int memberCount = + await featureManager.IsEnabledAsync(FeatureFlags.IncludeSubsidiariesInFeeCalculationsForRegulators) + ? viewModel.MemberCount + : 1; + var producerPaymentResponse = await paymentFacadeService .GetProducerPaymentDetailsForResubmissionAsync(new PackagingProducerPaymentRequest { ReferenceNumber = viewModel.ReferenceNumber, Regulator = viewModel.NationCode, + MemberCount = memberCount, ResubmissionDate = TimeZoneInfo.ConvertTimeToUtc(viewModel.SubmittedDate) //payment facade in utc format }); diff --git a/src/EPR.RegulatorService.Frontend.Web/appsettings.json b/src/EPR.RegulatorService.Frontend.Web/appsettings.json index 68bca14fc..15d686f5d 100644 --- a/src/EPR.RegulatorService.Frontend.Web/appsettings.json +++ b/src/EPR.RegulatorService.Frontend.Web/appsettings.json @@ -202,7 +202,8 @@ "EnableCsvDownload": false, "ReprocessorExporter": false, "ShowYourFeedbackFooter": false, - "ShowFeesWaiveButton": false + "ShowFeesWaiveButton": false, + "IncludeSubsidiariesInFeeCalculationsForRegulators": false }, "BehaviourManagement": { "PomSubmissionFilters": {