diff --git a/.gitignore b/.gitignore index 900145a9..1ceb5ee0 100644 --- a/.gitignore +++ b/.gitignore @@ -369,3 +369,4 @@ FodyWeavers.xsd src/certs/kainos-chain.pem src/certs/kainos-chain.p7b /src/EPR.RegulatorService.Frontend.Web/appsettings.development.json +/src/EPR.RegulatorService.Frontend.Web/appsettings.development.json diff --git a/pipelines/ci_pipeline.yaml b/pipelines/ci_pipeline.yaml index 2cd96940..c2204c41 100644 --- a/pipelines/ci_pipeline.yaml +++ b/pipelines/ci_pipeline.yaml @@ -39,8 +39,9 @@ variables: resources: repositories: - repository: CommonTemplates - name: RWD-CPR-EPR4P-ADO/epr-webapps-code-deploy-templates - type: git + name: defra/epr-webapps-code-deploy-templates + type: github + endpoint: defra ref: main extends: diff --git a/pipelines/deployment-pipeline.yaml b/pipelines/deployment-pipeline.yaml index 1461b17c..8624b9a0 100644 --- a/pipelines/deployment-pipeline.yaml +++ b/pipelines/deployment-pipeline.yaml @@ -62,8 +62,9 @@ variables: resources: repositories: - repository: CommonTemplates - name: RWD-CPR-EPR4P-ADO/epr-webapps-code-deploy-templates - type: git + name: defra/epr-webapps-code-deploy-templates + type: github + endpoint: defra ref: main # The repo will be reference the repo by a release tag (if the imageTag parameter contains 'release') otherwise it will pull down the main branch. diff --git a/src/Dockerfile b/src/Dockerfile index 62f9b99b..3e87bc48 100644 --- a/src/Dockerfile +++ b/src/Dockerfile @@ -1,4 +1,4 @@ -FROM defradigital/dotnetcore-development:latest AS build-env +FROM defradigital/dotnetcore-development:dotnet6.0 AS build-env # trigger Build 00.15 # Expose the app on a defined port, configurable via a build argument ARG PORT=3000 @@ -32,7 +32,7 @@ WORKDIR /home/dotnet/EPR.RegulatorService.Frontend.Web RUN dotnet publish -c Release -o out # Build runtime image -FROM defradigital/dotnetcore:latest +FROM defradigital/dotnetcore:dotnet6.0 COPY --from=build-env --chown=dotnet /home/dotnet/EPR.RegulatorService.Frontend.Web/out . # Add internationalisation support diff --git a/src/EPR.RegulatorService.Frontend.Core/Converters/OrganisationTypeConverter.cs b/src/EPR.RegulatorService.Frontend.Core/Converters/OrganisationTypeConverter.cs new file mode 100644 index 00000000..1171d357 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Core/Converters/OrganisationTypeConverter.cs @@ -0,0 +1,28 @@ +namespace EPR.RegulatorService.Frontend.Core.Converters; + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; +using Enums; +using Extensions; + +public class OrganisationTypeConverter : JsonConverter +{ + public override OrganisationType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + string value = reader.GetString(); + + foreach (OrganisationType type in Enum.GetValues(typeof(OrganisationType))) + { + if (type.GetDescription() == value) + { + return type; + } + } + + throw new JsonException($"Value '{value}' is not valid for {nameof(OrganisationType)}."); + } + + public override void Write(Utf8JsonWriter writer, OrganisationType value, JsonSerializerOptions options) + => writer.WriteStringValue(value.GetDescription()); +} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Core/EPR.RegulatorService.Frontend.Core.csproj b/src/EPR.RegulatorService.Frontend.Core/EPR.RegulatorService.Frontend.Core.csproj index 629b4915..bc2585d1 100644 --- a/src/EPR.RegulatorService.Frontend.Core/EPR.RegulatorService.Frontend.Core.csproj +++ b/src/EPR.RegulatorService.Frontend.Core/EPR.RegulatorService.Frontend.Core.csproj @@ -30,7 +30,7 @@ - **/MockedAcceptedRegistrations.cs,**/MockedPendingRegistrations.cs,**/MockedRejectedRegistrations.cs,**/ServiceProviderExtension.cs,**/MockedAcceptedSubmissions.cs,**/MockedPendingSubmissions.cs,**/MockedRejectedSubmissions.cs,**/OrganisationResponse.cs,**/TransferDetails.cs,**/User.cs,**/UserDataResponse.cs,**/UserDetails.cs,**/UserEnrolment.cs,**/MockedFacadeService.cs,**/JourneySession.cs,**/PermissionManagementSessionItem.cs,**/RejectUserJourneyData.cs,**/MockedAcceptedRegistrations.cs,**/RegistrationFilters.cs + **/MockedAcceptedRegistrations.cs,**/MockedPendingRegistrations.cs,**/MockedRejectedRegistrations.cs,**/ServiceProviderExtension.cs,**/MockedAcceptedSubmissions.cs,**/MockedPendingSubmissions.cs,**/MockedRejectedSubmissions.cs,**/OrganisationResponse.cs,**/TransferDetails.cs,**/User.cs,**/UserDataResponse.cs,**/UserDetails.cs,**/UserEnrolment.cs,**/MockedFacadeService.cs,**/JourneySession.cs,**/PermissionManagementSessionItem.cs,**/RejectUserJourneyData.cs,**/MockedAcceptedRegistrations.cs,**/RegistrationFilters.cs,**/Registration.cs diff --git a/src/EPR.RegulatorService.Frontend.Core/Enums/OrganisationType.cs b/src/EPR.RegulatorService.Frontend.Core/Enums/OrganisationType.cs index 2143fdc7..83a165ba 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Enums/OrganisationType.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Enums/OrganisationType.cs @@ -1,7 +1,10 @@ -using System.ComponentModel; - namespace EPR.RegulatorService.Frontend.Core.Enums; +using System.Text.Json.Serialization; +using System.ComponentModel; +using Converters; + +[JsonConverter(typeof(OrganisationTypeConverter))] public enum OrganisationType { [Description("Direct Producer")] diff --git a/src/EPR.RegulatorService.Frontend.Core/Extensions/BoolExtensionMethods.cs b/src/EPR.RegulatorService.Frontend.Core/Extensions/BoolExtensionMethods.cs new file mode 100644 index 00000000..102b38d8 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Core/Extensions/BoolExtensionMethods.cs @@ -0,0 +1,6 @@ +namespace EPR.RegulatorService.Frontend.Core.Extensions; + +public static class BoolExtensionMethods +{ + public static string ToYesNo(this bool inBool) => inBool ? "Yes" : "No"; +} diff --git a/src/EPR.RegulatorService.Frontend.Core/MockedData/Filters/RegistrationFilters.cs b/src/EPR.RegulatorService.Frontend.Core/MockedData/Filters/AbstractSubmissionFilters.cs similarity index 74% rename from src/EPR.RegulatorService.Frontend.Core/MockedData/Filters/RegistrationFilters.cs rename to src/EPR.RegulatorService.Frontend.Core/MockedData/Filters/AbstractSubmissionFilters.cs index bbf073d6..b02aeb36 100644 --- a/src/EPR.RegulatorService.Frontend.Core/MockedData/Filters/RegistrationFilters.cs +++ b/src/EPR.RegulatorService.Frontend.Core/MockedData/Filters/AbstractSubmissionFilters.cs @@ -1,11 +1,11 @@ -using EPR.RegulatorService.Frontend.Core.Models.Registrations; using EPR.RegulatorService.Frontend.Core.Enums; +using EPR.RegulatorService.Frontend.Core.Models; namespace EPR.RegulatorService.Frontend.Core.MockedData.Filters; -public static class RegistrationFilters +public static class AbstractSubmissionFilters { - public static IQueryable FilterByOrganisationNameAndOrganisationReference(this IQueryable query, + public static IQueryable FilterByOrganisationNameAndOrganisationReference(this IQueryable query, string organisationName, string organisationReference) { bool organisationNameSet = !string.IsNullOrWhiteSpace(organisationName); @@ -35,7 +35,7 @@ public static IQueryable FilterByOrganisationNameAndOrganisationRe return query; } - public static IQueryable FilterByOrganisationType(this IQueryable query, + public static IQueryable FilterByOrganisationType(this IQueryable query, OrganisationType? organisationType) { if (organisationType != null) @@ -46,10 +46,10 @@ public static IQueryable FilterByOrganisationType(this IQueryable< return query; } - public static IQueryable FilterByRegistrationStatus(this IQueryable query, + public static IQueryable FilterByStatus(this IQueryable query, string[] registrationStatuses) { - if (registrationStatuses.Length != 0) + if (registrationStatuses != null && registrationStatuses.Length != 0) { query = query.Where(o => registrationStatuses.Any(o.Decision.Contains)); } diff --git a/src/EPR.RegulatorService.Frontend.Core/MockedData/Filters/SubmissionsFilters.cs b/src/EPR.RegulatorService.Frontend.Core/MockedData/Filters/SubmissionsFilters.cs deleted file mode 100644 index 5ded1cd0..00000000 --- a/src/EPR.RegulatorService.Frontend.Core/MockedData/Filters/SubmissionsFilters.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace EPR.RegulatorService.Frontend.Core.MockedData.Filters; - -using Models.Submissions; - -public static class SubmissionsFilters -{ - public static IQueryable FilterByOrganisationNameAndOrganisationReference(this IQueryable query, - string organisationName, string organisationReference) - { - bool organisationNameSet = !string.IsNullOrWhiteSpace(organisationName); - bool organisationReferenceSet = !string.IsNullOrWhiteSpace(organisationReference); - - if (organisationNameSet && organisationReferenceSet) - { - query = query.Where(o => - (o.OrganisationName.Contains(organisationName, StringComparison.OrdinalIgnoreCase)) - || (o.OrganisationReference.Contains(organisationReference, StringComparison.OrdinalIgnoreCase))); - } - else - { - if (organisationNameSet) - { - query = query.Where(o => - o.OrganisationName.Contains(organisationName, StringComparison.OrdinalIgnoreCase)); - } - - if (organisationReferenceSet) - { - query = query.Where(o => - o.OrganisationReference.Contains(organisationReference, StringComparison.OrdinalIgnoreCase)); - } - } - - return query; - } - - public static IQueryable FilterByOrganisationType(this IQueryable query, - string organisationType) - { - if (!string.IsNullOrWhiteSpace(organisationType)) - { - query = query.Where(o => o.OrganisationType.Contains(organisationType, StringComparison.OrdinalIgnoreCase)); - } - return query; - } - - public static IQueryable FilterBySubmissionStatus(this IQueryable query, - string[] submissionStatuses) - { - if (submissionStatuses.Length != 0) - { - query = query.Where(o => submissionStatuses.Any(o.Decision.Contains)); - } - return query; - } -} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Core/MockedData/MockedAcceptedSubmissions.cs b/src/EPR.RegulatorService.Frontend.Core/MockedData/MockedAcceptedSubmissions.cs index c316faf7..baae06db 100644 --- a/src/EPR.RegulatorService.Frontend.Core/MockedData/MockedAcceptedSubmissions.cs +++ b/src/EPR.RegulatorService.Frontend.Core/MockedData/MockedAcceptedSubmissions.cs @@ -1,9 +1,12 @@ using System.Diagnostics.CodeAnalysis; using EPR.RegulatorService.Frontend.Core.Models.Submissions; +using System.Diagnostics.CodeAnalysis; +using EPR.RegulatorService.Frontend.Core.Enums; namespace EPR.RegulatorService.Frontend.Core.MockedData; [ExcludeFromCodeCoverage] +[SuppressMessage("Major Code Smell", "S2245:Random should not be used for security-sensitive applications", Justification = "Used only for generating test data")] public static class MockedAcceptedSubmissions { public static List GetMockedAcceptedSubmissions(int begin, int end) @@ -19,7 +22,7 @@ public static List GetMockedAcceptedSubmissions(int begin, int end) { OrganisationId = Guid.NewGuid(), OrganisationName = $"Organisation {i} Ltd", - OrganisationType = (i % 2) == 0 ? "Direct producer" : "Compliance scheme", + OrganisationType = (i % 2) == 0 ? OrganisationType.DirectProducer : OrganisationType.ComplianceScheme, OrganisationReference = i.ToString().PadLeft(6, '0').Insert(3, " "), Email = "test@abc.com", UserId = Guid.NewGuid(), diff --git a/src/EPR.RegulatorService.Frontend.Core/MockedData/MockedPendingSubmissions.cs b/src/EPR.RegulatorService.Frontend.Core/MockedData/MockedPendingSubmissions.cs index f8c1b2cf..66b91204 100644 --- a/src/EPR.RegulatorService.Frontend.Core/MockedData/MockedPendingSubmissions.cs +++ b/src/EPR.RegulatorService.Frontend.Core/MockedData/MockedPendingSubmissions.cs @@ -1,9 +1,12 @@ using System.Diagnostics.CodeAnalysis; using EPR.RegulatorService.Frontend.Core.Models.Submissions; +using System.Diagnostics.CodeAnalysis; +using EPR.RegulatorService.Frontend.Core.Enums; namespace EPR.RegulatorService.Frontend.Core.MockedData; [ExcludeFromCodeCoverage] +[SuppressMessage("Major Code Smell", "S2245:Random should not be used for security-sensitive applications", Justification = "Used only for generating test data")] public static class MockedPendingSubmissions { public static List GetMockedPendingSubmissions(int begin, int end) @@ -19,7 +22,7 @@ public static List GetMockedPendingSubmissions(int begin, int end) { OrganisationId = Guid.NewGuid(), OrganisationName = $"Organisation {i} Ltd", - OrganisationType = (i % 2) == 0 ? "Direct producer" : "Compliance scheme", + OrganisationType = (i % 2) == 0 ? OrganisationType.DirectProducer : OrganisationType.ComplianceScheme, OrganisationReference = i.ToString().PadLeft(6, '0').Insert(3, " "), Email = "test@abc.com", UserId = Guid.NewGuid(), @@ -29,6 +32,7 @@ public static List GetMockedPendingSubmissions(int begin, int end) ServiceRole = "Approved person", SubmissionId = Guid.NewGuid(), SubmittedDate = DateTime.Now.AddDays(-random.Next(2, 180)), + SubmissionPeriod = "July to December 2023", IsResubmission = isResubmission, Decision = "Pending", IsResubmissionRequired = false, diff --git a/src/EPR.RegulatorService.Frontend.Core/MockedData/MockedRejectedSubmissions.cs b/src/EPR.RegulatorService.Frontend.Core/MockedData/MockedRejectedSubmissions.cs index b5463e14..4ad6241d 100644 --- a/src/EPR.RegulatorService.Frontend.Core/MockedData/MockedRejectedSubmissions.cs +++ b/src/EPR.RegulatorService.Frontend.Core/MockedData/MockedRejectedSubmissions.cs @@ -1,9 +1,12 @@ using System.Diagnostics.CodeAnalysis; using EPR.RegulatorService.Frontend.Core.Models.Submissions; +using System.Diagnostics.CodeAnalysis; +using EPR.RegulatorService.Frontend.Core.Enums; namespace EPR.RegulatorService.Frontend.Core.MockedData; [ExcludeFromCodeCoverage] +[SuppressMessage("Major Code Smell", "S2245:Random should not be used for security-sensitive applications", Justification = "Used only for generating test data")] public static class MockedRejectedSubmissions { public static List GetMockedRejectedSubmissions(int begin, int end) @@ -19,7 +22,7 @@ public static List GetMockedRejectedSubmissions(int begin, int end) { OrganisationId = Guid.NewGuid(), OrganisationName = $"Organisation {i} Ltd", - OrganisationType = (i % 2) == 0 ? "Direct producer" : "Compliance scheme", + OrganisationType = (i % 2) == 0 ? OrganisationType.DirectProducer : OrganisationType.ComplianceScheme, OrganisationReference = i.ToString().PadLeft(6, '0').Insert(3, " "), Email = "test@abc.com", UserId = Guid.NewGuid(), diff --git a/src/EPR.RegulatorService.Frontend.Core/MockedData/Registrations/MockedAcceptedRegistrations.cs b/src/EPR.RegulatorService.Frontend.Core/MockedData/Registrations/MockedAcceptedRegistrations.cs index 22469978..5342864a 100644 --- a/src/EPR.RegulatorService.Frontend.Core/MockedData/Registrations/MockedAcceptedRegistrations.cs +++ b/src/EPR.RegulatorService.Frontend.Core/MockedData/Registrations/MockedAcceptedRegistrations.cs @@ -23,19 +23,39 @@ public static List GetMockedAcceptedRegistrations(int begin, int e OrganisationName = $"Organisation {i} Ltd", OrganisationType = (i % 2) == 0 ? OrganisationType.DirectProducer : OrganisationType.ComplianceScheme, OrganisationReference = i.ToString().PadLeft(6,'0').Insert(3, " "), + CompaniesHouseNumber = RandomNumberGenerator.GetInt32(1000000000).ToString(), + + BuildingName = "Building name", + SubBuildingName = "Sub-building name", + BuildingNumber = "Building number", + Street = "Street", + Locality = "Locality", + DependantLocality = "Dependant locality", + Town = "Town", + County = "County", + Country = "Country", + PostCode = "PostCode", Email = "test@abc.com", UserId = Guid.NewGuid(), - FirstName = "Test User", - LastName = "Test User", + FirstName = "Sally", + LastName = "Smith", Telephone = "0123 456 789", ServiceRole = "Approved person", - RegistrationId = Guid.NewGuid(), + SubmissionId = Guid.NewGuid(), + SubmissionPeriod = "January 2023 to June 2023", RegistrationDate = DateTime.Now.AddDays(-RandomNumberGenerator.GetInt32(2,180)), IsResubmission = isResubmission, Decision = "Accepted", - RejectionComments = String.Empty + RejectionComments = String.Empty, + PreviousRejectionComments = isResubmission ? "Rejected because reasons" : string.Empty, + OrganisationDetailsFileId = Guid.NewGuid(), + OrganisationDetailsFileName = "OrgDetails.csv", + PartnershipDetailsFileId = Guid.NewGuid(), + PartnershipDetailsFileName = "PartnerDetails.csv", + BrandDetailsFileId = Guid.NewGuid(), + BrandDetailsFileName = "BrandDetails.csv" }); } diff --git a/src/EPR.RegulatorService.Frontend.Core/MockedData/Registrations/MockedPendingRegistrations.cs b/src/EPR.RegulatorService.Frontend.Core/MockedData/Registrations/MockedPendingRegistrations.cs index 849874c7..d563b608 100644 --- a/src/EPR.RegulatorService.Frontend.Core/MockedData/Registrations/MockedPendingRegistrations.cs +++ b/src/EPR.RegulatorService.Frontend.Core/MockedData/Registrations/MockedPendingRegistrations.cs @@ -23,19 +23,39 @@ public static List GetMockedPendingRegistrations(int begin, int en OrganisationName = $"Organisation {i} Ltd", OrganisationType = (i % 2) == 0 ? OrganisationType.DirectProducer : OrganisationType.ComplianceScheme, OrganisationReference = i.ToString().PadLeft(6,'0').Insert(3, " "), + CompaniesHouseNumber = RandomNumberGenerator.GetInt32(1000000000).ToString(), + + BuildingName = "Building name", + SubBuildingName = "Sub-building name", + BuildingNumber = "Building number", + Street = "Street", + Locality = "Locality", + DependantLocality = "Dependant locality", + Town = "Town", + County = "County", + Country = "Country", + PostCode = "PostCode", Email = "test@abc.com", UserId = Guid.NewGuid(), - FirstName = "Test User", - LastName = "Test User", + FirstName = "Sally", + LastName = "Smith", Telephone = "0123 456 789", ServiceRole = "Approved person", - RegistrationId = Guid.NewGuid(), + SubmissionId = Guid.NewGuid(), + SubmissionPeriod = "January 2023 to June 2023", RegistrationDate = DateTime.Now.AddDays(-RandomNumberGenerator.GetInt32(2, 180)), IsResubmission = isResubmission, Decision = "Pending", - RejectionComments = isResubmission ? "Missing data / wrong submission period" : String.Empty + PreviousRejectionComments = isResubmission ? "Missing data / wrong submission period" : String.Empty, + + OrganisationDetailsFileId = Guid.NewGuid(), + OrganisationDetailsFileName = "OrgDetails.csv", + PartnershipDetailsFileId = Guid.NewGuid(), + BrandDetailsFileId = Guid.NewGuid(), + PartnershipDetailsFileName = "PartnerDetails.csv", + BrandDetailsFileName = "BrandDetails.csv" }); } diff --git a/src/EPR.RegulatorService.Frontend.Core/MockedData/Registrations/MockedRejectedRegistrations.cs b/src/EPR.RegulatorService.Frontend.Core/MockedData/Registrations/MockedRejectedRegistrations.cs index a1b704ab..524a8105 100644 --- a/src/EPR.RegulatorService.Frontend.Core/MockedData/Registrations/MockedRejectedRegistrations.cs +++ b/src/EPR.RegulatorService.Frontend.Core/MockedData/Registrations/MockedRejectedRegistrations.cs @@ -24,19 +24,39 @@ public static List GetMockedRejectedRegistrations(int begin, int e OrganisationName = $"Organisation {i} Ltd", OrganisationType = (i % 2) == 0 ? OrganisationType.DirectProducer : OrganisationType.ComplianceScheme, OrganisationReference = i.ToString().PadLeft(6,'0').Insert(3, " "), + CompaniesHouseNumber = RandomNumberGenerator.GetInt32(1000000000).ToString(), + + BuildingName = "Building name", + SubBuildingName = "Sub-building name", + BuildingNumber = "Building number", + Street = "Street", + Locality = "Locality", + DependantLocality = "Dependant locality", + Town = "Town", + County = "County", + Country = "Country", + PostCode = "PostCode", Email = "test@abc.com", UserId = Guid.NewGuid(), - FirstName = "Test User", - LastName = "Test User", + FirstName = "Sally", + LastName = "Smith", Telephone = "0123 456 789", ServiceRole = "Approved person", - RegistrationId = Guid.NewGuid(), + SubmissionId = Guid.NewGuid(), + SubmissionPeriod = "January 2023 to June 2023", RegistrationDate = DateTime.Now.AddDays(-RandomNumberGenerator.GetInt32(2, 180)), IsResubmission = isResubmission, Decision = "Rejected", - RejectionComments = "Missing data / wrong submission period" + RejectionComments = "Missing data / wrong submission period", + + OrganisationDetailsFileId = Guid.NewGuid(), + OrganisationDetailsFileName = "OrgDetails.csv", + PartnershipDetailsFileId = Guid.NewGuid(), + PartnershipDetailsFileName = "PartnerDetails.csv", + BrandDetailsFileId = Guid.NewGuid(), + BrandDetailsFileName = "BrandDetails.csv" }); } diff --git a/src/EPR.RegulatorService.Frontend.Core/Models/AbstractSubmission.cs b/src/EPR.RegulatorService.Frontend.Core/Models/AbstractSubmission.cs new file mode 100644 index 00000000..9ab69ab3 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Core/Models/AbstractSubmission.cs @@ -0,0 +1,24 @@ +namespace EPR.RegulatorService.Frontend.Core.Models; + +using Enums; + +public class AbstractSubmission +{ + public Guid SubmissionId { get; set; } + public DateTime SubmittedDate { get; set; } + public string? Decision { get; set; } = string.Empty; + public bool IsResubmission { get; set; } + public Guid OrganisationId { get; set; } + public string? OrganisationName { get; set; } + public string? OrganisationReference { get; set; } + public OrganisationType OrganisationType { get; set; } + public Guid? UserId { get; set; } + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? Email { get; set; } + public string? Telephone { get; set; } + public string? ServiceRole { get; set; } + public string? SubmissionPeriod { get; set; } + public string? Comments { get; set; } + public string? PreviousRejectionComments { get; set; } +} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Core/Models/Registrations/Registration.cs b/src/EPR.RegulatorService.Frontend.Core/Models/Registrations/Registration.cs index 6a108110..9c6bc5b0 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Models/Registrations/Registration.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Models/Registrations/Registration.cs @@ -1,30 +1,29 @@ -using EPR.RegulatorService.Frontend.Core.Enums; using System.Diagnostics.CodeAnalysis; namespace EPR.RegulatorService.Frontend.Core.Models.Registrations; [ExcludeFromCodeCoverage] -public class Registration +public class Registration : AbstractSubmission { - public Guid RegistrationId { get; set; } public DateTime RegistrationDate { get; set; } - public string? Decision { get; set; } = string.Empty; - public bool IsResubmission { get; set; } public string RejectionComments { get; set; } = string.Empty; - public Guid OrganisationId { get; set; } - public string? OrganisationName { get; set; } - public OrganisationType OrganisationType { get; set; } - public string? OrganisationReference { get; set; } - public Guid? UserId { get; set; } - public string? FirstName { get; set; } - public string? LastName { get; set; } - public string? Email { get; set; } - public string? Telephone { get; set; } - public string? ServiceRole { get; set; } - public string CompanyDetailsField { get; set; } + public string? CompaniesHouseNumber { get; set; } + public string? BuildingName { get; set; } + public string? SubBuildingName { get; set; } + public string? BuildingNumber { get; set; } + public string? Street { get; set; } + public string? Locality { get; set; } + public string? DependantLocality { get; set; } + public string? Town { get; set; } + public string? County { get; set; } + public string? Country { get; set; } + public string? PostCode { get; set; } + public Guid OrganisationDetailsFileId { get; set; } + public string OrganisationDetailsFileName { get; set; } + public Guid CompanyDetailsFileId { get; set; } public string CompanyDetailsFileName { get; set; } - public string PartnershipFileName { get; set; } - public string PartnershipFileId { get; set; } - public string BrandsFileName { get; set; } - public string BrandsFileId { get; set; } + public Guid? PartnershipDetailsFileId { get; set; } + public string PartnershipDetailsFileName { get; set; } + public Guid? BrandDetailsFileId { get; set; } + public string BrandDetailsFileName { get; set; } } diff --git a/src/EPR.RegulatorService.Frontend.Core/Models/Registrations/RegistrationSubmission.cs b/src/EPR.RegulatorService.Frontend.Core/Models/Registrations/RegistrationSubmission.cs new file mode 100644 index 00000000..8e0311bf --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Core/Models/Registrations/RegistrationSubmission.cs @@ -0,0 +1,34 @@ +namespace EPR.RegulatorService.Frontend.Core.Models.Registrations; + +using System.Diagnostics.CodeAnalysis; + +[ExcludeFromCodeCoverage] +public class RegistrationSubmission +{ + public Guid SubmissionId { get; set; } + public DateTime RegistrationDate { get; set; } + public string? Decision { get; set; } = string.Empty; + public bool IsResubmission { get; set; } + public Guid OrganisationId { get; set; } + public Guid? ComplianceSchemeId { get; set; } + public string? OrganisationName { get; set; } + public string? OrganisationReference { get; set; } + public string? CompaniesHouseNumber { get; set; } + public string? OrganisationType { get; set; } + public string? ProducerType { get; set; } + public Guid? UserId { get; set; } + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? Email { get; set; } + public string? Telephone { get; set; } + public string? ServiceRole { get; set; } + public Guid FileId { get; set; } + public string? SubmissionPeriod { get; set; } + public string? Comments { get; set; } + public Guid CompanyDetailsFileId { get; set; } + public string CompanyDetailsFileName { get; set; } + public Guid? PartnershipFileId { get; set; } + public string? PartnershipFileName { get; set; } + public Guid? BrandsFileId { get; set; } + public string? BrandsFileName { get; set; } +} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Core/Models/Registrations/RegulatorRegistrationDecisionCreateRequest.cs b/src/EPR.RegulatorService.Frontend.Core/Models/Registrations/RegulatorRegistrationDecisionCreateRequest.cs new file mode 100644 index 00000000..b821e9ba --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Core/Models/Registrations/RegulatorRegistrationDecisionCreateRequest.cs @@ -0,0 +1,21 @@ +namespace EPR.RegulatorService.Frontend.Core.Models.Registrations +{ + using Enums; + + public class RegulatorRegistrationDecisionCreateRequest + { + public Guid SubmissionId { get; set; } + + public RegulatorDecision Decision { get; set; } + + public string? Comments { get; set; } + + public Guid FileId { get; set; } + + public Guid OrganisationId { get; set; } + + public string OrganisationNumber { get; set; } + + public string OrganisationName { get; set; } + } +} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Core/Models/Submissions/Submission.cs b/src/EPR.RegulatorService.Frontend.Core/Models/Submissions/Submission.cs index 9f74406d..398355b6 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Models/Submissions/Submission.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Models/Submissions/Submission.cs @@ -1,26 +1,11 @@ namespace EPR.RegulatorService.Frontend.Core.Models.Submissions; -public class Submission +using Enums; + +public class Submission : AbstractSubmission { - public Guid SubmissionId { get; set; } - public DateTime SubmittedDate { get; set; } - public string? Decision { get; set; } = string.Empty; - public bool IsResubmission { get; set; } public bool IsResubmissionRequired { get; set; } - public Guid OrganisationId { get; set; } - public Guid? ComplianceSchemeId { get; set; } - public string? OrganisationName { get; set; } - public string? OrganisationReference { get; set; } - public string? OrganisationType { get; set; } - public string? ProducerType { get; set; } - public Guid? UserId { get; set; } - public string? FirstName { get; set; } - public string? LastName { get; set; } - public string? Email { get; set; } - public string? Telephone { get; set; } - public string? ServiceRole { get; set; } public Guid FileId { get; set; } - public string? SubmissionPeriod { get; set; } - public string? Comments { get; set; } - public string? PreviousRejectionComments { get; set; } + public string? ProducerType { get; set; } + public Guid? ComplianceSchemeId { get; set; } } \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Core/Services/FacadeService.cs b/src/EPR.RegulatorService.Frontend.Core/Services/FacadeService.cs index c308dcd2..0a574168 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Services/FacadeService.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Services/FacadeService.cs @@ -1,24 +1,22 @@ -using System.Net; -using System.Net.Http.Headers; -using System.Net.Http.Json; using EPR.RegulatorService.Frontend.Core.Configs; +using EPR.RegulatorService.Frontend.Core.Enums; using EPR.RegulatorService.Frontend.Core.Models; using EPR.RegulatorService.Frontend.Core.Models.Pagination; +using EPR.RegulatorService.Frontend.Core.Models.Registrations; using EPR.RegulatorService.Frontend.Core.Models.Submissions; using Microsoft.Extensions.Options; using Microsoft.Identity.Web; +using System.Net; +using System.Net.Http.Headers; +using System.Net.Http.Json; using System.Text.Json; -using EPR.RegulatorService.Frontend.Core.Models.Registrations; namespace EPR.RegulatorService.Frontend.Core.Services; -using Enums; - public class FacadeService : IFacadeService { private const string UpdateEnrolmentEndpointKey = "UpdateEnrolment"; private const string PendingApplicationsEndpointKey = "PendingApplications"; - private const string PomSubmissionsEndpointKey = "PomSubmissions"; private const string PomSubmissionDecision = "PomSubmissionDecision"; private const string SendEnrolmentUpdatedEmailsEndpointKey = "SendEnrolmentUpdatedEmails"; private const string UserAccountEndpointKey = "UserAccounts"; @@ -31,6 +29,7 @@ public class FacadeService : IFacadeService private const string OrganisationsRemoveApprovedUserPath = "OrganisationsRemoveApprovedUser"; private const string InviteNewApprovedPersonPath = "InviteNewApprovedPerson"; private const string AddRemoveApprovedUserPath = "AddRemoveApprovedUser"; + private const string RegistrationSubmissionDecisionPath = "RegistrationSubmissionDecisionPath"; private readonly string[] _scopes; private readonly HttpClient _httpClient; @@ -51,6 +50,12 @@ public FacadeService( _scopes = new[] {_facadeApiConfig.DownstreamScope}; } + private static readonly Dictionary _typeToEndpointMap = new() + { + { typeof(Submission), "PomSubmissions" }, + { typeof(Registration), "RegistrationSubmissions" } + }; + public async Task GetTestMessageAsync() { var response = await _httpClient.GetAsync("/api/test"); @@ -175,12 +180,12 @@ public async Task GetUserAccountDetails() return response; } - public async Task> GetOrganisationSubmissions( + public async Task> GetOrganisationSubmissions( string? organisationName, string? organisationReference, - string? organisationType, + OrganisationType? organisationType, string[]? status, - int currentPage = 1) + int currentPage = 1) where T : AbstractSubmission { await PrepareAuthenticatedClient(); @@ -199,22 +204,27 @@ public async Task> GetOrganisationSubmissions( query["organisationReference"] = organisationReference; } - if (!string.IsNullOrEmpty(organisationType)) + if (organisationType.HasValue) + { + query["organisationType"] = organisationType.ToString(); + } + else { - query["organisationType"] = organisationType; + query["organisationType"] = "All"; } - if (status != null) + if (status is {Length: > 0}) { - query["Statuses"] = string.Join(',', status); + query["statuses"] = string.Join(',', status); } var queryString = string.Join("&", query.Select(kvp => $"{kvp.Key}={Uri.EscapeDataString(kvp.Value)}")); - var path = $"{_facadeApiConfig.Endpoints[PomSubmissionsEndpointKey]}?{queryString}"; + var endpointKey = _typeToEndpointMap[typeof(T)]; + var path = $"{_facadeApiConfig.Endpoints[endpointKey]}?{queryString}"; var response = await _httpClient.GetAsync(path); response.EnsureSuccessStatusCode(); - return await response.Content.ReadFromJsonAsync>(); + return await response.Content.ReadFromJsonAsync>(); } public async Task SubmitPoMDecision(RegulatorPoMDecisionCreateRequest request) @@ -261,17 +271,6 @@ public async Task RemoveApprovedUser(RemoveApprovedUserR return response.IsSuccessStatusCode ? EndpointResponseStatus.Success : EndpointResponseStatus.Fail; } - public Task RejectSubmission() => throw new NotImplementedException(); - - public Task AcceptSubmission() => throw new NotImplementedException(); - - public Task> GetRegulatorRegistrations( - string? organisationName, - string? organisationReference, - OrganisationType? organisationType, - string[]? status, - int currentPage = 1) => - throw new NotImplementedException(); public async Task AddRemoveApprovedUser(AddRemoveApprovedUserRequest request) { @@ -283,6 +282,16 @@ public async Task AddRemoveApprovedUser(AddRemoveApprove return response.IsSuccessStatusCode ? EndpointResponseStatus.Success : EndpointResponseStatus.Fail; } + public async Task SubmitRegistrationDecision(RegulatorRegistrationDecisionCreateRequest request) + { + await PrepareAuthenticatedClient(); + + string path = _facadeApiConfig.Endpoints[RegistrationSubmissionDecisionPath]; + var response = await _httpClient.PostAsJsonAsync(path, request); + + return response.IsSuccessStatusCode ? EndpointResponseStatus.Success : EndpointResponseStatus.Fail; + } + private async Task PrepareAuthenticatedClient() { if (_httpClient.BaseAddress == null) diff --git a/src/EPR.RegulatorService.Frontend.Core/Services/IFacadeService.cs b/src/EPR.RegulatorService.Frontend.Core/Services/IFacadeService.cs index dde72960..64ebce76 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Services/IFacadeService.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Services/IFacadeService.cs @@ -1,13 +1,11 @@ +using EPR.RegulatorService.Frontend.Core.Enums; using EPR.RegulatorService.Frontend.Core.Models; using EPR.RegulatorService.Frontend.Core.Models.Pagination; +using EPR.RegulatorService.Frontend.Core.Models.Registrations; using EPR.RegulatorService.Frontend.Core.Models.Submissions; namespace EPR.RegulatorService.Frontend.Core.Services; -using Enums; - -using Models.Registrations; - public interface IFacadeService { Task GetTestMessageAsync(); @@ -31,13 +29,6 @@ Task> GetUserApplicationsByOrganisation( Task GetUserAccountDetails(); - Task> GetOrganisationSubmissions( - string? organisationName, - string? organisationReference, - string? organisationType, - string[]? status, - int currentPage = 1); - Task SubmitPoMDecision(RegulatorPoMDecisionCreateRequest request); Task> GetOrganisationBySearchTerm(string searchTerm, int currentPage = 1); @@ -46,16 +37,14 @@ Task> GetOrganisationSubmissions( Task RemoveApprovedUser(RemoveApprovedUserRequest request); - public Task RejectSubmission(); - Task AcceptSubmission(); - - Task> GetRegulatorRegistrations( + Task> GetOrganisationSubmissions( string? organisationName, string? organisationReference, OrganisationType? organisationType, string[]? status, - int currentPage = 1); + int currentPage = 1) where T : AbstractSubmission; Task AddRemoveApprovedUser(AddRemoveApprovedUserRequest request); + Task SubmitRegistrationDecision(RegulatorRegistrationDecisionCreateRequest request); } diff --git a/src/EPR.RegulatorService.Frontend.Core/Services/MockedFacadeService.cs b/src/EPR.RegulatorService.Frontend.Core/Services/MockedFacadeService.cs index 2399c785..19e74117 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Services/MockedFacadeService.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Services/MockedFacadeService.cs @@ -1,15 +1,15 @@ using EPR.RegulatorService.Frontend.Core.Configs; +using EPR.RegulatorService.Frontend.Core.Enums; using EPR.RegulatorService.Frontend.Core.MockedData; using EPR.RegulatorService.Frontend.Core.MockedData.Filters; using EPR.RegulatorService.Frontend.Core.MockedData.Registrations; using EPR.RegulatorService.Frontend.Core.Models; using EPR.RegulatorService.Frontend.Core.Models.Pagination; -using EPR.RegulatorService.Frontend.Core.Models.Submissions; using EPR.RegulatorService.Frontend.Core.Models.Registrations; +using EPR.RegulatorService.Frontend.Core.Models.Submissions; using Microsoft.Extensions.Options; using System.Diagnostics.CodeAnalysis; using System.Net; -using EPR.RegulatorService.Frontend.Core.Enums; using System.Security.Cryptography; namespace EPR.RegulatorService.Frontend.Core.Services; @@ -219,42 +219,6 @@ public Task GetUserAccountDetails() return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)); } - public Task> GetOrganisationSubmissions( - string? organisationName, - string? organisationReference, - string? organisationType, - string[]? status, - int currentPage = 1) - { - if (currentPage > (int)Math.Ceiling(_allSubmissions.Count / (double)_config.PageSize)) - { - currentPage = 1; - } - - var results = _allSubmissions - .AsQueryable() - .FilterByOrganisationNameAndOrganisationReference(organisationName, organisationReference) - .FilterByOrganisationType(organisationType) - .FilterBySubmissionStatus(status).ToList(); - - var response = new PaginatedList - { - Items = results - .OrderBy(x => x.Decision == Accepted) - .ThenBy(x => x.Decision == Rejected) - .ThenBy(x => x.Decision == Pending) - .ThenBy(x => x.IsResubmission) - .Skip((currentPage - 1) * _config.PageSize) - .Take(_config.PageSize) - .ToList(), - CurrentPage = currentPage, - TotalItems = results.Count, - PageSize = _config.PageSize - }; - - return Task.FromResult(response); - } - public async Task SubmitPoMDecision(RegulatorPoMDecisionCreateRequest request) => EndpointResponseStatus.Success; public Task> GetOrganisationBySearchTerm(string searchTerm, int currentPage = 1) @@ -304,9 +268,38 @@ public Task> GetProducerOrganisationUsersByOrganisationEx public async Task RemoveApprovedUser(RemoveApprovedUserRequest request) => EndpointResponseStatus.Success; public async Task RemoveApprovedUser(Guid connExternalId, Guid organisationId) => EndpointResponseStatus.Success; - public async Task RejectSubmission() => EndpointResponseStatus.Success; - public async Task AcceptSubmission() => EndpointResponseStatus.Success; + public async Task SubmitRegistrationDecision( + RegulatorRegistrationDecisionCreateRequest request) => EndpointResponseStatus.Success; + + public async Task> GetOrganisationSubmissions(string? organisationName, string? organisationReference, + OrganisationType? organisationType, string[]? status, int currentPage = 1) where T : AbstractSubmission + { + var items = typeof(T) == typeof(Submission) + ? _allSubmissions.Cast().ToList() + : _allRegistrations.Cast().ToList(); + + if (currentPage > (int)Math.Ceiling(_allSubmissions.Count / (double)_config.PageSize)) + { + currentPage = 1; + } + + var results = items + .AsQueryable() + .FilterByOrganisationNameAndOrganisationReference(organisationName, organisationReference) + .FilterByOrganisationType(organisationType) + .FilterByStatus(status).ToList(); + + var response = new PaginatedList + { + Items = await FilterSubmissions(results, currentPage), + CurrentPage = currentPage, + TotalItems = results.Count, + PageSize = _config.PageSize + }; + + return response; + } private static List GenerateRegulatorRegistrations() { @@ -319,27 +312,26 @@ private static List GenerateRegulatorRegistrations() return allItems; } - public async Task> GetRegulatorRegistrations( - string? organisationName, - string? organisationReference, - OrganisationType? organisationType, - string[]? status, - int currentPage = 1) + public async Task> FilterSubmissions( + IList items, int currentPage) where T : AbstractSubmission { - if (currentPage > (int)Math.Ceiling(_allRegistrations.Count / (double)_config.PageSize)) + if (typeof(T) == typeof(Submission)) { - currentPage = 1; - } + var filteredItems = items.OfType() + .OrderBy(x => x.Decision == Accepted) + .ThenBy(x => x.Decision == Rejected) + .ThenBy(x => x.Decision == Pending) + .ThenBy(x => x.IsResubmission) + .Skip((currentPage - 1) * _config.PageSize) + .Take(_config.PageSize) + .ToList(); - var results = _allRegistrations - .AsQueryable() - .FilterByOrganisationNameAndOrganisationReference(organisationName, organisationReference) - .FilterByOrganisationType(organisationType) - .FilterByRegistrationStatus(status).ToList(); + return filteredItems.Cast().ToList(); + } - var response = new PaginatedList + if (typeof(T) == typeof(Registration)) { - Items = results + var filteredItems = items.OfType() .OrderBy(x => x.Decision == Accepted) .ThenBy(x => x.Decision == Rejected) .ThenBy(x => x.Decision == Pending) @@ -347,13 +339,12 @@ public async Task> GetRegulatorRegistrations( .ThenBy(x => x.IsResubmission) .Skip((currentPage - 1) * _config.PageSize) .Take(_config.PageSize) - .ToList(), - CurrentPage = currentPage, - TotalItems = results.Count, - PageSize = _config.PageSize - }; + .ToList(); - return response; + return filteredItems.Cast().ToList(); + } + + return new List(); } public async Task AddRemoveApprovedUser(AddRemoveApprovedUserRequest request) => await Task.FromResult(EndpointResponseStatus.Success); diff --git a/src/EPR.RegulatorService.Frontend.Core/Sessions/RegulatorRegistrationSession.cs b/src/EPR.RegulatorService.Frontend.Core/Sessions/RegulatorRegistrationSession.cs index d6ffc783..24db350d 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Sessions/RegulatorRegistrationSession.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Sessions/RegulatorRegistrationSession.cs @@ -5,8 +5,8 @@ namespace EPR.RegulatorService.Frontend.Core.Sessions; public class RegulatorRegistrationSession { public List Journey { get; set; } = new(); + public Registration OrganisationRegistration { get; set; } - public RejectRegistrationJourneyData? RejectRegistrationJourneyData { get; set; } public RegistrationFiltersModel? RegistrationFiltersModel { get; set; } = new(); public int? PageNumber { get; set; } } diff --git a/src/EPR.RegulatorService.Frontend.Core/Sessions/RejectRegistrationJourneyData.cs b/src/EPR.RegulatorService.Frontend.Core/Sessions/RejectRegistrationJourneyData.cs index c4d3ce26..b0257807 100644 --- a/src/EPR.RegulatorService.Frontend.Core/Sessions/RejectRegistrationJourneyData.cs +++ b/src/EPR.RegulatorService.Frontend.Core/Sessions/RejectRegistrationJourneyData.cs @@ -6,6 +6,6 @@ namespace EPR.RegulatorService.Frontend.Core.Sessions; public class RejectRegistrationJourneyData { public string? OrganisationName { get; set; } - public Guid RejectionId { get; set; } + public Guid SubmissionId { get; set; } public string? SubmittedBy { get; set; } } diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Core/Converters/OrganisationTypeConverterTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Core/Converters/OrganisationTypeConverterTests.cs new file mode 100644 index 00000000..53025538 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Core/Converters/OrganisationTypeConverterTests.cs @@ -0,0 +1,71 @@ +namespace EPR.RegulatorService.Frontend.UnitTests.Core.Converters; + +using System.Text.Json; +using Frontend.Core.Converters; +using Frontend.Core.Enums; + +[TestClass] +public class OrganisationTypeConverterTests +{ + private JsonSerializerOptions _options; + + [TestInitialize] + public void TestInitialize() + { + _options = new JsonSerializerOptions + { + Converters = { new OrganisationTypeConverter() } + }; + } + + [TestMethod] + public void Deserialize_DirectProducer_ShouldReturnDirectProducerEnum() + { + string json = "\"Direct Producer\""; + + var result = JsonSerializer.Deserialize(json, _options); + + result.Should().Be(OrganisationType.DirectProducer); + } + + [TestMethod] + public void Deserialize_ComplianceScheme_ShouldReturnComplianceSchemeEnum() + { + string json = "\"Compliance Scheme\""; + + var result = JsonSerializer.Deserialize(json, _options); + + result.Should().Be(OrganisationType.ComplianceScheme); + } + + [TestMethod] + public void Deserialize_InvalidString_ShouldThrowJsonException() + { + string json = "\"Invalid String\""; + + Action act = () => JsonSerializer.Deserialize(json, _options); + + act.Should().Throw() + .WithMessage("*Value 'Invalid String' is not valid for OrganisationType*"); + } + + [TestMethod] + public void Serialize_DirectProducer_ShouldReturnCorrectString() + { + var enumValue = OrganisationType.DirectProducer; + + var json = JsonSerializer.Serialize(enumValue, _options); + + json.Should().Be("\"Direct Producer\""); + } + + [TestMethod] + public void Serialize_ComplianceScheme_ShouldReturnCorrectString() + { + var enumValue = OrganisationType.ComplianceScheme; + + var json = JsonSerializer.Serialize(enumValue, _options); + + json.Should().Be("\"Compliance Scheme\""); + } +} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Core/Extensions/BoolExtensionMethodsTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Core/Extensions/BoolExtensionMethodsTests.cs new file mode 100644 index 00000000..043477cc --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Core/Extensions/BoolExtensionMethodsTests.cs @@ -0,0 +1,33 @@ +namespace EPR.RegulatorService.Frontend.UnitTests.Core.Extensions; + +using Frontend.Core.Extensions; + +[TestClass] +public class BoolExtensionMethodsTests +{ + [TestMethod] + public void ToYesNo_WhenTrue_ShouldReturnYes() + { + // Arrange + bool testValue = true; + + // Act + var result = testValue.ToYesNo(); + + // Assert + result.Should().Be("Yes", "because calling ToYesNo on true should return 'Yes'"); + } + + [TestMethod] + public void ToYesNo_WhenFalse_ShouldReturnNo() + { + // Arrange + bool testValue = false; + + // Act + var result = testValue.ToYesNo(); + + // Assert + result.Should().Be("No", "because calling ToYesNo on false should return 'No'"); + } +} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Core/Filters/AbstractSubmissionsFiltersTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Core/Filters/AbstractSubmissionsFiltersTests.cs new file mode 100644 index 00000000..644289a7 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Core/Filters/AbstractSubmissionsFiltersTests.cs @@ -0,0 +1,172 @@ +using AutoFixture; +using EPR.RegulatorService.Frontend.Core.Enums; +using EPR.RegulatorService.Frontend.Core.MockedData.Filters; +using EPR.RegulatorService.Frontend.Core.Models; + +namespace EPR.RegulatorService.Frontend.UnitTests.Core.Filters; + +[TestClass] +public class AbstractSubmissionFiltersTests +{ + private IQueryable _abstractSubmissions; + private Fixture _fixture; + + [TestInitialize] + public void Initialize() + { + _fixture = new Fixture(); + _abstractSubmissions = _fixture + .Build() + .With(x => x.Decision, GetRandomStatus) + .CreateMany(30) + .AsQueryable(); + } + + public string GetRandomStatus() + { + string[] statuses = { "Pending", "Rejected", "Accepted" }; + Random random = new Random(); + int index = random.Next(statuses.Length); + return statuses[index]; + } + + [TestMethod] + [DataRow(1)] + [DataRow(5)] + [DataRow(7)] + [DataRow(12)] + [DataRow(23)] + public void FilterByOrganisationNameAndOrganisationReference_OnlyOrgRef_ReturnsMatch(int itemIndex) + { + var expectedSubmission = _abstractSubmissions.ToList()[itemIndex]; + + var result = + _abstractSubmissions + .FilterByOrganisationNameAndOrganisationReference( + string.Empty, + expectedSubmission.OrganisationReference); + + result.Should().Contain(expectedSubmission); + result.Count().Should().Be(1); + } + + [TestMethod] + [DataRow(1)] + [DataRow(5)] + [DataRow(7)] + [DataRow(12)] + [DataRow(23)] + public void FilterByOrganisationNameAndOrganisationReference_OnlyOrgName_ReturnsMatch(int itemIndex) + { + var expectedSubmission = _abstractSubmissions.ToList()[itemIndex]; + + var result = + _abstractSubmissions + .FilterByOrganisationNameAndOrganisationReference( + expectedSubmission.OrganisationName, + String.Empty); + + result.Should().Contain(expectedSubmission); + result.Count().Should().Be(1); + } + + [TestMethod] + [DataRow(1,4)] + [DataRow(5,2)] + [DataRow(7,9)] + [DataRow(12,20)] + [DataRow(23,13)] + public void FilterByOrganisationNameAndOrganisationReference_OrgNameAndRef_ReturnsMatch(int itemIndexRef, int itemIndexName) + { + var submissionList = _abstractSubmissions.ToList(); + var expectedSubmissionRef = submissionList[itemIndexRef]; + var expectedSubmissionName = submissionList[itemIndexName]; + + var result = + _abstractSubmissions + .FilterByOrganisationNameAndOrganisationReference( + expectedSubmissionName.OrganisationName, + expectedSubmissionRef.OrganisationReference); + + result.Should().Contain(expectedSubmissionRef); + result.Should().Contain(expectedSubmissionName); + result.Count().Should().Be(2); + } + + [TestMethod] + public void FilterByOrganisationNameAndOrganisationReference_NoValues_ReturnsAll() + { + var result = + _abstractSubmissions + .FilterByOrganisationNameAndOrganisationReference( + string.Empty, + string.Empty); + + result.Should().BeEquivalentTo(_abstractSubmissions); + } + + [TestMethod] + public void FilterByOrganisationType_NullType_ReturnsAll() + { + var result = + _abstractSubmissions + .FilterByOrganisationType(null); + + result.Should().BeEquivalentTo(_abstractSubmissions); + } + + [TestMethod] + [DataRow(OrganisationType.ComplianceScheme)] + [DataRow(OrganisationType.DirectProducer)] + public void FilterByOrganisationType_OrgTypeProvided_ReturnsOnlyMatches(OrganisationType orgType) + { + var expectedSubmissions = + _abstractSubmissions.Where(x => x.OrganisationType == orgType); + + var result = + _abstractSubmissions + .FilterByOrganisationType(orgType); + + result.Should().BeEquivalentTo(expectedSubmissions); + } + + [TestMethod] + public void FilterByStatus_Null_ReturnsAll() + { + var result = + _abstractSubmissions + .FilterByStatus(null); + + result.Should().BeEquivalentTo(_abstractSubmissions); + } + + [TestMethod] + public void FilterByStatus_EmptyArray_ReturnsAll() + { + var result = + _abstractSubmissions + .FilterByStatus(new string[]{}); + + result.Should().BeEquivalentTo(_abstractSubmissions); + } + + [TestMethod] + [DataRow(new[]{"Pending"})] + [DataRow(new[]{"Accepted"})] + [DataRow(new[]{"Rejected"})] + [DataRow(new[]{"Pending", "Accepted"})] + [DataRow(new[]{"Pending", "Rejected"})] + [DataRow(new[]{"Accepted", "Rejected"})] + [DataRow(new[]{"Pending", "Accepted", "Rejected"})] + public void FilterByStatus_StatusesPassed_ReturnsOnlyMatches(string[] statusArray) + { + var expectedSubmissions = + _abstractSubmissions.Where(x => statusArray.Contains(x.Decision)); + + var result = + _abstractSubmissions + .FilterByStatus(statusArray); + + result.Should().BeEquivalentTo(expectedSubmissions); + } +} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Core/Services/FacadeServiceTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Core/Services/FacadeServiceTests.cs index dc4706f0..c10dd2ca 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/Core/Services/FacadeServiceTests.cs +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Core/Services/FacadeServiceTests.cs @@ -1,19 +1,20 @@ +using AutoFixture; using EPR.RegulatorService.Frontend.Core.Configs; +using EPR.RegulatorService.Frontend.Core.Enums; using EPR.RegulatorService.Frontend.Core.MockedData; using EPR.RegulatorService.Frontend.Core.Models; using EPR.RegulatorService.Frontend.Core.Models.CompanyDetails; using EPR.RegulatorService.Frontend.Core.Models.Pagination; +using EPR.RegulatorService.Frontend.Core.Models.Registrations; +using EPR.RegulatorService.Frontend.Core.Models.Submissions; using EPR.RegulatorService.Frontend.Core.Services; -using AutoFixture; -using Moq; -using Moq.Protected; using Microsoft.Extensions.Options; using Microsoft.Identity.Web; +using Moq; +using Moq.Protected; using System.Net; -using System.Text.Json; using System.Text; -using EPR.RegulatorService.Frontend.Core.Models.Submissions; - +using System.Text.Json; namespace EPR.RegulatorService.Frontend.UnitTests.Core.Services { @@ -56,11 +57,13 @@ public void Setup() ["OrganisationsSearchPath"] = "organisations/search-organisations?currentPage={0}&pageSize={1}&searchTerm={2}", ["OrganisationDetails"] = "organisations/organisation-details?externalId={0}", ["GetOrganisationUsersByOrganisationExternalIdPath"] = "organisations/users-by-organisation-external-id?externalId={0}", - ["PomSubmissions"] = "http://testurl.com", + ["PomSubmissions"] = "http://testurl.com/PomSubmissions", + ["RegistrationSubmissions"] = "http://testurl.com/RegistrationSubmissions", ["OrganisationsSearchPath"] = "organisations/search-organisations?currentPage={0}&pageSize={1}&searchTerm={2}", ["PomSubmissionDecision"] = "http://testurl.com", ["OrganisationsRemoveApprovedUser"] = "organisations/remove-approved-users?connExternalId={0}&organisationId={1}&promotedPersonExternalId={2}", - ["AddRemoveApprovedUser"] = "/accounts-management/add-remove-approved-users" + ["AddRemoveApprovedUser"] = "/accounts-management/add-remove-approved-users", + ["RegistrationSubmissionDecisionPath"] = "http://testurl.com" } }); @@ -563,7 +566,7 @@ public async Task GetUserAccountDetails_WhenNoSpecificRequirements_ThenReturnOkR } [TestMethod] - public async Task GetOrganisationSubmissions_ShouldReturnPaginatedList_WhenRequestIsCorrect() + public async Task GetOrganisationPomSubmissions_ShouldReturnPaginatedList_WhenRequestIsCorrect() { // Arrange var testOrgAppList = _fixture.Create>(); @@ -583,11 +586,96 @@ public async Task GetOrganisationSubmissions_ShouldReturnPaginatedList_WhenReque .ReturnsAsync(httpResponseMessage); // Act - var result = await _facadeService.GetOrganisationSubmissions(null, null, null,null, 1); + var result = await _facadeService.GetOrganisationSubmissions(null, null, null,null, 1); + + // Assert + result.Should().BeEquivalentTo(testOrgAppList); + _mockHandler.Protected() + .Verify>( + "SendAsync", + Times.Once(), + ItExpr.Is(req => req.RequestUri.ToString().Contains("PomSubmissions")), + ItExpr.IsAny()); + + httpResponseMessage.Dispose(); + } + + [TestMethod] + public async Task GetOrganisationRegistrationSubmissions_ShouldReturnPaginatedList_WhenRequestIsCorrect() + { + // Arrange + var testOrgAppList = _fixture.Create>(); + string jsonContent = JsonSerializer.Serialize(testOrgAppList); + + var httpResponseMessage = new HttpResponseMessage + { + StatusCode = HttpStatusCode.OK, + Content = new StringContent(jsonContent, Encoding.UTF8, "application/json"), + }; + + _mockHandler.Protected() + .Setup>( + "SendAsync", + ItExpr.IsAny(), + ItExpr.IsAny()) + .ReturnsAsync(httpResponseMessage); + + // Act + var result = await _facadeService.GetOrganisationSubmissions((string?) null, (string?) null, (OrganisationType?) null,null, 1); + + // Assert + result.Should().BeEquivalentTo(testOrgAppList); + _mockHandler.Protected() + .Verify>( + "SendAsync", + Times.Once(), + ItExpr.Is(req => req.RequestUri.ToString().Contains("RegistrationSubmissions")), + ItExpr.IsAny()); + + httpResponseMessage.Dispose(); + } + + [TestMethod] + public async Task GetOrganisationSubmissions_ParamsAdded_ShouldPassToFacade() + { + // Arrange + var testOrgAppList = _fixture.Create>(); + string jsonContent = JsonSerializer.Serialize(testOrgAppList); + + var httpResponseMessage = new HttpResponseMessage + { + StatusCode = HttpStatusCode.OK, + Content = new StringContent(jsonContent, Encoding.UTF8, "application/json"), + }; + + _mockHandler.Protected() + .Setup>( + "SendAsync", + ItExpr.IsAny(), + ItExpr.IsAny()) + .ReturnsAsync(httpResponseMessage); + + var statuses = new[] {"Pending", "Accepted"}; + + // Act + var result = + await _facadeService.GetOrganisationSubmissions("orgName", "orgRef", OrganisationType.ComplianceScheme, statuses, 2); // Assert result.Should().BeEquivalentTo(testOrgAppList); + var expectedQueryString = + "pageNumber=2&pageSize=10&organisationName=orgName&organisationReference=orgRef&organisationType=ComplianceScheme&statuses=Pending%2CAccepted"; + + _mockHandler.Protected() + .Verify>( + "SendAsync", + Times.Once(), + ItExpr.Is( + req => req.RequestUri.ToString().Contains("RegistrationSubmissions") + && req.RequestUri.ToString().Contains(expectedQueryString)), + ItExpr.IsAny()); + httpResponseMessage.Dispose(); } @@ -859,5 +947,55 @@ public async Task AddRemoveApprovedUser_WhenHttpStatusCodeBadRequest_ThenReturnF Assert.IsNotNull(result); result.Should().Be(EndpointResponseStatus.Fail); } + + [TestMethod] + public async Task SubmitRegistrationDecision_WhenHttpStatusCodeOk_ThenReturnSuccess() + { + // Arrange + var request = new RegulatorRegistrationDecisionCreateRequest(); + + var httpTestHandler = new HttpResponseMessage + { + StatusCode = HttpStatusCode.OK + }; + + _mockHandler.Protected() + .Setup>( + "SendAsync", + ItExpr.IsAny(), + ItExpr.IsAny()) + .ReturnsAsync(httpTestHandler); + + // Act + var result = await _facadeService.SubmitRegistrationDecision(request); + + // Assert + result.Should().Be(EndpointResponseStatus.Success); + } + + [TestMethod] + public async Task SubmitRegistrationDecision_WhenHttpStatusCodeBadRequest_ThenReturnFail() + { + // Arrange + var request = new RegulatorRegistrationDecisionCreateRequest(); + + var httpTestHandler = new HttpResponseMessage + { + StatusCode = HttpStatusCode.BadRequest + }; + + _mockHandler.Protected() + .Setup>( + "SendAsync", + ItExpr.IsAny(), + ItExpr.IsAny()) + .ReturnsAsync(httpTestHandler); + + // Act + var result = await _facadeService.SubmitRegistrationDecision(request); + + // Assert + result.Should().Be(EndpointResponseStatus.Fail); + } } } \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/EPR.RegulatorService.Frontend.UnitTests.csproj b/src/EPR.RegulatorService.Frontend.UnitTests/EPR.RegulatorService.Frontend.UnitTests.csproj index fba25f7f..642309d0 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/EPR.RegulatorService.Frontend.UnitTests.csproj +++ b/src/EPR.RegulatorService.Frontend.UnitTests/EPR.RegulatorService.Frontend.UnitTests.csproj @@ -30,4 +30,5 @@ + diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/MockedData/MockedRegistrationFiltersTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/MockedData/MockedRegistrationFiltersTests.cs index dadc1786..baa43dd8 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/MockedData/MockedRegistrationFiltersTests.cs +++ b/src/EPR.RegulatorService.Frontend.UnitTests/MockedData/MockedRegistrationFiltersTests.cs @@ -74,7 +74,7 @@ public async Task Test_Filter_By_Registration_Status_Accepted() { var results = _allRegistrations .AsQueryable() - .FilterByRegistrationStatus(new []{ Accepted }).ToList(); + .FilterByStatus(new []{ Accepted }).ToList(); Assert.IsNotNull(results); results.Should().HaveCount(2); @@ -85,7 +85,7 @@ public async Task Test_Filter_By_Registration_Status_Rejected() { var results = _allRegistrations .AsQueryable() - .FilterByRegistrationStatus(new []{ Rejected }).ToList(); + .FilterByStatus(new []{ Rejected }).ToList(); Assert.IsNotNull(results); results.Should().HaveCount(2); @@ -96,7 +96,7 @@ public async Task Test_Filter_By_Registration_Status_Pending() { var results = _allRegistrations .AsQueryable() - .FilterByRegistrationStatus(new []{ Pending }).ToList(); + .FilterByStatus(new []{ Pending }).ToList(); Assert.IsNotNull(results); results.Should().HaveCount(2); @@ -107,7 +107,7 @@ public async Task Test_Filter_By_Registration_Status_Accepted_And_Pending() { var results = _allRegistrations .AsQueryable() - .FilterByRegistrationStatus(new []{ Accepted, Pending }).ToList(); + .FilterByStatus(new []{ Accepted, Pending }).ToList(); Assert.IsNotNull(results); results.Should().HaveCount(4); @@ -118,7 +118,7 @@ public async Task Test_Filter_By_Registration_Status_Rejected_And_Pending() { var results = _allRegistrations .AsQueryable() - .FilterByRegistrationStatus(new []{ Rejected, Pending }).ToList(); + .FilterByStatus(new []{ Rejected, Pending }).ToList(); Assert.IsNotNull(results); results.Should().HaveCount(4); diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/MockedData/MockedSubmissionFiltersTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/MockedData/MockedSubmissionFiltersTests.cs index 215ecfe5..1bd68b6c 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/MockedData/MockedSubmissionFiltersTests.cs +++ b/src/EPR.RegulatorService.Frontend.UnitTests/MockedData/MockedSubmissionFiltersTests.cs @@ -1,5 +1,6 @@ namespace EPR.RegulatorService.Frontend.UnitTests.MockedData; +using Frontend.Core.Enums; using Frontend.Core.MockedData.Filters; using Frontend.Core.Models.Submissions; @@ -29,9 +30,9 @@ public async Task Test_Filter_By_Organisation_Name_And_Organisation_Reference() } [TestMethod] - [DataRow(DirectProducer)] - [DataRow(ComplianceScheme)] - public async Task Test_Filter_By_Organisation_Type(string organisationType) + [DataRow(OrganisationType.DirectProducer)] + [DataRow(OrganisationType.ComplianceScheme)] + public async Task Test_Filter_By_Organisation_Type(OrganisationType organisationType) { var results = _allSubmissions .AsQueryable() @@ -46,7 +47,7 @@ public async Task Test_Filter_By_Submission_Status_Accepted() { var results = _allSubmissions .AsQueryable() - .FilterBySubmissionStatus(new []{ Accepted }).ToList(); + .FilterByStatus(new []{ Accepted }).ToList(); Assert.IsNotNull(results); results.Should().HaveCount(2); @@ -57,7 +58,7 @@ public async Task Test_Filter_By_Submission_Status_Rejected() { var results = _allSubmissions .AsQueryable() - .FilterBySubmissionStatus(new []{ Rejected }).ToList(); + .FilterByStatus(new []{ Rejected }).ToList(); Assert.IsNotNull(results); results.Should().HaveCount(2); @@ -68,7 +69,7 @@ public async Task Test_Filter_By_Submission_Status_Pending() { var results = _allSubmissions .AsQueryable() - .FilterBySubmissionStatus(new []{ Pending }).ToList(); + .FilterByStatus(new []{ Pending }).ToList(); Assert.IsNotNull(results); results.Should().HaveCount(2); @@ -79,7 +80,7 @@ public async Task Test_Filter_By_Submission_Status_Accepted_And_Pending() { var results = _allSubmissions .AsQueryable() - .FilterBySubmissionStatus(new []{ Accepted, Pending }).ToList(); + .FilterByStatus(new []{ Accepted, Pending }).ToList(); Assert.IsNotNull(results); results.Should().HaveCount(4); @@ -90,7 +91,7 @@ public async Task Test_Filter_By_Submission_Status_Rejected_And_Pending() { var results = _allSubmissions .AsQueryable() - .FilterBySubmissionStatus(new []{ Rejected, Pending }).ToList(); + .FilterByStatus(new []{ Rejected, Pending }).ToList(); Assert.IsNotNull(results); results.Should().HaveCount(4); @@ -104,42 +105,42 @@ private static List GenerateOrganisationSubmissions() { OrganisationName = "DirectProducer_Accepted_111111", OrganisationReference = "111 111", - OrganisationType = DirectProducer, + OrganisationType = OrganisationType.DirectProducer, Decision = Accepted }, new() { OrganisationName = "ComplianceScheme_Accepted_123456", OrganisationReference = "123 456", - OrganisationType = ComplianceScheme, + OrganisationType = OrganisationType.ComplianceScheme, Decision = Accepted }, new() { OrganisationName = "DirectProducer_Rejected_222222", OrganisationReference = "222 222", - OrganisationType = DirectProducer, + OrganisationType = OrganisationType.DirectProducer, Decision = Rejected }, new() { OrganisationName = "ComplianceScheme_Rejected_333333", OrganisationReference = "333 333", - OrganisationType = ComplianceScheme, + OrganisationType = OrganisationType.ComplianceScheme, Decision = Rejected }, new() { OrganisationName = "DirectProducer_Pending_444444", OrganisationReference = "444 444", - OrganisationType = DirectProducer, + OrganisationType = OrganisationType.DirectProducer, Decision = Pending }, new() { OrganisationName = "ComplianceScheme_Pending_555555", OrganisationReference = "555 555", - OrganisationType = ComplianceScheme, + OrganisationType = OrganisationType.ComplianceScheme, Decision = Pending } }; diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/TestData/TestSubmission.cs b/src/EPR.RegulatorService.Frontend.UnitTests/TestData/TestSubmission.cs index a00980a7..550d7a8d 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/TestData/TestSubmission.cs +++ b/src/EPR.RegulatorService.Frontend.UnitTests/TestData/TestSubmission.cs @@ -3,6 +3,9 @@ namespace EPR.RegulatorService.Frontend.UnitTests.TestData { + using Frontend.Core.Enums; + using Frontend.Core.Extensions; + public static class TestSubmission { public static Submission GetTestSubmission() => @@ -16,7 +19,7 @@ public static Submission GetTestSubmission() => Comments = string.Empty, OrganisationId = Guid.NewGuid(), OrganisationName = "Test Org Ltd.", - OrganisationType = "Direct producer", + OrganisationType = OrganisationType.DirectProducer, OrganisationReference = "123 456", Email = "test@abc.com", UserId = Guid.NewGuid(), diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/AccountControllerTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/AccountControllerTests.cs index d48890ae..ec328b2f 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/AccountControllerTests.cs +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/AccountControllerTests.cs @@ -1,10 +1,14 @@ +using EPR.RegulatorService.Frontend.Web.Constants; +using System.Text; using EPR.RegulatorService.Frontend.Web.Controllers.Account; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Routing; using Microsoft.Extensions.Options; using Microsoft.Identity.Web; using Moq; +using System.Text.Json; namespace EPR.RegulatorService.Frontend.UnitTests.Web.Controllers { @@ -14,6 +18,7 @@ public class AccountControllerTests private AccountController _systemUnderTest = default!; private Mock> _microsoftIdentityOptionsMonitor = null!; private Mock _mockUrlHelperMock = null!; + private Mock _mockSession = null!; private readonly string _scheme = OpenIdConnectDefaults.AuthenticationScheme; [TestInitialize] @@ -25,10 +30,12 @@ public void Setup() _microsoftIdentityOptionsMonitor.Setup(x => x.Get(_scheme)).Returns(new MicrosoftIdentityOptions { ResetPasswordPolicyId = "ResetPasswordPolicyId" }); _mockUrlHelperMock = new Mock(); + _mockSession = new Mock(); var httpContext = new DefaultHttpContext(); httpContext.Request.Headers["X-Custom-Header"] = "88-test-tcb"; httpContext.Request.Scheme = _scheme; + httpContext.Session = _mockSession.Object; var controllerContext = new ControllerContext() { @@ -131,5 +138,35 @@ public void WhenSignOut_WithInvalidLocalUri_ThenReturnLocalUri() Assert.AreEqual(expected: 2, actual: response.AuthenticationSchemes.Count); Assert.IsNotNull(response.Properties); } + + [TestMethod] + [DataRow(null, "culture", false, DisplayName = "Null")] + [DataRow("", "culture", false, DisplayName = "Empty")] + [DataRow(Language.English, $"\"culture\":\"{Language.English}\"", true, DisplayName = "Lang")] + public void WhenSignOut_WithSelectedCulture_ThenIncludeCultureInRedirect( + string culture, + string searchString, + bool expectedResult) + { + // Arrange + byte[]? outCulture = culture != null ? Encoding.UTF8.GetBytes(culture) : null; + _mockSession.Setup(x => x.TryGetValue(Language.SessionLanguageKey, out outCulture)); + + _mockUrlHelperMock + .Setup(m => m.Action(It.IsAny())) + .Returns((UrlActionContext c) => JsonSerializer.Serialize(c.Values)); + + // Act + var result = _systemUnderTest.SignOut(_scheme); + + // Assert + Assert.IsNotNull(result); + result.Should().BeOfType(); + var response = result as SignOutResult; + Assert.IsNotNull(response); + Assert.AreEqual(expected: 2, actual: response.AuthenticationSchemes.Count); + Assert.IsNotNull(response.Properties); + Assert.AreEqual(response.Properties.RedirectUri.Contains(searchString), expectedResult); + } } } diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RegistrationControllerTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RegistrationControllerTests.cs deleted file mode 100644 index 4d100fc8..00000000 --- a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RegistrationControllerTests.cs +++ /dev/null @@ -1,128 +0,0 @@ -using EPR.RegulatorService.Frontend.Web.Constants; -using EPR.RegulatorService.Frontend.Web.ViewModels.Registrations; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Moq; -using EPR.RegulatorService.Frontend.Core.Models.Registrations; -using EPR.RegulatorService.Frontend.Core.Sessions; - -namespace EPR.RegulatorService.Frontend.UnitTests.Web.Controllers -{ - [TestClass] - public class RegistrationControllerTests : RegistrationTestBase - { - [TestInitialize] - public void Setup() - { - SetupBase(); - - } - - [TestMethod] - public async Task RegistrationsGet_CreatesNewSessionAndReturnsView() - { - // Act - var result = await _sut.Registrations(null, null); - - // Assert - result.Should().NotBeNull(); - result.Should().BeOfType(); - - var viewResult = result as ViewResult; - viewResult.Should().NotBeNull(); - - var journeySession = await _sessionManagerMock.Object.GetSessionAsync(It.IsAny()); - journeySession.Should().NotBeNull(); - } - - [TestMethod] - public async Task RegistrationsGet_NewPageNumber_UpdatesCurrentPage() - { - // Act - var result = await _sut.Registrations(5, null); - - // Assert - result.Should().NotBeNull(); - result.Should().BeOfType(); - - var viewResult = result as ViewResult; - viewResult.Should().NotBeNull(); - var registrationsViewModel = viewResult.Model as RegistrationsViewModel; - registrationsViewModel.PageNumber.Should().Be(5); - } - - [TestMethod] - public async Task RegistrationsPost_WithNullSession_CreatesNewSessionAndReturnsView() - { - // Act - var result = await _sut.Registrations(new RegistrationFiltersModel()); - - // Assert - result.Should().NotBeNull(); - result.Should().BeOfType(); - - var viewResult = result as RedirectToActionResult; - viewResult.Should().NotBeNull(); - viewResult.RouteValues.Should().BeNull(); - - var journeySession = await _sessionManagerMock.Object.GetSessionAsync(It.IsAny()); - journeySession.Should().NotBeNull(); - } - - [TestMethod] - public async Task RegistrationsPost_WithValidSession_ReturnsCorrectViewAndModel_Where_SelectedFiltersOverwriteSessionFilters_And_IsFilteredSearch() - { - // Arrange - var registrationFiltersModel = GetRegistrationFiltersModel(); - SetupJourneySession(registrationFiltersModel); - - // Act - var result = await _sut.Registrations(registrationFiltersModel); - - // Assert - result.Should().NotBeNull(); - result.Should().BeOfType(); - - var viewResult = result as RedirectToActionResult; - viewResult.Should().NotBeNull(); - viewResult.RouteValues.Should().BeNull(); - - var journeySession = await _sessionManagerMock.Object.GetSessionAsync(It.IsAny()); - var registrationFiltersModelFromSession = journeySession.RegulatorRegistrationSession.RegistrationFiltersModel; - registrationFiltersModelFromSession.SearchOrganisationName.Should().Be("Test Organisation"); - registrationFiltersModelFromSession.SearchOrganisationId.Should().Be("123"); - registrationFiltersModelFromSession.IsDirectProducerChecked.Should().BeTrue(); - registrationFiltersModelFromSession.IsComplianceSchemeChecked.Should().BeTrue(); - registrationFiltersModelFromSession.IsPendingRegistrationChecked.Should().BeTrue(); - registrationFiltersModelFromSession.IsAcceptedRegistrationChecked.Should().BeTrue(); - registrationFiltersModelFromSession.IsRejectedRegistrationChecked.Should().BeTrue(); - } - - [TestMethod] - public async Task RegistrationsPost_WithValidSession_ReturnsCorrectViewAndModel_Where_SessionFiltersApplied_And_Not_IsFilteredSearch() - { - // Arrange - SetupJourneySession(new RegistrationFiltersModel()); - - var result = await _sut.Registrations(new RegistrationFiltersModel()); - - // Assert - result.Should().NotBeNull(); - result.Should().BeOfType(); - - var viewResult = result as RedirectToActionResult; - viewResult.Should().NotBeNull(); - viewResult.RouteValues.Should().BeNull(); - - var journeySession = await _sessionManagerMock.Object.GetSessionAsync(It.IsAny()); - var registrationFiltersModel = journeySession.RegulatorRegistrationSession.RegistrationFiltersModel; - registrationFiltersModel.SearchOrganisationName.Should().BeEmpty(); - registrationFiltersModel.SearchOrganisationId.Should().BeEmpty(); - registrationFiltersModel.IsDirectProducerChecked.Should().BeFalse(); - registrationFiltersModel.IsComplianceSchemeChecked.Should().BeFalse(); - registrationFiltersModel.IsPendingRegistrationChecked.Should().BeFalse(); - registrationFiltersModel.IsAcceptedRegistrationChecked.Should().BeFalse(); - registrationFiltersModel.IsRejectedRegistrationChecked.Should().BeFalse(); - } - } -} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RegistrationTestBase.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RegistrationTestBase.cs index 336d69ae..dfb8f751 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RegistrationTestBase.cs +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RegistrationTestBase.cs @@ -57,7 +57,7 @@ protected void SetupBase(UserData userData = null) _urlsOptionMock.Setup(mock => mock.Value).Returns(new ExternalUrlsOptions { PowerBiLogin = PowerBiLogin }); _sut = new RegistrationsController(_sessionManagerMock.Object, _configurationMock.Object, - _urlsOptionMock.Object); + _urlsOptionMock.Object, _facadeServiceMock.Object); _sut.ControllerContext.HttpContext = _httpContextMock.Object; } @@ -74,13 +74,14 @@ private void SetUpUserData(UserData? userData) _httpContextMock.Setup(x => x.User).Returns(_userMock.Object); } - public void SetupJourneySession(RegistrationFiltersModel registrationFiltersModel) + public void SetupJourneySession(RegistrationFiltersModel registrationFiltersModel, Registration registration = null) { JourneySessionMock = new JourneySession() { RegulatorRegistrationSession = new RegulatorRegistrationSession() { - RegistrationFiltersModel = registrationFiltersModel, PageNumber = 1 + RegistrationFiltersModel = registrationFiltersModel, PageNumber = 1, + OrganisationRegistration = registration } }; diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RegistrationsControllerTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RegistrationsControllerTests.cs new file mode 100644 index 00000000..2824d944 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RegistrationsControllerTests.cs @@ -0,0 +1,219 @@ +namespace EPR.RegulatorService.Frontend.UnitTests.Web.Controllers +{ + using AutoFixture; + using Frontend.Core.Enums; + using Frontend.Core.Extensions; + using Frontend.Core.Models.Registrations; + using Frontend.Web.ViewModels.Registrations; + using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Mvc; + using Moq; + + [TestClass] + public class RegistrationsControllerTests : RegistrationTestBase + { + private Fixture _fixture; + + [TestInitialize] + public void Setup() + { + _fixture = new Fixture(); + SetupBase(); + } + + [TestMethod] + public async Task RegistrationsGet_CreatesNewSessionAndReturnsView() + { + // Act + var result = await _sut.Registrations(new RegistrationFiltersModel(), null, false); + + // Assert + result.Should().NotBeNull(); + result.Should().BeOfType(); + + var viewResult = result as ViewResult; + viewResult.Should().NotBeNull(); + + var journeySession = await _sessionManagerMock.Object.GetSessionAsync(It.IsAny()); + journeySession.Should().NotBeNull(); + } + + [TestMethod] + public async Task RegistrationsGet_NewPageNumber_UpdatesCurrentPage() + { + // Act + var result = await _sut.Registrations(new RegistrationFiltersModel(), 5, false); + + // Assert + result.Should().NotBeNull(); + result.Should().BeOfType(); + + var viewResult = result as ViewResult; + viewResult.Should().NotBeNull(); + var registrationsViewModel = viewResult.Model as RegistrationsViewModel; + registrationsViewModel.PageNumber.Should().Be(5); + } + + [TestMethod] + public async Task RegistrationsPost_WithNullSession_CreatesNewSessionAndReturnsView() + { + // Act + var result = await _sut.Registrations(new RegistrationFiltersModel(), 1, false); + + // Assert + result.Should().NotBeNull(); + result.Should().BeOfType(); + + var viewResult = result as ViewResult; + viewResult.Should().NotBeNull(); + + var journeySession = await _sessionManagerMock.Object.GetSessionAsync(It.IsAny()); + journeySession.Should().NotBeNull(); + } + + [TestMethod] + public async Task RegistrationsPost_WithValidSession_ReturnsCorrectViewAndModel_Where_SelectedFiltersOverwriteSessionFilters_And_IsFilteredSearch() + { + // Arrange + var registrationFiltersModel = GetRegistrationFiltersModel(); + SetupJourneySession(registrationFiltersModel); + + // Act + var result = await _sut.Registrations(registrationFiltersModel, 1, false); + + // Assert + result.Should().NotBeNull(); + result.Should().BeOfType(); + + var viewResult = result as ViewResult; + viewResult.Should().NotBeNull(); + + var journeySession = await _sessionManagerMock.Object.GetSessionAsync(It.IsAny()); + var registrationFiltersModelFromSession = journeySession.RegulatorRegistrationSession.RegistrationFiltersModel; + registrationFiltersModelFromSession.SearchOrganisationName.Should().Be("Test Organisation"); + registrationFiltersModelFromSession.SearchOrganisationId.Should().Be("123"); + registrationFiltersModelFromSession.IsDirectProducerChecked.Should().BeTrue(); + registrationFiltersModelFromSession.IsComplianceSchemeChecked.Should().BeTrue(); + registrationFiltersModelFromSession.IsPendingRegistrationChecked.Should().BeTrue(); + registrationFiltersModelFromSession.IsAcceptedRegistrationChecked.Should().BeTrue(); + registrationFiltersModelFromSession.IsRejectedRegistrationChecked.Should().BeTrue(); + } + + [TestMethod] + public async Task RegistrationsPost_WithValidSession_ReturnsCorrectViewAndModel_Where_SessionFiltersApplied_And_Not_IsFilteredSearch() + { + // Arrange + SetupJourneySession(new RegistrationFiltersModel()); + + var result = await _sut.Registrations(new RegistrationFiltersModel(), 1, false); + + // Assert + result.Should().NotBeNull(); + result.Should().BeOfType(); + + var viewResult = result as ViewResult; + viewResult.Should().NotBeNull(); + + var journeySession = await _sessionManagerMock.Object.GetSessionAsync(It.IsAny()); + var registrationFiltersModel = journeySession.RegulatorRegistrationSession.RegistrationFiltersModel; + registrationFiltersModel.SearchOrganisationName.Should().BeEmpty(); + registrationFiltersModel.SearchOrganisationId.Should().BeEmpty(); + registrationFiltersModel.IsDirectProducerChecked.Should().BeFalse(); + registrationFiltersModel.IsComplianceSchemeChecked.Should().BeFalse(); + registrationFiltersModel.IsPendingRegistrationChecked.Should().BeFalse(); + registrationFiltersModel.IsAcceptedRegistrationChecked.Should().BeFalse(); + registrationFiltersModel.IsRejectedRegistrationChecked.Should().BeFalse(); + } + + [TestMethod] + public async Task RegistrationsPost_WithClearFiltersTrue_ReturnsClearedFilter() + { + // Arrange + SetupJourneySession(GetRegistrationFiltersModel()); + + var result = await _sut.Registrations(new RegistrationFiltersModel(), 1, true); + + // Assert + result.Should().NotBeNull(); + result.Should().BeOfType(); + + var viewResult = result as ViewResult; + viewResult.Should().NotBeNull(); + + var journeySession = await _sessionManagerMock.Object.GetSessionAsync(It.IsAny()); + var registrationFiltersModel = journeySession.RegulatorRegistrationSession.RegistrationFiltersModel; + registrationFiltersModel.SearchOrganisationName.Should().BeEmpty(); + registrationFiltersModel.SearchOrganisationId.Should().BeEmpty(); + registrationFiltersModel.IsDirectProducerChecked.Should().BeFalse(); + registrationFiltersModel.IsComplianceSchemeChecked.Should().BeFalse(); + registrationFiltersModel.IsPendingRegistrationChecked.Should().BeFalse(); + registrationFiltersModel.IsAcceptedRegistrationChecked.Should().BeFalse(); + registrationFiltersModel.IsRejectedRegistrationChecked.Should().BeFalse(); + } + + [TestMethod] + public async Task Submissions_WithNullSession_CreatesNewSessionAndRedirectsToSubmissionDetails() + { + // Act + var result = await _sut.Registrations("{\r\n \"SubmissionId\": \"a3f6c7b8-9d4e-4f9a-bcde-1234567890ab\",\r\n \"SubmissionDate\": \"2023-10-30T10:51:23Z\",\r\n \"SubmissionStatus\": \"Pending\",\r\n \"IsResubmission\": false,\r\n \"IsResubmissionRequired\": false,\r\n \"RejectionComments\": \"\",\r\n \"Organisation\": {\r\n \"OrganisationId\": \"d4e5f6a7-b8c9-0d1e-2f3a-9876543210cd\",\r\n \"OrganisationName\": \"Acme Inc.\",\r\n \"OrganisationType\": \"Private\"\r\n }\r\n}\r\n"); + + // Assert + result.Should().BeOfType(); + + var actionResult = result as RedirectToActionResult; + actionResult?.ControllerName.Should().Be("Registrations"); + actionResult?.ActionName.Should().Be("RegistrationDetails"); + } + + [TestMethod] + public async Task RegistrationDetails_ReturnsCorrectViewModel() + { + // Arrange + var registration = _fixture.Create(); + SetupJourneySession(GetRegistrationFiltersModel(), registration); + + // Act + var result = await _sut.RegistrationDetails(); + + // Assert + result.Should().BeOfType(); + var viewResult = result as ViewResult; + viewResult.Model.Should().BeOfType(); + var model = viewResult.Model as RegistrationDetailsViewModel; + + model.OrganisationName.Should().Be(registration.OrganisationName); + model.BuildingName.Should().Be(registration.BuildingName); + model.SubBuildingName.Should().Be(registration.SubBuildingName); + model.BuildingNumber.Should().Be(registration.BuildingNumber); + model.Street.Should().Be(registration.Street); + model.Locality.Should().Be(registration.Locality); + model.DependantLocality.Should().Be(registration.DependantLocality); + model.Town.Should().Be(registration.Town); + model.County.Should().Be(registration.County); + model.Country.Should().Be(registration.Country); + model.PostCode.Should().Be(registration.PostCode); + model.OrganisationType.Should().Be(registration.OrganisationType.GetDescription()); + model.OrganisationReferenceNumber.Should().Be(registration.OrganisationReference); + model.SubmissionId.Should().Be(registration.SubmissionId); + model.SubmissionPeriod.Should().Be(registration.SubmissionPeriod); + model.SubmittedBy.Should().Be($"{registration.FirstName} {registration.LastName}"); + model.AccountRole.Should().Be(registration.ServiceRole); + model.Telephone.Should().Be(registration.Telephone); + model.Email.Should().Be(registration.Email); + model.Status.Should().Be(registration.Decision); + model.IsResubmission.Should().Be(registration.IsResubmission); + model.RejectionReason.Should().Be(registration.RejectionComments); + model.PreviousRejectionReason.Should().Be(registration.PreviousRejectionComments); + model.CompaniesHouseNumber.Should().Be(registration.CompaniesHouseNumber); + model.OrganisationDetailsFileId.Should().Be(registration.OrganisationDetailsFileId); + model.OrganisationDetailsFileName.Should().Be(registration.OrganisationDetailsFileName); + model.PartnershipDetailsFileId.Should().Be(registration.PartnershipDetailsFileId); + model.PartnershipDetailsFileName.Should().Be(registration.PartnershipDetailsFileName); + model.BrandDetailsFileId.Should().Be(registration.BrandDetailsFileId); + model.BrandDetailsFileName.Should().Be(registration.BrandDetailsFileName); + model.DeclaredBy.Should().Be(registration.OrganisationType == OrganisationType.ComplianceScheme + ? "Not required (compliance scheme)" + : $"{registration.FirstName} {registration.LastName}"); + } + } +} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RejectRegistrationTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RejectRegistrationTests.cs new file mode 100644 index 00000000..4bb1f41b --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/RejectRegistrationTests.cs @@ -0,0 +1,122 @@ +namespace EPR.RegulatorService.Frontend.UnitTests.Web.Controllers +{ + using Frontend.Core.Models; + using Frontend.Core.Models.Registrations; + using Frontend.Core.Sessions; + using Frontend.Web.Constants; + using Frontend.Web.Controllers.Registrations; + using Frontend.Web.ViewModels.Registrations; + + using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Mvc; + + using Moq; + + [TestClass] + public class RejectRegistrationTests : RegistrationTestBase + { + private const string RejectRegistrationViewName = "RejectRegistration"; + private const string OrganisationName = "Test Organisation"; + private const string ModelError = "Test Model Error"; + private readonly Guid _submissionId = Guid.NewGuid(); + private readonly Guid _fileId = Guid.NewGuid(); + + [TestInitialize] + public void Setup() + { + SetupBase(); + + JourneySessionMock = new JourneySession + { + RegulatorRegistrationSession = new RegulatorRegistrationSession + { + Journey = new List + { + PagePath.Registrations, PagePath.RegistrationDetails, PagePath.RejectRegistration + }, + OrganisationRegistration = new Registration + { + OrganisationDetailsFileId = _fileId, + OrganisationName = OrganisationName, + SubmissionId = _submissionId + } + } + }; + + _sessionManagerMock.Setup(x => x.GetSessionAsync(It.IsAny())) + .ReturnsAsync(JourneySessionMock); + } + + [TestMethod] + public async Task RejectRegistrationGet_WhenAccessedFromRegistrationDetails_SetsBackLinkCorrectly() + { + // Act + var viewResult = await _sut.RejectRegistration() as ViewResult; + + // Assert + Assert.IsNotNull(viewResult); + viewResult.ViewName.Should().Be(RejectRegistrationViewName); + AssertBackLink(viewResult, PagePath.RegistrationDetails); + } + + [TestMethod] + public async Task RejectRegistrationPost_WhenModelInvalid_CreatesValidationError() + { + + // Arrange + var viewModel = new RejectRegistrationViewModel() + { + ReasonForRejection = null, + }; + + _sut.ModelState.AddModelError(ModelErrorKey, ModelError); + + _facadeServiceMock.Setup(x => x.SubmitRegistrationDecision(It.IsAny())) + .ReturnsAsync(EndpointResponseStatus.Success); + + // Act + var result = await _sut.RejectRegistration(viewModel) as ViewResult; + + // Assert + Assert.IsNotNull(result); + result.ViewName.Should().Be(RejectRegistrationViewName); + Assert.AreEqual( + expected: result.ViewData.ModelState[ModelErrorKey]!.Errors[0].ErrorMessage, + actual: ModelError + ); + + _facadeServiceMock.Verify(x => x.SubmitRegistrationDecision(It.IsAny()), + Times.Never); + } + + [TestMethod] + public async Task RejectRegistrationPost_WhenValidModelAndSession_CreatesDecisionAndRedirects() + { + // Arrange + var viewModel = new RejectRegistrationViewModel() + { + ReasonForRejection = string.Empty, + }; + + _facadeServiceMock.Setup(x => x.SubmitRegistrationDecision(It.IsAny())) + .ReturnsAsync(EndpointResponseStatus.Success); + + // Act + var result = await _sut.RejectRegistration(viewModel) as RedirectToActionResult; + + // Assert + Assert.IsNotNull(result); + result.ActionName.Should().Be(nameof(RegistrationsController.Registrations)); + + var routeValues = result.RouteValues; + Assert.IsNotNull(routeValues); + routeValues.Values.Should().Contain(EndpointResponseStatus.Success); + routeValues.Values.Should().Contain(OrganisationName); + + _facadeServiceMock.Verify(x => x.SubmitRegistrationDecision(It.IsAny()), + Times.Once); + _sessionManagerMock.Verify(x => x.SaveSessionAsync(It.IsAny(), It.IsAny()), + Times.Once); + } + } +} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/SubmissionControllerTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/SubmissionControllerTests.cs index b05cf3f3..7cc35630 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/SubmissionControllerTests.cs +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Controllers/SubmissionControllerTests.cs @@ -308,15 +308,6 @@ public async Task Applications_WithValidSession_ReturnsCorrectViewAndModel_Where viewModel.IsRejectedSubmissionChecked.Should().BeFalse(); } - [TestMethod] - public void Given_TimeAndDateForSubmission_Set_Then_FormatTimeAndDateForSubmission_As_String() - { - DateTime timeAndDateOfSubmission = new(2023, 11, 11, 13, 11, 11); - string result = _systemUnderTest.FormatTimeAndDateForSubmission(timeAndDateOfSubmission); - - result.Should().BeEquivalentTo("1:11pm on 11 November 2023"); - } - [TestMethod] public async Task Submissions_WithNullSession_CreatesNewSessionAndRedirectsToSubmissionDetails() { diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Helpers/DateTimeHelpersTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Helpers/DateTimeHelpersTests.cs new file mode 100644 index 00000000..9e789cd4 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Helpers/DateTimeHelpersTests.cs @@ -0,0 +1,43 @@ +namespace EPR.RegulatorService.Frontend.UnitTests.Web.Helpers; + +using AutoFixture; +using Frontend.Web.Helpers; + +public class DateTimeHelpersTests +{ + private Fixture _fixture; + + [TestInitialize] + public void Initialize() + { + _fixture = new Fixture(); + } + + [TestMethod] + public void FormatTimeAndDateForSubmission_ShouldFormatCorrectlyForAMTime() + { + // Arrange + var timeAndDateOfSubmission = _fixture.Create().Date.AddHours(9); // 9 AM + var expectedFormat = $"{timeAndDateOfSubmission:h:mm}am on {timeAndDateOfSubmission:dd MMMM yyyy}"; + + // Act + var result = DateTimeHelpers.FormatTimeAndDateForSubmission(timeAndDateOfSubmission); + + // Assert + result.Should().Be(expectedFormat); + } + + [TestMethod] + public void FormatTimeAndDateForSubmission_ShouldFormatCorrectlyForPMTime() + { + // Arrange + var timeAndDateOfSubmission = _fixture.Create().Date.AddHours(15); // 3 PM + var expectedFormat = $"{timeAndDateOfSubmission:h:mm}pm on {timeAndDateOfSubmission:dd MMMM yyyy}"; + + // Act + var result = DateTimeHelpers.FormatTimeAndDateForSubmission(timeAndDateOfSubmission); + + // Assert + result.Should().Be(expectedFormat); + } +} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Sessions/SessionManagerTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Sessions/SessionManagerTests.cs index 4ea2250a..7a77b2c1 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/Web/Sessions/SessionManagerTests.cs +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Web/Sessions/SessionManagerTests.cs @@ -5,6 +5,7 @@ using Moq; using System.Text; using System.Text.Json; +using EPR.RegulatorService.Frontend.Core.Enums; namespace EPR.RegulatorService.Frontend.UnitTests.Web.Sessions; @@ -30,7 +31,8 @@ public void Setup() { SubmissionId = Guid.NewGuid(), OrganisationId = Guid.NewGuid(), - OrganisationName = "Test Organisation" + OrganisationName = "Test Organisation", + OrganisationType = OrganisationType.ComplianceScheme } }, PermissionManagementSession = new PermissionManagementSession diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Web/ViewComponents/RegistrationsListViewComponentTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Web/ViewComponents/RegistrationsListViewComponentTests.cs index 206b1c27..f99bda13 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/Web/ViewComponents/RegistrationsListViewComponentTests.cs +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Web/ViewComponents/RegistrationsListViewComponentTests.cs @@ -5,11 +5,12 @@ using EPR.RegulatorService.Frontend.Web.ViewModels.Registrations; using Microsoft.AspNetCore.Mvc.ViewComponents; using Moq; -using EPR.RegulatorService.Frontend.Core.Enums; -using EPR.RegulatorService.Frontend.Web.Constants; namespace EPR.RegulatorService.Frontend.UnitTests.Web.ViewComponents { + using Frontend.Core.Enums; + using Frontend.Web.Constants; + [TestClass] public class RegistrationsListViewComponentTests : ViewComponentsTestBase { @@ -40,7 +41,7 @@ public void TestInitialize() { new() { - RegistrationId = Guid.NewGuid(), + SubmissionId = Guid.NewGuid(), Decision = PendingStatus, RegistrationDate = DateTime.Now, IsResubmission = false, @@ -57,7 +58,7 @@ public void TestInitialize() }, new() { - RegistrationId = Guid.NewGuid(), + SubmissionId = Guid.NewGuid(), Decision = ApprovedStatus, RegistrationDate = DateTime.Now, IsResubmission = true, @@ -75,44 +76,6 @@ public void TestInitialize() }; } - [TestMethod] - public async Task InvokeAsync_InvalidPageNumber_SendsToErrorPage() - { - // Arrange - var registrations = _fixture.Build>() - .With(x => x.Items, _registrations) - .With(x => x.CurrentPage, 1) - .With(x => x.TotalItems, 2) - .Create(); - - _facadeServiceMock - .Setup(x => x.GetRegulatorRegistrations(It.IsAny(), It.IsAny(), null, - It.IsAny(), It.IsAny())) - .Returns(Task.FromResult(registrations)); - - var viewComponent = - new RegistrationsListViewComponent(_facadeServiceMock.Object, _viewComponentHttpContextAccessor.Object); - _httpContextMock.Setup(x => x.Response.Redirect(PagePath.PageNotFound)); - - SetViewComponentContext(PagePath.PageNotFound, viewComponent, null); - - // Act - await viewComponent.InvokeAsync(new RegistrationListRequest() - { - SearchOrganisationName = string.Empty, - SearchOrganisationReference = string.Empty, - IsDirectProducerChecked = false, - IsComplianceSchemeChecked = false, - IsPendingRegistrationChecked = false, - IsAcceptedRegistrationChecked = false, - IsRejectedRegistrationChecked = false, - PageNumber = 9 - }); - - // Assert - _httpContextMock.Verify(x => x.Response.Redirect(PagePath.PageNotFoundPath), Times.Once); - } - [TestMethod] public async Task InvokeAsync_ReturnsCorrectViewAndModel_Where_NoFiltersSet() { @@ -124,15 +87,18 @@ public async Task InvokeAsync_ReturnsCorrectViewAndModel_Where_NoFiltersSet() .Create(); _facadeServiceMock - .Setup(x => x.GetRegulatorRegistrations(It.IsAny(), It.IsAny(), null, - It.IsAny(), It.IsAny())) + .Setup(x => x.GetOrganisationSubmissions( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())) .Returns(Task.FromResult(registrations)); - var viewComponent = - new RegistrationsListViewComponent(_facadeServiceMock.Object, _viewComponentHttpContextAccessor.Object); + var viewComponent = new RegistrationsListViewComponent(_facadeServiceMock.Object, _viewComponentHttpContextAccessor.Object); // Act - var result = await viewComponent.InvokeAsync(new RegistrationListRequest() + var result = await viewComponent.InvokeAsync(new RegistrationListRequest { SearchOrganisationName = string.Empty, SearchOrganisationReference = string.Empty, @@ -164,8 +130,7 @@ public async Task InvokeAsync_ReturnsCorrectViewAndModel_Where_NoFiltersSet() } [TestMethod] - public async Task - InvokeAsync_ReturnsCorrectViewAndModel_Where_ApprovedStatus_ComplianceScheme_OrganisationNameSet() + public async Task InvokeAsync_ReturnsCorrectViewAndModel_Where_ApprovedStatus_ComplianceScheme_OrganisationNameSet() { // Arrange var registrations = _fixture.Build>() @@ -177,13 +142,15 @@ public async Task registrations.Items.RemoveAt(0); _facadeServiceMock - .Setup(x => x.GetRegulatorRegistrations(It.IsAny(), It.IsAny(), + .Setup(x => x.GetOrganisationSubmissions( + It.IsAny(), + It.IsAny(), It.IsAny(), - It.IsAny(), It.IsAny())) + It.IsAny(), + It.IsAny())) .Returns(Task.FromResult(registrations)); - var viewComponent = - new RegistrationsListViewComponent(_facadeServiceMock.Object, _viewComponentHttpContextAccessor.Object); + var viewComponent = new RegistrationsListViewComponent(_facadeServiceMock.Object, _viewComponentHttpContextAccessor.Object); var registrationFiltersModel = new RegistrationFiltersModel() { @@ -212,8 +179,7 @@ public async Task model.PagedOrganisationRegistrations.Should().BeEquivalentTo(registrations.Items); model.PagedOrganisationRegistrations.Count().Should().Be(1); model.PagedOrganisationRegistrations.FirstOrDefault().OrganisationName.Should().Be(SweetsLtdCompanyName); - model.PagedOrganisationRegistrations.FirstOrDefault().OrganisationType.Should() - .Be(OrganisationType.ComplianceScheme); + model.PagedOrganisationRegistrations.FirstOrDefault().OrganisationType.Should().Be(OrganisationType.ComplianceScheme); model.PagedOrganisationRegistrations.FirstOrDefault().Decision.Should().Be(ApprovedStatus); model.PaginationNavigationModel.CurrentPage.Should().Be(registrations.CurrentPage); model.PaginationNavigationModel.PageCount.Should().Be(registrations.TotalPages); @@ -225,6 +191,44 @@ public async Task model.RegulatorRegistrationFiltersModel.IsRejectedRegistrationChecked.Should().BeFalse(); } + [TestMethod] + public async Task InvokeAsync_InvalidPageNumber_SendsToErrorPage() + { + // Arrange + var registrations = _fixture.Build>() + .With(x => x.Items, _registrations) + .With(x => x.CurrentPage, 1) + .With(x => x.TotalItems, 2) + .Create(); + + _facadeServiceMock + .Setup(x => x.GetOrganisationSubmissions(It.IsAny(), It.IsAny(), null, + It.IsAny(), It.IsAny())) + .Returns(Task.FromResult(registrations)); + + var viewComponent = + new RegistrationsListViewComponent(_facadeServiceMock.Object, _viewComponentHttpContextAccessor.Object); + _httpContextMock.Setup(x => x.Response.Redirect(PagePath.PageNotFound)); + + SetViewComponentContext(PagePath.PageNotFound, viewComponent, null); + + // Act + await viewComponent.InvokeAsync(new RegistrationListRequest() + { + SearchOrganisationName = string.Empty, + SearchOrganisationReference = string.Empty, + IsDirectProducerChecked = false, + IsComplianceSchemeChecked = false, + IsPendingRegistrationChecked = false, + IsAcceptedRegistrationChecked = false, + IsRejectedRegistrationChecked = false, + PageNumber = 9 + }); + + // Assert + _httpContextMock.Verify(x => x.Response.Redirect(PagePath.PageNotFoundPath), Times.Once); + } + [TestMethod] public async Task InvokeAsync_ReturnsCorrectViewAndModel_Where_PendingStatus_ComplianceScheme_OrganisationNameSet() @@ -239,9 +243,12 @@ public async Task registrations.Items.RemoveAt(0); _facadeServiceMock - .Setup(x => x.GetRegulatorRegistrations(It.IsAny(), It.IsAny(), + .Setup(x => x.GetOrganisationSubmissions( + It.IsAny(), + It.IsAny(), It.IsAny(), - It.IsAny(), It.IsAny())) + It.IsAny(), + It.IsAny())) .Returns(Task.FromResult(registrations)); var viewComponent = @@ -301,9 +308,12 @@ public async Task registrations.Items.RemoveAt(0); _facadeServiceMock - .Setup(x => x.GetRegulatorRegistrations(It.IsAny(), It.IsAny(), + .Setup(x => x.GetOrganisationSubmissions( + It.IsAny(), + It.IsAny(), It.IsAny(), - It.IsAny(), It.IsAny())) + It.IsAny(), + It.IsAny())) .Returns(Task.FromResult(registrations)); var viewComponent = @@ -362,9 +372,12 @@ public async Task InvokeAsync_ReturnsCorrectViewAndModel_Where_Accepted_DirectPr registrations.Items.RemoveAt(0); _facadeServiceMock - .Setup(x => x.GetRegulatorRegistrations(It.IsAny(), It.IsAny(), + .Setup(x => x.GetOrganisationSubmissions( + It.IsAny(), + It.IsAny(), It.IsAny(), - It.IsAny(), It.IsAny())) + It.IsAny(), + It.IsAny())) .Returns(Task.FromResult(registrations)); var viewComponent = diff --git a/src/EPR.RegulatorService.Frontend.UnitTests/Web/ViewComponents/SubmissionsListViewComponentTests.cs b/src/EPR.RegulatorService.Frontend.UnitTests/Web/ViewComponents/SubmissionsListViewComponentTests.cs index 01faa395..2ef1efd7 100644 --- a/src/EPR.RegulatorService.Frontend.UnitTests/Web/ViewComponents/SubmissionsListViewComponentTests.cs +++ b/src/EPR.RegulatorService.Frontend.UnitTests/Web/ViewComponents/SubmissionsListViewComponentTests.cs @@ -8,6 +8,8 @@ namespace EPR.RegulatorService.Frontend.UnitTests.Web.ViewComponents { + using Frontend.Core.Enums; + [TestClass] public class SubmissionsListViewComponentTests : ViewComponentsTestBase { @@ -24,8 +26,6 @@ public class SubmissionsListViewComponentTests : ViewComponentsTestBase private const string JohnDoeTelephone = "0011223344"; private const string SweetsLtdCompanyName = "SweetsLtd"; private const string SweetsLtdCompanyReference = "987654"; - private const string DirectProducer = "Direct Producer"; - private const string ComplianceScheme = "Compliance Scheme"; private const string TonyStarkFirstName = "Tony"; private const string TonyStarkLastName = "Stark"; private const string TonyStarkEmail = "tony.stark@test.com"; @@ -47,7 +47,7 @@ public void TestInitialize() OrganisationId = Guid.NewGuid(), OrganisationName = DrinksLtdCompanyName, OrganisationReference = DrinksLtdCompanyReference, - OrganisationType = DirectProducer, + OrganisationType = OrganisationType.DirectProducer, UserId = Guid.NewGuid(), Email = JohnDoeEmail, ServiceRole = JohnDoeServiceRole, @@ -64,7 +64,7 @@ public void TestInitialize() OrganisationId = Guid.NewGuid(), OrganisationName = SweetsLtdCompanyName, OrganisationReference = SweetsLtdCompanyReference, - OrganisationType = ComplianceScheme, + OrganisationType = OrganisationType.ComplianceScheme, UserId = Guid.NewGuid(), Email = TonyStarkEmail, ServiceRole = TonyStarkServiceRole, @@ -86,7 +86,7 @@ public async Task InvokeAsync_ReturnsCorrectViewAndModel_Where_NoFiltersSet() .Create(); _facadeServiceMock - .Setup(x => x.GetOrganisationSubmissions(It.IsAny(), It.IsAny(), It.IsAny(), + .Setup(x => x.GetOrganisationSubmissions(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.FromResult(submissions)); @@ -137,7 +137,7 @@ public async Task InvokeAsync_ReturnsCorrectViewAndModel_Where_ApprovedStatus_Co submissions.Items.RemoveAt(0); _facadeServiceMock - .Setup(x => x.GetOrganisationSubmissions(It.IsAny(), It.IsAny(), It.IsAny(), + .Setup(x => x.GetOrganisationSubmissions(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.FromResult(submissions)); @@ -170,7 +170,7 @@ public async Task InvokeAsync_ReturnsCorrectViewAndModel_Where_ApprovedStatus_Co model.PagedOrganisationSubmissions.Should().BeEquivalentTo(submissions.Items); model.PagedOrganisationSubmissions.Count().Should().Be(1); model.PagedOrganisationSubmissions.FirstOrDefault().OrganisationName.Should().Be(SweetsLtdCompanyName); - model.PagedOrganisationSubmissions.FirstOrDefault().OrganisationType.Should().Be(ComplianceScheme); + model.PagedOrganisationSubmissions.FirstOrDefault().OrganisationType.Should().Be(OrganisationType.ComplianceScheme); model.PagedOrganisationSubmissions.FirstOrDefault().Decision.Should().Be(ApprovedStatus); model.PaginationNavigationModel.CurrentPage.Should().Be(submissions.CurrentPage); model.PaginationNavigationModel.PageCount.Should().Be(submissions.TotalPages); diff --git a/src/EPR.RegulatorService.Frontend.Web/Configs/ExternalUrlsOptions.cs b/src/EPR.RegulatorService.Frontend.Web/Configs/ExternalUrlsOptions.cs index b9c3c313..d0debe8f 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Configs/ExternalUrlsOptions.cs +++ b/src/EPR.RegulatorService.Frontend.Web/Configs/ExternalUrlsOptions.cs @@ -34,4 +34,8 @@ public class ExternalUrlsOptions public string PrivacyEnvironmentAgency { get; set; } public string PowerBiLogin { get; set; } + + public string CompaniesHouseRegisterBaseUrl { get; set; } + + public string RegistrationFileDownloadBaseUrl { get; set; } } diff --git a/src/EPR.RegulatorService.Frontend.Web/Configs/FeatureFlags.cs b/src/EPR.RegulatorService.Frontend.Web/Configs/FeatureFlags.cs index 48d4e8ff..7ed276bf 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Configs/FeatureFlags.cs +++ b/src/EPR.RegulatorService.Frontend.Web/Configs/FeatureFlags.cs @@ -12,4 +12,6 @@ public static class FeatureFlags public const string ManageRegistrations = "ManageRegistrations"; public const string ManageApprovedUsers = "ManageApprovedUsers"; + + public const string PomDataPeriodAndTime = "PomDataPeriodAndTime"; } \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/Constants/PagePath.cs b/src/EPR.RegulatorService.Frontend.Web/Constants/PagePath.cs index 55044645..1a44437f 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Constants/PagePath.cs +++ b/src/EPR.RegulatorService.Frontend.Web/Constants/PagePath.cs @@ -22,6 +22,9 @@ public static class PagePath public const string NominationDecisionConfirmation = "approve-decision-confirmation"; public const string PrePageNotFound = "pre-page-not-found"; public const string Registrations = "manage-registrations"; + public const string RegistrationDetails = "organisation-details-submission"; + public const string RejectRegistration = "organisation-details-submission-reject"; + public const string AcceptRegistrationSubmission = "organisation-details-submission-confirm"; public const string InviteNewApprovedPersonPage = "invite-new-approved-person"; public const string InviteNewApprovedPersonName = "invite-new-approved-person-name"; public const string InviteNewApprovedPersonEmail = "invite-new-approved-person-email"; diff --git a/src/EPR.RegulatorService.Frontend.Web/Controllers/Account/AccountController.cs b/src/EPR.RegulatorService.Frontend.Web/Controllers/Account/AccountController.cs index 57a84cab..77f27974 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Controllers/Account/AccountController.cs +++ b/src/EPR.RegulatorService.Frontend.Web/Controllers/Account/AccountController.cs @@ -1,3 +1,4 @@ +using EPR.RegulatorService.Frontend.Web.Constants; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; @@ -72,8 +73,11 @@ public IActionResult SignOut( return Ok(); } + var selectedCulture = HttpContext.Session.GetString(Language.SessionLanguageKey); + var queryParams = !string.IsNullOrEmpty(selectedCulture) ? new { culture = selectedCulture } : null; + scheme ??= OpenIdConnectDefaults.AuthenticationScheme; - var callbackUrl = Url.Action(action: "SignedOut", controller: "Home", values: null, protocol: Request.Scheme); + var callbackUrl = Url.Action(action: "SignedOut", controller: "Home", values: queryParams, protocol: Request.Scheme); return SignOut( new AuthenticationProperties { diff --git a/src/EPR.RegulatorService.Frontend.Web/Controllers/Registrations/RegistrationsController.cs b/src/EPR.RegulatorService.Frontend.Web/Controllers/Registrations/RegistrationsController.cs index c92ee877..d271db48 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Controllers/Registrations/RegistrationsController.cs +++ b/src/EPR.RegulatorService.Frontend.Web/Controllers/Registrations/RegistrationsController.cs @@ -1,16 +1,21 @@ using EPR.Common.Authorization.Constants; +using EPR.RegulatorService.Frontend.Core.Enums; +using RegulatorDecision = EPR.RegulatorService.Frontend.Core.Enums.RegulatorDecision; using EPR.RegulatorService.Frontend.Core.Extensions; +using EPR.RegulatorService.Frontend.Core.Models; +using EPR.RegulatorService.Frontend.Core.Models.Registrations; using EPR.RegulatorService.Frontend.Core.Services; using EPR.RegulatorService.Frontend.Core.Sessions; using EPR.RegulatorService.Frontend.Web.Configs; using EPR.RegulatorService.Frontend.Web.Constants; +using EPR.RegulatorService.Frontend.Web.Helpers; using EPR.RegulatorService.Frontend.Web.Sessions; using EPR.RegulatorService.Frontend.Web.ViewModels.Registrations; -using EPR.RegulatorService.Frontend.Core.Models.Registrations; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Microsoft.FeatureManagement.Mvc; +using System.Text.Json; namespace EPR.RegulatorService.Frontend.Web.Controllers.Registrations { @@ -18,36 +23,44 @@ namespace EPR.RegulatorService.Frontend.Web.Controllers.Registrations [Authorize(Policy = PolicyConstants.RegulatorBasicPolicy)] public class RegistrationsController : Controller { + private const string DeclaredByComplianceScheme = "Not required (compliance scheme)"; private readonly ISessionManager _sessionManager; private readonly string _pathBase; private readonly ExternalUrlsOptions _options; + private readonly IFacadeService _facadeService; public RegistrationsController(ISessionManager sessionManager, - IConfiguration configuration, IOptions options) + IConfiguration configuration, IOptions options, IFacadeService facadeService) { _sessionManager = sessionManager; _pathBase = configuration.GetValue(ConfigKeys.PathBase); _options = options.Value; + _facadeService = facadeService; } [HttpGet] [Route(PagePath.Registrations)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task Registrations(int? pageNumber, bool? clearFilters) + public async Task Registrations( + RegistrationFiltersModel registrationFiltersModel, + int? pageNumber, + bool? clearFilters, + EndpointResponseStatus? rejectRegistrationResult = null, + EndpointResponseStatus? acceptRegistrationResult = null, + string? organisationName = null) { var session = await _sessionManager.GetSessionAsync(HttpContext.Session); session ??= new JourneySession(); - session.RegulatorRegistrationSession.RejectRegistrationJourneyData = null; session.RegulatorRegistrationSession.RegistrationFiltersModel ??= new RegistrationFiltersModel(); - clearFilters = clearFilters ?? false; - if (clearFilters.Value) + if (clearFilters.HasValue && clearFilters.Value) { ClearFilters(session); } SetCustomBackLink(); + SetOrResetFilterValuesInSession(session, registrationFiltersModel); var model = new RegistrationsViewModel { @@ -63,6 +76,9 @@ public async Task Registrations(int? pageNumber, bool? clearFilte }, PageNumber = pageNumber ?? 1, PowerBiLogin = _options.PowerBiLogin, + RejectRegistrationResult = rejectRegistrationResult, + AcceptRegistrationResult = acceptRegistrationResult, + OrganisationName = organisationName }; await SaveSessionAndJourney(session, PagePath.Registrations, PagePath.Registrations); @@ -72,21 +88,189 @@ public async Task Registrations(int? pageNumber, bool? clearFilte [HttpPost] [Route(PagePath.Registrations)] - public async Task Registrations( - RegistrationFiltersModel registrationFiltersModel) + public async Task Registrations(string jsonRegistration) { + var registrationSubmission = JsonSerializer.Deserialize(jsonRegistration); var session = await _sessionManager.GetSessionAsync(HttpContext.Session); + session ??= new JourneySession(); + session.RegulatorRegistrationSession.OrganisationRegistration = registrationSubmission; - SetOrResetFilterValuesInSession(session, registrationFiltersModel); + await SaveSession(session); + return RedirectToAction("RegistrationDetails", "Registrations"); + } + + [HttpGet] + [Route(PagePath.RegistrationDetails)] + public async Task RegistrationDetails() + { + var session = await _sessionManager.GetSessionAsync(HttpContext.Session); + var registration = session.RegulatorRegistrationSession.OrganisationRegistration; + var model = new RegistrationDetailsViewModel + { + OrganisationName = registration.OrganisationName, + BuildingName = registration.BuildingName, + SubBuildingName = registration.SubBuildingName, + BuildingNumber = registration.BuildingNumber, + Street = registration.Street, + Locality = registration.Locality, + DependantLocality = registration.DependantLocality, + Town = registration.Town, + County = registration.County, + Country = registration.Country, + PostCode = registration.PostCode, + OrganisationType = registration.OrganisationType.GetDescription(), + OrganisationReferenceNumber = registration.OrganisationReference, + FormattedTimeAndDateOfSubmission = DateTimeHelpers.FormatTimeAndDateForSubmission(registration.RegistrationDate), + SubmissionId = registration.SubmissionId, + SubmissionPeriod = registration.SubmissionPeriod, + SubmittedBy = $"{registration.FirstName} {registration.LastName}", + AccountRole = registration.ServiceRole, + Telephone = registration.Telephone, + Email = registration.Email, + Status = registration.Decision, + IsResubmission = registration.IsResubmission, + RejectionReason = registration.RejectionComments, + PreviousRejectionReason = registration.PreviousRejectionComments, + PowerBiLogin = _options.PowerBiLogin, + CompaniesHouseNumber = registration.CompaniesHouseNumber, + OrganisationDetailsFileId = registration.OrganisationDetailsFileId, + OrganisationDetailsFileName = registration.OrganisationDetailsFileName, + PartnershipDetailsFileId = registration.PartnershipDetailsFileId, + PartnershipDetailsFileName = registration.PartnershipDetailsFileName, + BrandDetailsFileId = registration.BrandDetailsFileId, + BrandDetailsFileName = registration.BrandDetailsFileName, + DeclaredBy = registration.OrganisationType == OrganisationType.ComplianceScheme + ? DeclaredByComplianceScheme + : $"{registration.FirstName} {registration.LastName}" + }; + + await SaveSessionAndJourney(session, PagePath.Registrations, PagePath.RegistrationDetails); + SetBackLink(session, PagePath.RegistrationDetails); + + return View(nameof(RegistrationDetails), model); + } + + [HttpGet] + [Route(PagePath.RejectRegistration)] + public async Task RejectRegistration() + { + var session = await _sessionManager.GetSessionAsync(HttpContext.Session); + var model = new RejectRegistrationViewModel(); + + await SaveSessionAndJourney(session, PagePath.RegistrationDetails, PagePath.RejectRegistration); + SetBackLink(session, PagePath.RejectRegistration); + + return View(nameof(RejectRegistration), model); + } + + [HttpPost] + [Route(PagePath.RejectRegistration)] + public async Task RejectRegistration(RejectRegistrationViewModel model) + { + var session = await _sessionManager.GetSessionAsync(HttpContext.Session); + + if (!ModelState.IsValid) + { + SetBackLink(session, PagePath.RejectRegistration); + return View(nameof(RejectRegistration), model); + } + + var request = new RegulatorRegistrationDecisionCreateRequest + { + SubmissionId = session.RegulatorRegistrationSession.OrganisationRegistration.SubmissionId, + Decision = RegulatorDecision.Rejected, + Comments = model.ReasonForRejection, + FileId = session.RegulatorRegistrationSession.OrganisationRegistration.OrganisationDetailsFileId, + OrganisationId = session.RegulatorRegistrationSession.OrganisationRegistration.OrganisationId, + OrganisationName = session.RegulatorRegistrationSession.OrganisationRegistration.OrganisationName, + OrganisationNumber = session.RegulatorRegistrationSession.OrganisationRegistration.OrganisationReference + }; + + var result = await _facadeService.SubmitRegistrationDecision(request); + + var organisationName = session.RegulatorRegistrationSession.OrganisationRegistration.OrganisationName; + session.RegulatorRegistrationSession.OrganisationRegistration = null; return await SaveSessionAndRedirect( session, nameof(Registrations), + PagePath.RejectRegistration, PagePath.Registrations, + new + { + rejectRegistrationResult = result, + organisationName = organisationName + }); + } + + [HttpGet] + [Route(PagePath.AcceptRegistrationSubmission)] + public async Task AcceptRegistrationSubmission() + { + var session = await _sessionManager.GetSessionAsync(HttpContext.Session); + var model = new AcceptRegistrationSubmissionViewModel(); + + + await SaveSessionAndJourney(session, PagePath.RegistrationDetails, PagePath.AcceptRegistrationSubmission); + SetBackLink(session, PagePath.AcceptRegistrationSubmission); + + return View(nameof(AcceptRegistrationSubmission), model); + } + + [HttpPost] + [Route(PagePath.AcceptRegistrationSubmission)] + public async Task AcceptRegistrationSubmission(AcceptRegistrationSubmissionViewModel model) + { + var session = await _sessionManager.GetSessionAsync(HttpContext.Session); + + if (!ModelState.IsValid) + { + SetBackLink(session, PagePath.AcceptRegistrationSubmission); + return View(nameof(AcceptRegistrationSubmission), model); + } + + if (model.Accepted != true) + { + return await SaveSessionAndRedirect( + session, + nameof(Registrations), + PagePath.AcceptRegistrationSubmission, + PagePath.Registrations, + new { }); + } + + var request = new RegulatorRegistrationDecisionCreateRequest + { + SubmissionId = session.RegulatorRegistrationSession.OrganisationRegistration.SubmissionId, + Decision = RegulatorDecision.Accepted, + FileId = session.RegulatorRegistrationSession.OrganisationRegistration.OrganisationDetailsFileId, + OrganisationId = session.RegulatorRegistrationSession.OrganisationRegistration.OrganisationId, + OrganisationName = session.RegulatorRegistrationSession.OrganisationRegistration.OrganisationName, + OrganisationNumber = session.RegulatorRegistrationSession.OrganisationRegistration.OrganisationReference + + }; + var result = await _facadeService.SubmitRegistrationDecision(request); + + var organisationName = session.RegulatorRegistrationSession.OrganisationRegistration.OrganisationName; + session.RegulatorRegistrationSession.OrganisationRegistration = null; + + return await SaveSessionAndRedirect( + session, + nameof(Registrations), + PagePath.AcceptRegistrationSubmission, PagePath.Registrations, - null); + new + { + acceptRegistrationResult = result, + organisationName = organisationName + }); + } + private void SetBackLink(JourneySession session, string currentPagePath) => + ViewBag.BackLinkToDisplay = + session.RegulatorRegistrationSession.Journey.PreviousOrDefault(currentPagePath) ?? string.Empty; + private static void SetOrResetFilterValuesInSession(JourneySession session, RegistrationFiltersModel registrationFiltersModel) { var regulatorRegistrationSession = session.RegulatorRegistrationSession; diff --git a/src/EPR.RegulatorService.Frontend.Web/Controllers/Submissions/SubmissionsController.cs b/src/EPR.RegulatorService.Frontend.Web/Controllers/Submissions/SubmissionsController.cs index c284b711..f4c49162 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Controllers/Submissions/SubmissionsController.cs +++ b/src/EPR.RegulatorService.Frontend.Web/Controllers/Submissions/SubmissionsController.cs @@ -15,6 +15,7 @@ using Microsoft.FeatureManagement.Mvc; using System.Globalization; using System.Text.Json; +using EPR.RegulatorService.Frontend.Web.Helpers; using RegulatorDecision = EPR.RegulatorService.Frontend.Core.Enums.RegulatorDecision; namespace EPR.RegulatorService.Frontend.Web.Controllers.Submissions @@ -151,7 +152,7 @@ public async Task SubmissionDetails() OrganisationName = submission.OrganisationName, OrganisationType = submission.OrganisationType, OrganisationReferenceNumber = submission.OrganisationReference, - FormattedTimeAndDateOfSubmission = FormatTimeAndDateForSubmission(submission.SubmittedDate), + FormattedTimeAndDateOfSubmission = DateTimeHelpers.FormatTimeAndDateForSubmission(submission.SubmittedDate), SubmissionId = submission.SubmissionId, SubmittedBy = $"{submission.FirstName} {submission.LastName}", AccountRole = submission.ServiceRole, diff --git a/src/EPR.RegulatorService.Frontend.Web/Dockerfile b/src/EPR.RegulatorService.Frontend.Web/Dockerfile index 77e36dda..61849a56 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Dockerfile +++ b/src/EPR.RegulatorService.Frontend.Web/Dockerfile @@ -1,4 +1,4 @@ -FROM defradigital/dotnetcore-development:latest AS build-env +FROM defradigital/dotnetcore-development:dotnet6.0 AS build-env # Expose the app on a defined port, configurable via a build argument ARG PORT=3000 @@ -34,7 +34,7 @@ WORKDIR /home/dotnet/EPR.RegulatorService.Frontend.Web RUN dotnet publish -c Release -o out # Build runtime image -FROM defradigital/dotnetcore:latest +FROM defradigital/dotnetcore:dotnet6.0 COPY --from=build-env --chown=dotnet /home/dotnet/EPR.RegulatorService.Frontend.Web/out . # Add internationalisation support diff --git a/src/EPR.RegulatorService.Frontend.Web/EPR.RegulatorService.Frontend.Web.csproj b/src/EPR.RegulatorService.Frontend.Web/EPR.RegulatorService.Frontend.Web.csproj index 666b5889..58e2f5a1 100644 --- a/src/EPR.RegulatorService.Frontend.Web/EPR.RegulatorService.Frontend.Web.csproj +++ b/src/EPR.RegulatorService.Frontend.Web/EPR.RegulatorService.Frontend.Web.csproj @@ -344,5 +344,10 @@ **/_SubmissionDetails.cshtml + + + **/RegistrationDetailsViewModel.cs + + diff --git a/src/EPR.RegulatorService.Frontend.Web/Helpers/DateTimeHelpers.cs b/src/EPR.RegulatorService.Frontend.Web/Helpers/DateTimeHelpers.cs new file mode 100644 index 00000000..b4a61c4a --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Helpers/DateTimeHelpers.cs @@ -0,0 +1,14 @@ +namespace EPR.RegulatorService.Frontend.Web.Helpers; + +using System.Globalization; + +public static class DateTimeHelpers +{ + public static string FormatTimeAndDateForSubmission(DateTime timeAndDateOfSubmission) + { + string time = timeAndDateOfSubmission.ToString("h:mm", CultureInfo.CurrentCulture); + string ampm = timeAndDateOfSubmission.ToString("tt", CultureInfo.CurrentCulture).ToLower(); + string date = timeAndDateOfSubmission.ToString("dd MMMM yyyy", CultureInfo.CurrentCulture); + return $"{time}{ampm} on {date}"; + } +} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/SharedResources.cy.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/SharedResources.cy.resx index c85acdcb..07887e66 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Resources/SharedResources.cy.resx +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/SharedResources.cy.resx @@ -1,4 +1,4 @@ - + @@ -151,4 +151,13 @@ Person a ddirprwywyd + + WDownload + + + WNot listed + + + WYou can enter up to 500 characters + diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/SharedResources.en.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/SharedResources.en.resx index b17f2e38..36a64c88 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Resources/SharedResources.en.resx +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/SharedResources.en.resx @@ -133,6 +133,12 @@ Job title + + Download + + + Not listed + Direct Producer @@ -145,4 +151,7 @@ Delegated Person + + You can enter up to 500 characters + diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/AcceptRegistrationSubmission.cy.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/AcceptRegistrationSubmission.cy.resx new file mode 100644 index 00000000..a1e4b1d6 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/AcceptRegistrationSubmission.cy.resx @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Dewiswch ‘Hoffwn’ os hoffech chi dderbyn y cyflwyniad yma + + + Ydych chi'n siŵr yr hoffech chi +dderbyn y cyflwyniad yma? + + + Derbyn y Cyflwyniad + + \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/AcceptRegistrationSubmission.en.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/AcceptRegistrationSubmission.en.resx new file mode 100644 index 00000000..47749df8 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/AcceptRegistrationSubmission.en.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Select yes if you want to accept this submission + + + Are you sure you want to accept this submission? + + + Accept Submission + + \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RegistrationDetails.cy.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RegistrationDetails.cy.resx new file mode 100644 index 00000000..fe83dbed --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RegistrationDetails.cy.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Rheoli cyflwyniadau data pecynwaith + + + Math o sefydliad + + + ID y sefydliad + + + WGo back to all registrations + + + WCompanies House Number + + + WPowerBI + + + I weld crynodeb o’r data pecynwaith ac unrhyw gyflwyniadau blaenorol, + + + WView on Companies House register + + + WRegistered address + + + WHead office address + + + I weld crynodeb o fanylion y sefydliad ac unrhyw gyflwyniadau blaenorol, + + + WManage organisation details submissions + + \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RegistrationDetails.en.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RegistrationDetails.en.resx new file mode 100644 index 00000000..89f62465 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RegistrationDetails.en.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Manage packaging data submissions + + + Organisation type + + + Organisation ID + + + Go back to all registrations + + + Companies House Number + + + Power BI + + + To view a summary of the packaging data and any previous submissions, + + + View on Companies House register + + + Registered address + + + Head office address + + + To view a summary of the organisation details and any previous submissions, + + + Manage organisation details submissions + + \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RegistrationDetails.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RegistrationDetails.resx new file mode 100644 index 00000000..370c4831 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RegistrationDetails.resx @@ -0,0 +1,41 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/Registrations.cy.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/Registrations.cy.resx index e718a965..b93c38c4 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/Registrations.cy.resx +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/Registrations.cy.resx @@ -1,24 +1,122 @@ - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx - 1.3 + 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - WManage organisation details submissions @@ -31,7 +129,13 @@ WThis list shows the current pending submissions and the latest actioned submissions. To view older submissions + + WYou have rejected {0}'s organisation details submission. + + + WYou have accepted {0}'s organisation details submission. + Wlog in to Power-BI - + \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/Registrations.en.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/Registrations.en.resx index 27250211..8ee126ac 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/Registrations.en.resx +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/Registrations.en.resx @@ -1,24 +1,122 @@ - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx - 1.3 + 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Manage organisation details submissions @@ -31,7 +129,13 @@ This list shows the current pending submissions and the latest actioned submissions. To view older submissions + + You have rejected {0}'s organisation details submission. + + + You have accepted {0}'s organisation details submission. + log in to Power-BI - + \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RejectRegistration.cy.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RejectRegistration.cy.resx new file mode 100644 index 00000000..19e8121c --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RejectRegistration.cy.resx @@ -0,0 +1,35 @@ + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + WReject Submission + + + WWhy are you rejecting this submission? + + + WWe’ll use this information in an email to the organisation's approved and delegated people. It will also be added to the submission details. + + + WWEnter why you’re rejecting this submission + + + WYour summary must be 500 characters or less + + diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RejectRegistration.en.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RejectRegistration.en.resx new file mode 100644 index 00000000..38e40c86 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Registrations/RejectRegistration.en.resx @@ -0,0 +1,35 @@ + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Reject Submission + + + Why are you rejecting this submission? + + + We’ll use this information in an email to the organisation's approved and delegated people. It will also be added to the submission details. + + + Enter why you’re rejecting this submission + + + Your summary must be 500 characters or less + + diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Components/SubmissionsList/Default.cy.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Components/SubmissionsList/Default.cy.resx index e2f8a161..a7f933e0 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Components/SubmissionsList/Default.cy.resx +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Components/SubmissionsList/Default.cy.resx @@ -17,10 +17,16 @@ Dyddiad y cyflwyniad + + WSubmission Date and Time + + + WSubmission Period + Statws Sefydliad - \ No newline at end of file + diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Components/SubmissionsList/Default.en.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Components/SubmissionsList/Default.en.resx index 6180790c..ff71d2a2 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Components/SubmissionsList/Default.en.resx +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Components/SubmissionsList/Default.en.resx @@ -17,10 +17,16 @@ Date of submission + + Submission Date and Time + + + Submission Period + Status Organisation - \ No newline at end of file + diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Components/SubmissionsList/Default.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Components/SubmissionsList/Default.resx index 8db905f2..5b0faa6a 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Components/SubmissionsList/Default.resx +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Components/SubmissionsList/Default.resx @@ -17,6 +17,12 @@ + + + + + + diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationResubmissionDetails.cy.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationResubmissionDetails.cy.resx new file mode 100644 index 00000000..c46a282c --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationResubmissionDetails.cy.resx @@ -0,0 +1,66 @@ + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + WResubmission details + + + WTime and date of resubmission + + + WResubmitted by + + + WAccount role + + + WTelephone + + + WEmail + + + WReason for rejection + + + WResubmission required + + + W{0} cannot resubmit until this submission has been actioned. + + + WOrganisation details + + + WDeclared by + + + WBrand details + + + WPartnerDetails + + + WSubmitted on time + + + WReason for rejection of previous submission + + diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationResubmissionDetails.en.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationResubmissionDetails.en.resx new file mode 100644 index 00000000..c38fd6b1 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationResubmissionDetails.en.resx @@ -0,0 +1,66 @@ + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Resubmission details + + + Time and date of resubmission + + + Resubmitted by + + + Account role + + + Telephone + + + Email + + + Reason for rejection + + + Resubmission required + + + {0} cannot resubmit until this submission has been actioned. + + + Organisation details + + + Brand details + + + Declared by + + + Partner details + + + Submitted on time + + + Reason for rejection of previous submission + + diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationResubmissionDetails.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationResubmissionDetails.resx new file mode 100644 index 00000000..60deb0eb --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationResubmissionDetails.resx @@ -0,0 +1,32 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + + + + + + + + + + + + + + + + diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationSubmissionDetails.cy.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationSubmissionDetails.cy.resx new file mode 100644 index 00000000..45054919 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationSubmissionDetails.cy.resx @@ -0,0 +1,63 @@ + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Manylion y cyflwyniad + + + Amser a dyddiad y cyflwyniad + + + Cyflwynwyd gan + + + Rôl yn y cyfrif + + + Ffôn + + + Ebost + + + WReason for rejection + + + WResubmission required + + + Chaiff {0} ddim ailgyflwyno nes bod y cyflwyniad yma wedi’i weithredu. + + + WOrganisation details + + + WDeclared by + + + WBrand details + + + WPartner details + + + WSubmitted on time + + diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationSubmissionDetails.en.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationSubmissionDetails.en.resx new file mode 100644 index 00000000..19de03f1 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationSubmissionDetails.en.resx @@ -0,0 +1,63 @@ + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Submission details + + + Time and date of submission + + + Submitted by + + + Account role + + + Telephone + + + Email + + + Reason for rejection + + + Resubmission required + + + {0} cannot resubmit until this submission has been actioned. + + + Organisation details + + + Declared by + + + Brand details + + + Partner details + + + Submitted on time + + diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationSubmissionDetails.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationSubmissionDetails.resx new file mode 100644 index 00000000..12a3b33a --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Shared/Partials/_RegistrationSubmissionDetails.resx @@ -0,0 +1,29 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Submissions/Submissions.cy.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Submissions/Submissions.cy.resx index 9a75bf78..bc030784 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Submissions/Submissions.cy.resx +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Submissions/Submissions.cy.resx @@ -28,9 +28,6 @@ Mae’r rhestr yma yn dangos y cyflwyniadau presennol sydd ar ddod a’r cyflwyniadau a weithredwyd dros y 6 mis diwethaf. I weld cyflwyniadau hŷn - - mewngofnodwch i Power-BI - Rydych chi wedi gwrthod cyflwyniad pecynwaith {0}. @@ -38,4 +35,3 @@ Rydych chi wedi derbyn cyflwyniad data pecynwaith {0}. - diff --git a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Submissions/Submissions.en.resx b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Submissions/Submissions.en.resx index 53fee2fe..7f65b5c1 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Submissions/Submissions.en.resx +++ b/src/EPR.RegulatorService.Frontend.Web/Resources/Views/Submissions/Submissions.en.resx @@ -28,9 +28,6 @@ This list shows the current pending submissions and the actioned submissions for the last 6 months. To view older submissions - - log in to Power-BI - You have rejected {0}'s packaging data submission. @@ -38,4 +35,3 @@ You have accepted {0}'s packaging data submission. - diff --git a/src/EPR.RegulatorService.Frontend.Web/Sessions/SessionRequestCultureProvider.cs b/src/EPR.RegulatorService.Frontend.Web/Sessions/SessionRequestCultureProvider.cs index deceb87f..e108978c 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Sessions/SessionRequestCultureProvider.cs +++ b/src/EPR.RegulatorService.Frontend.Web/Sessions/SessionRequestCultureProvider.cs @@ -1,3 +1,4 @@ +using EPR.RegulatorService.Frontend.Web.Constants; using Microsoft.AspNetCore.Localization; using System.Diagnostics.CodeAnalysis; @@ -7,8 +8,18 @@ public class SessionRequestCultureProvider : RequestCultureProvider { public override async Task DetermineProviderCultureResult(HttpContext httpContext) { - await Task.Yield(); - var culture = httpContext.Session.Get(EPR.RegulatorService.Frontend.Web.Constants.Language.SessionLanguageKey) == null ? EPR.RegulatorService.Frontend.Web.Constants.Language.English : httpContext.Session.GetString(EPR.RegulatorService.Frontend.Web.Constants.Language.SessionLanguageKey); - return new ProviderCultureResult(culture); + var culture = httpContext.Session.GetString(Language.SessionLanguageKey); + + if (culture == null && httpContext.Request.Path.Value == $"/{PagePath.SignedOut}") + { + var cultureFromQuery = httpContext.Request.Query["culture"].ToString(); + + if (!string.IsNullOrEmpty(cultureFromQuery)) + { + culture = cultureFromQuery; + } + } + + return await Task.FromResult(new ProviderCultureResult(culture ?? Language.English)); } } \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/ViewComponents/RegistrationsListViewComponent.cs b/src/EPR.RegulatorService.Frontend.Web/ViewComponents/RegistrationsListViewComponent.cs index 2e022a0a..4d1ef1f9 100644 --- a/src/EPR.RegulatorService.Frontend.Web/ViewComponents/RegistrationsListViewComponent.cs +++ b/src/EPR.RegulatorService.Frontend.Web/ViewComponents/RegistrationsListViewComponent.cs @@ -9,6 +9,8 @@ namespace EPR.RegulatorService.Frontend.Web.ViewComponents; +using Core.Models.Registrations; + public class RegistrationsListViewComponent : ViewComponent { private const string PendingStatus = "Pending"; @@ -38,7 +40,7 @@ public async Task InvokeAsync( request.IsRejectedRegistrationChecked); var pagedOrganisationRegistrations - = await _facadeService.GetRegulatorRegistrations( + = await _facadeService.GetOrganisationSubmissions( request.SearchOrganisationName, request.SearchOrganisationReference, organisationType, @@ -50,7 +52,14 @@ var pagedOrganisationRegistrations _httpContextAccessor.HttpContext.Response.Redirect(PagePath.PageNotFoundPath); } - var model = new RegistrationsListViewModel() + foreach(Registration item in pagedOrganisationRegistrations.Items) + { + item.OrganisationDetailsFileId = item.CompanyDetailsFileId; + item.OrganisationDetailsFileName = item.CompanyDetailsFileName; + item.RejectionComments = item.Comments; + } + + var model = new RegistrationsListViewModel() { PagedOrganisationRegistrations = pagedOrganisationRegistrations.Items, PaginationNavigationModel = new PaginationNavigationModel diff --git a/src/EPR.RegulatorService.Frontend.Web/ViewComponents/SubmissionsListViewComponent.cs b/src/EPR.RegulatorService.Frontend.Web/ViewComponents/SubmissionsListViewComponent.cs index 8e6cfc14..b273ebd4 100644 --- a/src/EPR.RegulatorService.Frontend.Web/ViewComponents/SubmissionsListViewComponent.cs +++ b/src/EPR.RegulatorService.Frontend.Web/ViewComponents/SubmissionsListViewComponent.cs @@ -9,6 +9,9 @@ namespace EPR.RegulatorService.Frontend.Web.ViewComponents; using Constants; +using Core.Enums; +using Core.Models.Submissions; + public class SubmissionsListViewComponent : ViewComponent { private const string DirectProducer = "Direct Producer"; @@ -29,7 +32,7 @@ public SubmissionsListViewComponent( public async Task InvokeAsync( SubmissionListRequest request) { - string organisationType = SetFilteredOrganisationType( + var organisationType = SetFilteredOrganisationType( request.IsDirectProducerChecked, request.IsComplianceSchemeChecked); @@ -39,7 +42,7 @@ public async Task InvokeAsync( request.IsRejectedSubmissionChecked); var pagedOrganisationSubmissions - = await _facadeService.GetOrganisationSubmissions( + = await _facadeService.GetOrganisationSubmissions( request.SearchOrganisationName, request.SearchOrganisationReference, organisationType, @@ -75,19 +78,19 @@ var pagedOrganisationSubmissions return View(model); } - private static string SetFilteredOrganisationType(bool isDirectProducerSelected, bool isComplianceSchemeSelected) + private static OrganisationType? SetFilteredOrganisationType(bool isDirectProducerSelected, bool isComplianceSchemeSelected) { if (isDirectProducerSelected && !isComplianceSchemeSelected) { - return DirectProducer; + return OrganisationType.DirectProducer; } if (isComplianceSchemeSelected && !isDirectProducerSelected) { - return ComplianceScheme; + return OrganisationType.ComplianceScheme; } - return string.Empty; + return null; } private static string[] SetFilteredStatus(bool isPendingStatusSelected, bool isAcceptedStatusSelected, bool isRejectedStatusSelected) diff --git a/src/EPR.RegulatorService.Frontend.Web/ViewModels/Registrations/AcceptRegistrationSubmissionViewModel.cs b/src/EPR.RegulatorService.Frontend.Web/ViewModels/Registrations/AcceptRegistrationSubmissionViewModel.cs new file mode 100644 index 00000000..6e3b286e --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/ViewModels/Registrations/AcceptRegistrationSubmissionViewModel.cs @@ -0,0 +1,9 @@ +namespace EPR.RegulatorService.Frontend.Web.ViewModels.Registrations; + +using System.ComponentModel.DataAnnotations; + +public class AcceptRegistrationSubmissionViewModel +{ + [Required(ErrorMessage = "Error.AcceptSubmission")] + public bool? Accepted { get; set; } +} diff --git a/src/EPR.RegulatorService.Frontend.Web/ViewModels/Registrations/RegistrationDetailsViewModel.cs b/src/EPR.RegulatorService.Frontend.Web/ViewModels/Registrations/RegistrationDetailsViewModel.cs new file mode 100644 index 00000000..d883419a --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/ViewModels/Registrations/RegistrationDetailsViewModel.cs @@ -0,0 +1,42 @@ +namespace EPR.RegulatorService.Frontend.Web.ViewModels.Registrations; + +using System.Diagnostics.CodeAnalysis; + +[ExcludeFromCodeCoverage] +public class RegistrationDetailsViewModel +{ + public string OrganisationName { get; set; } + public string? BuildingName { get; set; } + public string? SubBuildingName { get; set; } + public string? BuildingNumber { get; set; } + public string? Street { get; set; } + public string? Locality { get; set; } + public string? DependantLocality { get; set; } + public string? Town { get; set; } + public string? County { get; set; } + public string? Country { get; set; } + public string? PostCode { get; set; } + public string OrganisationType { get; set; } + public string OrganisationReferenceNumber { get; set; } + public string CompaniesHouseNumber { get; set; } + public string FormattedTimeAndDateOfSubmission { get; set; } + public bool SubmittedOnTime { get; set; } + public Guid SubmissionId { get; set; } + public string SubmittedBy { get; set; } + public string SubmissionPeriod { get; set; } + public string DeclaredBy { get; set; } + public string AccountRole { get; set; } + public string Telephone { get; set; } + public string Email { get; set; } + public string Status { get; set; } + public string PowerBiLogin { get; set; } + public bool IsResubmission { get; set; } + public string RejectionReason { get; set; } + public string PreviousRejectionReason { get; set; } + public string OrganisationDetailsFileName { get; set; } + public Guid OrganisationDetailsFileId { get; set; } + public string PartnershipDetailsFileName { get; set; } + public Guid? PartnershipDetailsFileId { get; set; } + public string BrandDetailsFileName { get; set; } + public Guid? BrandDetailsFileId { get; set; } +} \ No newline at end of file diff --git a/src/EPR.RegulatorService.Frontend.Web/ViewModels/Registrations/RejectRegistrationViewModel.cs b/src/EPR.RegulatorService.Frontend.Web/ViewModels/Registrations/RejectRegistrationViewModel.cs new file mode 100644 index 00000000..0e826bd8 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/ViewModels/Registrations/RejectRegistrationViewModel.cs @@ -0,0 +1,10 @@ +namespace EPR.RegulatorService.Frontend.Web.ViewModels.Registrations +{ + using Attributes; + + public class RejectRegistrationViewModel + { + [CharacterCount("Error.RejectionReason", "Error.RejectionReasonTooLong", 500)] + public string? ReasonForRejection { get; set; } + } +} diff --git a/src/EPR.RegulatorService.Frontend.Web/ViewModels/Submissions/SubmissionDetailsViewModel.cs b/src/EPR.RegulatorService.Frontend.Web/ViewModels/Submissions/SubmissionDetailsViewModel.cs index 6cbf582e..8cc67c4f 100644 --- a/src/EPR.RegulatorService.Frontend.Web/ViewModels/Submissions/SubmissionDetailsViewModel.cs +++ b/src/EPR.RegulatorService.Frontend.Web/ViewModels/Submissions/SubmissionDetailsViewModel.cs @@ -1,9 +1,11 @@ namespace EPR.RegulatorService.Frontend.Web.ViewModels.Submissions; +using Core.Enums; + public class SubmissionDetailsViewModel { public string OrganisationName { get; set; } - public string OrganisationType { get; set; } + public OrganisationType OrganisationType { get; set; } public string OrganisationReferenceNumber { get; set; } public string FormattedTimeAndDateOfSubmission { get; set; } public Guid SubmissionId { get; set; } diff --git a/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/AcceptRegistrationSubmission.cshtml b/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/AcceptRegistrationSubmission.cshtml new file mode 100644 index 00000000..7a18c771 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/AcceptRegistrationSubmission.cshtml @@ -0,0 +1,77 @@ +@using EPR.RegulatorService.Frontend.Web.Extensions +@using EPR.RegulatorService.Frontend.Web.ViewModels.Registrations +@using EPR.RegulatorService.Frontend.Web.ViewModels.Shared.GovUK + +@model AcceptRegistrationSubmissionViewModel +@{ + ViewData["Title"] = Localizer["Title.AcceptSubmission"]; + var errorsViewModel = new ErrorsViewModel(ViewData.ModelState.ToErrorDictionary(), Localizer); +} + +@using (Html.BeginForm("AcceptRegistrationSubmission", "Registrations", FormMethod.Post)) +{ +
+
+
+
+ @if (!ViewData.ModelState.IsValid) + { + @await Html.PartialAsync("Partials/Govuk/_ErrorSummary", errorsViewModel) + } +
+
+
+ +

+ @Localizer["Header.AreYouSure"] +

+
+
+ @await Html.PartialAsync("Partials/Govuk/_FormItemError", errorsViewModel[nameof(AcceptRegistrationSubmissionViewModel.Accepted)]) +
+ + +
+
+ + +
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+} diff --git a/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/RegistrationDetails.cshtml b/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/RegistrationDetails.cshtml new file mode 100644 index 00000000..5fd1da7a --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/RegistrationDetails.cshtml @@ -0,0 +1,107 @@ +@using EPR.RegulatorService.Frontend.Web.ViewModels.Shared.GovUK +@using EPR.RegulatorService.Frontend.Web.Extensions +@using EPR.RegulatorService.Frontend.Web.ViewModels.Registrations +@using Microsoft.Extensions.Options +@using EPR.RegulatorService.Frontend.Web.Configs + +@inject IOptions ExternalUrls + +@model RegistrationDetailsViewModel +@{ + ViewData["Title"] = Localizer["Title.ManageRegistrationDataSubmissions"]; + var errorsViewModel = new ErrorsViewModel(ViewData.ModelState.ToErrorDictionary(), Localizer); +} + +
+
+
+
+ @if (!ViewData.ModelState.IsValid) + { + @await Html.PartialAsync("Partials/Govuk/_ErrorSummary", errorsViewModel) + } + +

@Localizer["Title.RegistrationsOrgTitle"]

+

@Model.OrganisationName

+
+

@Localizer["SubTitle.OrganisationType"]

+

@Model.OrganisationType

+
+
+

@Localizer["SubTitle.OrganisationId"]

+

@Model.OrganisationReferenceNumber

+
+
+

+ @if (string.IsNullOrEmpty(Model.CompaniesHouseNumber)) + { + @Localizer["SubTitle.HeadOfficeAddress"] + } + else + { + @Localizer["SubTitle.RegisteredAddress"] + } +

+

+ @if (!string.IsNullOrWhiteSpace(Model.BuildingName)){@Model.BuildingName
} + @if (!string.IsNullOrWhiteSpace(Model.SubBuildingName)){@Model.SubBuildingName
} + @if (!string.IsNullOrWhiteSpace(Model.BuildingNumber) && !string.IsNullOrWhiteSpace(Model.Street)) + { + @Model.BuildingNumber @Model.Street
+ } + @if (!string.IsNullOrWhiteSpace(Model.Locality)){@Model.Locality
} + @if (!string.IsNullOrWhiteSpace(Model.DependantLocality)){@Model.DependantLocality
} + @if (!string.IsNullOrWhiteSpace(Model.Town)){@Model.Town
} + @if (!string.IsNullOrWhiteSpace(Model.County)){@Model.County
} + @if (!string.IsNullOrWhiteSpace(Model.Country)){@Model.Country
} + @if (!string.IsNullOrWhiteSpace(Model.PostCode)){@Model.PostCode
} +

+
+
+

@Localizer["SubTitle.CompaniesHouseNumber"]

+

+ @if (string.IsNullOrWhiteSpace(Model.CompaniesHouseNumber)) + { + @SharedLocalizer["NotListed"] + } + else + { + @Model.CompaniesHouseNumber +
+ @Localizer["Link.ViewOnCompaniesHouseRegister"] + } +

+
+
+

@Localizer["SubTitle.PowerBI"]

+

@Localizer["SubTitle.PowerBIOrg.Text"] + @SharedLocalizer["Link.LogIntoPowerBI"]. +

+
+
+
+ +
+
+ @if (!Model.IsResubmission) + { + + } + else + { + + } +
+
+ +
+
+ @Html.ActionLink(Localizer["Link.BackToRegistrations"].Value, + "Registrations", + "Registrations", + null, + new {@class = "govuk-body govuk-link govuk-link--no-visited-state"}) +
+
+
+
diff --git a/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/Registrations.cshtml b/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/Registrations.cshtml index e3955804..aa471e02 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/Registrations.cshtml +++ b/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/Registrations.cshtml @@ -1,7 +1,7 @@ -@using EPR.RegulatorService.Frontend.Web.ViewModels.Shared.GovUK -@using EPR.RegulatorService.Frontend.Web.Extensions @using EPR.RegulatorService.Frontend.Core.Models +@using EPR.RegulatorService.Frontend.Web.Extensions @using EPR.RegulatorService.Frontend.Web.ViewModels.Registrations +@using EPR.RegulatorService.Frontend.Web.ViewModels.Shared.GovUK @model RegistrationsViewModel @@ -41,7 +41,7 @@ @Localizer["Title.RegistrationsTitle"]
- @Localizer["Page.Registrations.Subtitle"] @Localizer["PowerBILogin"]. + @Localizer["Page.Registrations.Subtitle"] @SharedLocalizer["Link.LogIntoPowerBI"].
@await Component.InvokeAsync("RegistrationsList", diff --git a/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/RejectRegistration.cshtml b/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/RejectRegistration.cshtml new file mode 100644 index 00000000..5289723a --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Views/Registrations/RejectRegistration.cshtml @@ -0,0 +1,64 @@ +@using EPR.RegulatorService.Frontend.Web.Extensions +@using EPR.RegulatorService.Frontend.Web.ViewModels.Registrations +@using EPR.RegulatorService.Frontend.Web.ViewModels.Shared.GovUK + +@model RejectRegistrationViewModel +@{ + ViewData["Title"] = Localizer["Title.RejectSubmission"]; + var errorsViewModel = new ErrorsViewModel(ViewData.ModelState.ToErrorDictionary(), Localizer, nameof(Model.ReasonForRejection)); + var reasonForRejection = string.IsNullOrEmpty(Model.ReasonForRejection) ? string.Empty : Model.ReasonForRejection; + var reasonForRejectionError = errorsViewModel.Errors.FirstOrDefault(x => x.Key == nameof(Model.ReasonForRejection)); + var reasonForRejectionErrorExists = !string.IsNullOrEmpty(reasonForRejectionError.Key); +} + +@using (Html.BeginForm("RejectRegistration", "Registrations", FormMethod.Post)) +{ +
+
+
+
+ @if (!ViewData.ModelState.IsValid) + { + @await Html.PartialAsync("Partials/Govuk/_ErrorSummary", errorsViewModel) + } +

+ +

+

@Localizer["Title.Description"]

+
+
+ +
+
+
+
+ @if (reasonForRejectionErrorExists) + { + @await Html.PartialAsync("Partials/Govuk/_InlineError", reasonForRejectionError) + } + +
+
+ @SharedLocalizer["CharacterLimit.NoJavaScript"] +
+
+
+
+ +
+
+ + @Html.ActionLink(SharedLocalizer["Cancel"], + "RegistrationDetails", + "Registrations", + null, + new { @class = "govuk-body govuk-link govuk-link--no-visited-state epr-horizontal-control epr-horizontal-control-link" }) +
+
+
+
+} diff --git a/src/EPR.RegulatorService.Frontend.Web/Views/Shared/Components/RegistrationsList/Default.cshtml b/src/EPR.RegulatorService.Frontend.Web/Views/Shared/Components/RegistrationsList/Default.cshtml index 935f5bef..852de26f 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Views/Shared/Components/RegistrationsList/Default.cshtml +++ b/src/EPR.RegulatorService.Frontend.Web/Views/Shared/Components/RegistrationsList/Default.cshtml @@ -23,7 +23,7 @@ - @using (Html.BeginForm("Registrations", "Registrations", new { jsonSubmission = JsonSerializer.Serialize(registration) }, FormMethod.Post)) + @using (Html.BeginForm("Registrations", "Registrations", new { jsonRegistration = JsonSerializer.Serialize(registration) }, FormMethod.Post)) { + + +
+ +
+ + } + + + diff --git a/src/EPR.RegulatorService.Frontend.Web/Views/Shared/Partials/_RegistrationSubmissionDetails.cshtml b/src/EPR.RegulatorService.Frontend.Web/Views/Shared/Partials/_RegistrationSubmissionDetails.cshtml new file mode 100644 index 00000000..7fb16093 --- /dev/null +++ b/src/EPR.RegulatorService.Frontend.Web/Views/Shared/Partials/_RegistrationSubmissionDetails.cshtml @@ -0,0 +1,197 @@ +@using EPR.RegulatorService.Frontend.Core.Extensions +@using EPR.RegulatorService.Frontend.Web.Configs +@using EPR.RegulatorService.Frontend.Web.Constants +@using EPR.RegulatorService.Frontend.Web.ViewModels.Registrations +@using Microsoft.Extensions.Options + +@model RegistrationDetailsViewModel + +@inject IOptions ExternalUrls + +
+
+

+ @Localizer["SummaryList.Title"] + @if (!string.IsNullOrEmpty(Model.SubmissionPeriod)) + { + - @Model.SubmissionPeriod + } +

+
    +
  • + @switch (Model.Status) + { + case SubmissionStatus.Pending: + @SharedLocalizer["Tag.Pending"] + break; + case SubmissionStatus.Accepted: + @SharedLocalizer["Tag.Accepted"] + break; + case SubmissionStatus.Rejected: + @SharedLocalizer["Tag.Rejected"] + break; + } +
  • +
+
+
+
+
+
+ @Localizer["SummaryList.SubTitle.TimeAndDateOfSubmission"] +
+
+ @Model.FormattedTimeAndDateOfSubmission +
+
+
+ +
+
+ @Localizer["SummaryList.SubTitle.SubmittedOnTime"] +
+
+ @Model.SubmittedOnTime.ToYesNo() +
+
+
+ +
+
+ @Localizer["SummaryList.SubTitle.SubmittedBy"] +
+
+ @Model.SubmittedBy +
+
+
+ +
+
+ @Localizer["SummaryList.SubTitle.AccountRole"] +
+
+ @Model.AccountRole +
+
+
+ +
+
+ @Localizer["SummaryList.SubTitle.Telephone"] +
+
+ @Model.Telephone +
+
+
+ +
+
+ @Localizer["SummaryList.SubTitle.Email"] +
+
+ @Model.Email +
+
+
+ +
+
+ @Localizer["SummaryList.SubTitle.DeclaredBy"] +
+
+ @Model.DeclaredBy +
+
+
+ +
+
+ @Localizer["SummaryList.SubTitle.OrganisationDetails"] +
+
+ @Model.OrganisationDetailsFileName +
+ +
+ + @if (!string.IsNullOrEmpty(Model.BrandDetailsFileName)) + { +
+
+ @Localizer["SummaryList.SubTitle.BrandDetails"] +
+
+ @Model.BrandDetailsFileName +
+ +
+ } + + @if (!string.IsNullOrEmpty(Model.PartnershipDetailsFileName)) + { +
+
+ @Localizer["SummaryList.SubTitle.PartnerDetails"] +
+
+ @Model.PartnershipDetailsFileName +
+ +
+ } + @if (!string.IsNullOrEmpty(Model.RejectionReason) && Model.Status == SubmissionStatus.Rejected) + { +
+
+ @Localizer["SummaryList.SubTitle.ReasonForRejection"] +
+
+ @Model.RejectionReason +
+
+
+ } + @if (Model.Status == EnrolmentStatus.Pending) + { +
+
+ } +
+ @if (Model.Status == EnrolmentStatus.Pending) + { +
@Localizer["SummaryList.Information.Text", Model.OrganisationName]
+
+ +
+ +
+ +
+ +
+
+ } +
+
+ diff --git a/src/EPR.RegulatorService.Frontend.Web/Views/Shared/Partials/_RegulatorRegistrationFilters.cshtml b/src/EPR.RegulatorService.Frontend.Web/Views/Shared/Partials/_RegulatorRegistrationFilters.cshtml index a8882704..7add8e45 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Views/Shared/Partials/_RegulatorRegistrationFilters.cshtml +++ b/src/EPR.RegulatorService.Frontend.Web/Views/Shared/Partials/_RegulatorRegistrationFilters.cshtml @@ -3,7 +3,7 @@ @model RegulatorRegistrationFiltersModel -@using (Html.BeginForm("Registrations", "Registrations", FormMethod.Post)) +@using (Html.BeginForm("Registrations", "Registrations", FormMethod.Get)) {
diff --git a/src/EPR.RegulatorService.Frontend.Web/Views/Submissions/Submissions.cshtml b/src/EPR.RegulatorService.Frontend.Web/Views/Submissions/Submissions.cshtml index 196a3655..0f0b7cb0 100644 --- a/src/EPR.RegulatorService.Frontend.Web/Views/Submissions/Submissions.cshtml +++ b/src/EPR.RegulatorService.Frontend.Web/Views/Submissions/Submissions.cshtml @@ -1,7 +1,7 @@ -@using EPR.RegulatorService.Frontend.Web.ViewModels.Submissions -@using EPR.RegulatorService.Frontend.Web.ViewModels.Shared.GovUK -@using EPR.RegulatorService.Frontend.Web.Extensions @using EPR.RegulatorService.Frontend.Core.Models +@using EPR.RegulatorService.Frontend.Web.Extensions +@using EPR.RegulatorService.Frontend.Web.ViewModels.Shared.GovUK +@using EPR.RegulatorService.Frontend.Web.ViewModels.Submissions @model SubmissionsViewModel @@ -39,7 +39,7 @@ @Localizer["Title.SubmissionsTitle"]
- @Localizer["Page.Submissions.Subtitle"] @Localizer["PowerBILogin"]. + @Localizer["Page.Submissions.Subtitle"] @SharedLocalizer["Link.LogIntoPowerBI"].
@await Component.InvokeAsync("SubmissionsList", diff --git a/src/EPR.RegulatorService.Frontend.Web/appsettings.json b/src/EPR.RegulatorService.Frontend.Web/appsettings.json index d5cec0d8..b5c4daa3 100644 --- a/src/EPR.RegulatorService.Frontend.Web/appsettings.json +++ b/src/EPR.RegulatorService.Frontend.Web/appsettings.json @@ -52,6 +52,8 @@ "PrivacyEnvironmentAgency": "https://npwd.environment-agency.gov.uk/Public/Guidance.aspx?CategoryId=ad749427-9848-41a6-9d8e-ddf142e98720&ReturnUrl=%2fPublic%2fNewsAndGuidance.aspx", "LandingPageUrl": "/regulators/home", "PowerBILogin": "https://app.powerbi.com/groups/me/apps/19782b5f-9ff7-4d08-a585-19293c52d516/reports/9ebf2c90-a6d0-43da-91da-847e51bada07/ReportSection?ctid=770a2450-0227-4c62-90c7-4e38537f1102&experience=power-bi" + "CompaniesHouseRegisterBaseUrl": "https://find-and-update.company-information.service.gov.uk/company", + "RegistrationFileDownloadBaseUrl": "https://tempfakelinktodownload.com/" }, "EmailAddresses": { "DataProtection": "data.protection@defra.gov.uk", @@ -90,8 +92,10 @@ "GetOrganisationUsersByOrganisationExternalIdPath": "organisations/users-by-organisation-external-id?externalId={0}", "PomSubmissions": "pom/get-submissions", "PomSubmissionDecision": "pom/regulator-decision", - "OrganisationsRemoveApprovedUser" : "organisations/remove-approved-users?connExternalId={0}&organisationId={1}&promotedPersonExternalId={2}", - "AddRemoveApprovedUser": "organisations/add-remove-approved-users" + "OrganisationsRemoveApprovedUser" : "organisations/remove-approved-users?connExternalId={0}&organisationId={1}", + "AddRemoveApprovedUser": "organisations/add-remove-approved-users", + "RegistrationSubmissions": "registrations/get-submissions", + "RegistrationSubmissionDecisionPath" : "registration/regulator-decision" } }, "Pagination": { @@ -117,6 +121,7 @@ "ShowLanguageSwitcher": true, "ManagePoMSubmissions": true, "ManageRegistrations": true, - "ManageApprovedUsers": false + "ManageApprovedUsers": false, + "PomDataPeriodAndTime": true } } diff --git a/src/EPR.RegulatorService.Frontend.Web/assets/scss/application.scss b/src/EPR.RegulatorService.Frontend.Web/assets/scss/application.scss index bef32e61..2aae62a3 100644 --- a/src/EPR.RegulatorService.Frontend.Web/assets/scss/application.scss +++ b/src/EPR.RegulatorService.Frontend.Web/assets/scss/application.scss @@ -373,10 +373,18 @@ button.epr-link-no-visited-state { width: 28%; } +.epr-width-twenty-two-percent { + width: 22%; +} + .epr-width-sixteen-percent { width: 16%; } +.epr-summary-list-download-link { + text-align: right; +} + table.cookies-table { @media (min-width: $narrow-media-width) { table-layout: auto; diff --git a/src/Epr.RegulatorService.sln b/src/Epr.RegulatorService.sln index 93d7c757..959f7b05 100644 --- a/src/Epr.RegulatorService.sln +++ b/src/Epr.RegulatorService.sln @@ -1,10 +1,13 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EPR.RegulatorService.Frontend.Core", "EPR.RegulatorService.Frontend.Core\EPR.RegulatorService.Frontend.Core.csproj", "{3C9225BF-917E-4E81-BED3-FC72776BC19C}" +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34607.119 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EPR.RegulatorService.Frontend.Core", "EPR.RegulatorService.Frontend.Core\EPR.RegulatorService.Frontend.Core.csproj", "{3C9225BF-917E-4E81-BED3-FC72776BC19C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EPR.RegulatorService.Frontend.Web", "EPR.RegulatorService.Frontend.Web\EPR.RegulatorService.Frontend.Web.csproj", "{2A9F6DCA-F5FF-4B2C-9703-E71CDC225A1D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EPR.RegulatorService.Frontend.Web", "EPR.RegulatorService.Frontend.Web\EPR.RegulatorService.Frontend.Web.csproj", "{2A9F6DCA-F5FF-4B2C-9703-E71CDC225A1D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EPR.RegulatorService.Frontend.UnitTests", "EPR.RegulatorService.Frontend.UnitTests\EPR.RegulatorService.Frontend.UnitTests.csproj", "{4B38E54D-26F9-4C21-8859-ED5691DAEB13}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EPR.RegulatorService.Frontend.UnitTests", "EPR.RegulatorService.Frontend.UnitTests\EPR.RegulatorService.Frontend.UnitTests.csproj", "{4B38E54D-26F9-4C21-8859-ED5691DAEB13}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -25,4 +28,7 @@ Global {4B38E54D-26F9-4C21-8859-ED5691DAEB13}.Release|Any CPU.ActiveCfg = Release|Any CPU {4B38E54D-26F9-4C21-8859-ED5691DAEB13}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal