Skip to content

Commit

Permalink
Merge pull request #342 from ministryofjustice/activity-templates-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
carlsixsmith-moj authored Dec 6, 2024
2 parents bb85b1a + 2450c6b commit a30caaf
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 35 deletions.
40 changes: 38 additions & 2 deletions src/Application/Features/Payables/Commands/AddEducationTraining.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Cfo.Cats.Application.Common.Security;
using Cfo.Cats.Application.SecurityConstants;
using Humanizer.Bytes;
using Microsoft.AspNetCore.Components.Forms;

namespace Cfo.Cats.Application.Features.Payables.Commands;

Expand All @@ -26,8 +28,8 @@ public class Command : IRequest<Result<bool>>
[Description("Passed")]
public string? Passed { get; set; }

[Description("Additional Information")]
public string? AdditionalInformation { get; set; }
[Description("Upload Education/Training Template")]
public IBrowserFile? Document { get; set; }
}

class Handler: IRequestHandler<Command, Result<bool>>
Expand Down Expand Up @@ -63,7 +65,41 @@ public Validator(IUnitOfWork unitOfWork)
.NotNull()
.WithMessage("You must choose a value for Passed");

RuleFor(v => v.Document)
.NotNull()
.WithMessage("You must upload a Right to Work document")
.Must(file => NotExceedMaximumFileSize(file, Infrastructure.Constants.Documents.RightToWork.MaximumSizeInMegabytes))
.WithMessage($"File size exceeds the maxmimum allowed size of {Infrastructure.Constants.Documents.RightToWork.MaximumSizeInMegabytes} megabytes")
.MustAsync(BePdfFile)
.WithMessage("File is not a PDF");
}

private static bool NotExceedMaximumFileSize(IBrowserFile? file, double maxSizeMB)
=> file?.Size < ByteSize.FromMegabytes(maxSizeMB).Bytes;

private async Task<bool> BePdfFile(IBrowserFile? file, CancellationToken cancellationToken)
{
if (file is null)
return false;

// Check file extension
if (!Path.GetExtension(file.Name).Equals(".pdf", StringComparison.OrdinalIgnoreCase))
return false;

// Check MIME type
if (file.ContentType != "application/pdf")
return false;

long maxSizeBytes = Convert.ToInt64(ByteSize.FromMegabytes(Infrastructure.Constants.Documents.RightToWork.MaximumSizeInMegabytes).Bytes);

// Check file signature (magic numbers)
using (var stream = file.OpenReadStream(maxSizeBytes, cancellationToken))
{
byte[] buffer = new byte[4];
await stream.ReadExactlyAsync(buffer.AsMemory(0, 4), cancellationToken);
string header = System.Text.Encoding.ASCII.GetString(buffer);
return header == "%PDF";
}
}
}
}
4 changes: 0 additions & 4 deletions src/Application/Features/Payables/Commands/AddEmployment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ public class Command : IRequest<Result<bool>>

[Description("Upload Employment Template")]
public IBrowserFile? Document { get; set; }

[Description("Additional Information")]
public string? AdditionalInformation { get; set; }
}

class Handler: IRequestHandler<Command, Result<bool>>
Expand Down Expand Up @@ -75,7 +72,6 @@ public Validator(IUnitOfWork unitOfWork)
.NotNull()
.WithMessage("You must choose a Employment start date");


RuleFor(v => v.Document)
.NotNull()
.WithMessage("You must upload a Right to Work document")
Expand Down
13 changes: 9 additions & 4 deletions src/Domain/Common/Enums/ActivityDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -345,12 +345,17 @@ private DeliveryLocationType(string name, int value) : base(name, value) { }

public class ClassificationType : SmartEnum<ClassificationType>
{
public static readonly ClassificationType EducationAndTraining = new ClassificationType("Education and Training", 0);
public static readonly ClassificationType Employment = new ClassificationType("Employment", 1);
public static readonly ClassificationType ISWActivity = new ClassificationType("ISW Activity", 2);
public static readonly ClassificationType EducationAndTraining = new ClassificationType("Education and Training", 0, true);
public static readonly ClassificationType Employment = new ClassificationType("Employment", 1, true);
public static readonly ClassificationType ISWActivity = new ClassificationType("ISW Activity", 2, true);
public static readonly ClassificationType NonISWActivity = new ClassificationType("Non-ISW Activity", 3);

private ClassificationType(string name, int value) : base(name, value) { }
private ClassificationType(string name, int value, bool requiresFurtherInformation = false) : base(name, value)
{
RequiresFurtherInformation = requiresFurtherInformation;
}

public bool RequiresFurtherInformation { get; private set; }
}

public class ActivityETEType(string name, int value, string? shortenedDisplayName = null) : SmartEnum<ActivityETEType>(name, value)
Expand Down
21 changes: 20 additions & 1 deletion src/Server.UI/Pages/Payables/AddActivityDialog.razor
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
}
</MudSelect>
</MudItem>

<MudItem xs="12">
<MudDatePicker @bind-Date="Model.Completed"
For="() => Model.Completed"
Expand All @@ -64,6 +63,26 @@
For="() => Model.AdditionalInformation"
Lines="5" />
</MudItem>
@if (Model.ActivityDefinition is { ClassificationType.RequiresFurtherInformation: true })
{
<MudItem xs="12">
<MudAlert Severity="Severity.Info">Further information is required for this type of activity</MudAlert>

@if(Model.ActivityDefinition.ClassificationType == ClassificationType.Employment)
{
<Employment Model="new AddEmployment.Command()"/>
}
else if(Model.ActivityDefinition.ClassificationType == ClassificationType.EducationAndTraining)
{
<EducationTraining Model="new AddEducationTraining.Command()" />
}
else if(Model.ActivityDefinition.ClassificationType == ClassificationType.ISWActivity)
{
<MudText>ISW Template</MudText>
}

</MudItem>
}
</MudGrid>
</MudForm>
}
Expand Down
48 changes: 41 additions & 7 deletions src/Server.UI/Pages/Payables/Components/EducationTraining.razor
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,52 @@
<MudSelectItem Value="@("Not Applicable")">Not Applicable</MudSelectItem>
</MudSelect>
</MudItem>
<MudTextField @bind-Value="@Model.AdditionalInformation"
For="@(() => Model.AdditionalInformation)"
Lines="5"
Label="@Model.GetMemberDescription(x => x.AdditionalInformation)"
Placeholder="Use this area to provide any additional information with regards to Employment.">
</MudTextField>
<MudItem xs="12">
<div class="mb-4 mt-8">
<MudFileUpload @bind-Files="Model.Document"
For="() => Model.Document"
MaximumFileCount="1"
Accept=".pdf" >
<ActivatorContent>
<MudLoadingButton Loading="uploading"
Variant="Variant.Outlined"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Upload">
@if (uploading)
{
@ConstantString.Uploading
}
else
{
@ConstantString.Upload
}
</MudLoadingButton>
</ActivatorContent>
<SelectedTemplate>
<br />
@if (context != null)
{
<MudText>
Education template uploaded: @context.Name
</MudText>
}
else
{
<MudText>No Files</MudText>
}
<br />
</SelectedTemplate>
</MudFileUpload>
</div>
</MudItem>
</MudGrid>
}
@code {
private bool uploading = false;

[Inject]
private IPicklistService PicklistService { get; set; } = default!;

[Parameter, EditorRequired]
public required AddEducationTraining.Command Model { get; set; }

}
26 changes: 9 additions & 17 deletions src/Server.UI/Pages/Payables/Components/Employment.razor
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@
<MudItem xs="12">
<div class="mb-4 mt-8">
<MudFileUpload @bind-Files="Model.Document"
For="() => Model.Document"
MaximumFileCount="1"
Accept=".pdf" Disabled="Disabled">
For="() => Model.Document"
MaximumFileCount="1"
Accept=".pdf" Disabled="Disabled">
<ActivatorContent>
<MudLoadingButton Loading="_uploading"
<MudLoadingButton Loading="uploading"
Variant="Variant.Outlined"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Upload">
@if (_uploading)
@if (uploading)
{
@ConstantString.Uploading
}
Expand All @@ -81,7 +81,7 @@
@if (context != null)
{
<MudText>
Right To Work supporting documentation uploaded: @context.Name
Employment template uploaded: @context.Name
</MudText>
}
else
Expand All @@ -93,25 +93,17 @@
</MudFileUpload>
</div>
</MudItem>
<MudItem xs="12">
<MudTextField @bind-Value="@Model.AdditionalInformation"
For="@(() => Model.AdditionalInformation)"
Lines="5"
Label="@Model.GetMemberDescription(x => x.AdditionalInformation)"
Placeholder="Use this area to provide any additional information with regards to Employment.">
</MudTextField>
</MudItem>
</MudGrid>
}
@code {
private bool uploading = false;

[Inject]
private IPicklistService PicklistService { get; set; } = default!;

[Parameter, EditorRequired]
public required AddEmployment.Command Model { get; set; }

private bool _uploading = false;

//bool Disabled => Model.Location is null;
bool Disabled = false;

}

0 comments on commit a30caaf

Please sign in to comment.