Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/src/Feature.QuickReports/Get/Endpoint.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Authorization.Policies.Requirements;
using Feature.QuickReports.Models;
using Feature.QuickReports.Specifications;
using Microsoft.AspNetCore.Authorization;
using Vote.Monitor.Core.Services.FileStorage.Contracts;
Expand Down
61 changes: 0 additions & 61 deletions api/src/Feature.QuickReports/Get/QuickReportDetailedModel.cs

This file was deleted.

9 changes: 9 additions & 0 deletions api/src/Feature.QuickReports/List/Endpoint.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Authorization.Policies;
using Dapper;
using Feature.QuickReports.Models;
using Vote.Monitor.Core.Models;
using Vote.Monitor.Domain.ConnectionFactory;
using Vote.Monitor.Domain.Specifications;
Expand Down Expand Up @@ -36,6 +37,8 @@ public override async Task<PagedResponse<QuickReportOverviewModel>> ExecuteAsync
AND MN."NgoId" = @ngoId
AND (@followUpStatus IS NULL or QR."FollowUpStatus" = @followUpStatus)
AND (@quickReportLocationType IS NULL or QR."QuickReportLocationType" = @quickReportLocationType)
AND (@issueType IS NULL or QR."IssueType" = @issueType)
AND (@officialComplaintFilingStatus IS NULL or QR."OfficialComplaintFilingStatus" = @officialComplaintFilingStatus)
AND (
@level1 IS NULL
OR PS."Level1" = @level1
Expand Down Expand Up @@ -64,6 +67,8 @@ @level5 IS NULL
QR."Title",
QR."Description",
QR."FollowUpStatus",
QR."IssueType",
QR."OfficialComplaintFilingStatus",
COUNT(QRA."Id") FILTER(WHERE QRA."IsDeleted" = FALSE AND QRA."IsCompleted" = TRUE) AS "NumberOfAttachments",
O."FirstName",
O."LastName",
Expand All @@ -90,6 +95,8 @@ @level5 IS NULL
AND MN."NgoId" = @ngoId
AND (@followUpStatus IS NULL or QR."FollowUpStatus" = @followUpStatus)
AND (@quickReportLocationType IS NULL or QR."QuickReportLocationType" = @quickReportLocationType)
AND (@issueType IS NULL or QR."IssueType" = @issueType)
AND (@officialComplaintFilingStatus IS NULL or QR."OfficialComplaintFilingStatus" = @officialComplaintFilingStatus)
AND (
@level1 IS NULL
OR PS."Level1" = @level1
Expand Down Expand Up @@ -136,6 +143,8 @@ FETCH NEXT
level4 = req.Level4Filter,
level5 = req.Level5Filter,
followUpStatus = req.FollowUpStatus?.ToString(),
issueType = req.IssueType?.ToString(),
officialComplaintFilingStatus = req.OfficialComplaintFilingStatus?.ToString(),
quickReportLocationType = req.QuickReportLocationType?.ToString(),
sortExpression = GetSortExpression(req.SortColumnName, req.IsAscendingSorting)
};
Expand Down
6 changes: 6 additions & 0 deletions api/src/Feature.QuickReports/List/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,10 @@ public class Request : BaseSortPaginatedRequest

[QueryParam]
public QuickReportLocationType? QuickReportLocationType { get; set; }

[QueryParam]
public QuickReportIssueType? IssueType { get; set; }

[QueryParam]
public QuickReportOfficialComplaintFilingStatus? OfficialComplaintFilingStatus { get; set; }
}
1 change: 1 addition & 0 deletions api/src/Feature.QuickReports/ListMy/Endpoint.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Authorization.Policies;
using Authorization.Policies.Requirements;
using Feature.QuickReports.Models;
using Feature.QuickReports.Specifications;
using Microsoft.AspNetCore.Authorization;
using Vote.Monitor.Core.Services.FileStorage.Contracts;
Expand Down
44 changes: 44 additions & 0 deletions api/src/Feature.QuickReports/Models/QuickReportDetailedModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Vote.Monitor.Domain.Entities.QuickReportAggregate;

namespace Feature.QuickReports.Models;

public record QuickReportDetailedModel : QuickReportOverviewModel
{
public Guid MonitoringObserverId { get; init; }

public List<QuickReportAttachmentModel> Attachments { get; init; }

public static QuickReportDetailedModel FromEntity(QuickReport quickReport,
IEnumerable<QuickReportAttachmentModel> attachments)
{
var attachmentsList = attachments.ToList();

return new QuickReportDetailedModel
{
Id = quickReport.Id,
QuickReportLocationType = quickReport.QuickReportLocationType,
IssueType = quickReport.IssueType,
OfficialComplaintFilingStatus = quickReport.OfficialComplaintFilingStatus,
Title = quickReport.Title,
Description = quickReport.Description,
MonitoringObserverId = quickReport.MonitoringObserverId,
FirstName = quickReport.MonitoringObserver.Observer.ApplicationUser.FirstName,
LastName = quickReport.MonitoringObserver.Observer.ApplicationUser.LastName,
PollingStationId = quickReport.PollingStationId,
Level1 = quickReport.PollingStation?.Level1,
Level2 = quickReport.PollingStation?.Level2,
Level3 = quickReport.PollingStation?.Level3,
Level4 = quickReport.PollingStation?.Level4,
Level5 = quickReport.PollingStation?.Level5,
Number = quickReport.PollingStation?.Number,
Address = quickReport.PollingStation?.Address,
PollingStationDetails = quickReport.PollingStationDetails,
Timestamp = quickReport.LastModifiedOn ?? quickReport.CreatedOn,
Attachments = attachmentsList,
FollowUpStatus = quickReport.FollowUpStatus,
NumberOfAttachments = attachmentsList.Count,
Email = quickReport.MonitoringObserver.Observer.ApplicationUser.Email ?? "",
PhoneNumber = quickReport.MonitoringObserver.Observer.ApplicationUser.PhoneNumber ?? "",
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@
using Ardalis.SmartEnum.SystemTextJson;
using Vote.Monitor.Domain.Entities.QuickReportAggregate;

namespace Feature.QuickReports;
namespace Feature.QuickReports.Models;

public record QuickReportModel
{
public Guid Id { get; init; }
public Guid ElectionRoundId { get; init; }

[JsonConverter(typeof(SmartEnumNameConverter<QuickReportLocationType, string>))]
public QuickReportLocationType QuickReportLocationType { get; init; }

[JsonConverter(typeof(SmartEnumNameConverter<QuickReportIssueType, string>))]
public QuickReportIssueType IssueType { get; set; }

[JsonConverter(typeof(SmartEnumNameConverter<QuickReportOfficialComplaintFilingStatus, string>))]
public QuickReportOfficialComplaintFilingStatus OfficialComplaintFilingStatus { get; set; }

public DateTime Timestamp { get; init; }
public string Title { get; init; }
public string Description { get; init; }
Expand All @@ -19,21 +25,22 @@ public record QuickReportModel
public string? PollingStationDetails { get; init; }
public List<QuickReportAttachmentModel> Attachments { get; init; }

public static QuickReportModel FromEntity(QuickReport quickReport, IEnumerable<QuickReportAttachmentModel> attachments)
public static QuickReportModel FromEntity(QuickReport quickReport,
IEnumerable<QuickReportAttachmentModel> attachments)
{
return new QuickReportModel
{
Id = quickReport.Id,
ElectionRoundId = quickReport.ElectionRoundId,
QuickReportLocationType = quickReport.QuickReportLocationType,
Title = quickReport.Title,
Description = quickReport.Description,
MonitoringObserverId = quickReport.MonitoringObserverId,
PollingStationId = quickReport.PollingStationId,
PollingStationDetails = quickReport.PollingStationDetails,
Timestamp = quickReport.LastModifiedOn ?? quickReport.CreatedOn,
IssueType = quickReport.IssueType,
OfficialComplaintFilingStatus = quickReport.OfficialComplaintFilingStatus,
Attachments = attachments.ToList()
};
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@
using Ardalis.SmartEnum.SystemTextJson;
using Vote.Monitor.Domain.Entities.QuickReportAggregate;

namespace Feature.QuickReports.List;
namespace Feature.QuickReports.Models;

public class QuickReportOverviewModel
public record QuickReportOverviewModel
{
public Guid Id { get; set; }

[JsonConverter(typeof(SmartEnumNameConverter<QuickReportLocationType, string>))]
public QuickReportLocationType QuickReportLocationType { get; set; }

[JsonConverter(typeof(SmartEnumNameConverter<QuickReportIssueType, string>))]
public QuickReportIssueType IssueType { get; set; }

[JsonConverter(typeof(SmartEnumNameConverter<QuickReportOfficialComplaintFilingStatus, string>))]
public QuickReportOfficialComplaintFilingStatus OfficialComplaintFilingStatus { get; set; }

public DateTime Timestamp { get; set; }
public string Title { get; set; }
public string Description { get; set; }
Expand All @@ -30,4 +37,4 @@ public class QuickReportOverviewModel

[JsonConverter(typeof(SmartEnumNameConverter<QuickReportFollowUpStatus, string>))]
public QuickReportFollowUpStatus FollowUpStatus { get; set; }
}
}
34 changes: 21 additions & 13 deletions api/src/Feature.QuickReports/Upsert/Endpoint.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Authorization.Policies;
using Authorization.Policies.Requirements;
using Feature.QuickReports.Models;
using Feature.QuickReports.Specifications;
using Microsoft.AspNetCore.Authorization;
using Vote.Monitor.Core.Services.FileStorage.Contracts;
Expand All @@ -22,39 +23,45 @@ public override void Configure()
Post("/api/election-rounds/{electionRoundId}/quick-reports");
DontAutoTag();
Options(x => x.WithTags("quick-reports", "mobile"));
Summary(s =>
{
s.Summary = "Upserts a quick report";
});
Summary(s => { s.Summary = "Upserts a quick report"; });
Policies(PolicyNames.ObserversOnly);
}

public override async Task<Results<Ok<QuickReportModel>, NotFound>> ExecuteAsync(Request req, CancellationToken ct)
public override async Task<Results<Ok<QuickReportModel>, NotFound>> ExecuteAsync(Request req,
CancellationToken ct)
{
var authorizationResult = await authorizationService.AuthorizeAsync(User, new MonitoringObserverRequirement(req.ElectionRoundId));
var authorizationResult =
await authorizationService.AuthorizeAsync(User, new MonitoringObserverRequirement(req.ElectionRoundId));
if (!authorizationResult.Succeeded)
{
return TypedResults.NotFound();
}

var quickReport = await repository.FirstOrDefaultAsync(new GetQuickReportByIdSpecification(req.ElectionRoundId, req.Id), ct);
var quickReport =
await repository.FirstOrDefaultAsync(new GetQuickReportByIdSpecification(req.ElectionRoundId, req.Id), ct);

return quickReport is null ? await AddQuickReportAsync(req, ct) : await UpdateQuickReportAsync(req, quickReport, ct);
return quickReport is null
? await AddQuickReportAsync(req, ct)
: await UpdateQuickReportAsync(req, quickReport, ct);
}

private async Task<Results<Ok<QuickReportModel>, NotFound>> AddQuickReportAsync(Request req,
CancellationToken ct)
{
var monitoringObserverSpecification = new GetMonitoringObserverSpecification(req.ElectionRoundId, req.ObserverId);
var monitoringObserver = await monitoringObserverRepository.FirstOrDefaultAsync(monitoringObserverSpecification, ct);
var monitoringObserverSpecification =
new GetMonitoringObserverSpecification(req.ElectionRoundId, req.ObserverId);
var monitoringObserver =
await monitoringObserverRepository.FirstOrDefaultAsync(monitoringObserverSpecification, ct);

if (monitoringObserver == null)
{
AddError(r => r.ObserverId, "Observer not found");
return TypedResults.NotFound();
}

var quickReport = QuickReport.Create(req.Id, req.ElectionRoundId, monitoringObserver.Id, req.Title, req.Description, req.QuickReportLocationType, req.PollingStationId, req.PollingStationDetails);
var quickReport = QuickReport.Create(req.Id, req.ElectionRoundId, monitoringObserver.Id, req.Title,
req.Description, req.QuickReportLocationType, req.IssueType, req.OfficialComplaintFilingStatus,
req.PollingStationId, req.PollingStationDetails);

await repository.AddAsync(quickReport, ct);

Expand All @@ -67,7 +74,8 @@ private async Task<Results<Ok<QuickReportModel>, NotFound>> UpdateQuickReportAsy
QuickReport quickReport,
CancellationToken ct)
{
quickReport.Update(req.Title, req.Description, req.QuickReportLocationType, req.PollingStationId, req.PollingStationDetails);
quickReport.Update(req.Title, req.Description, req.QuickReportLocationType, req.IssueType,
req.OfficialComplaintFilingStatus, req.PollingStationId, req.PollingStationDetails);
await repository.UpdateAsync(quickReport, ct);

var attachments = await GetPresignedAttachments(req.ElectionRoundId, req.Id, ct);
Expand Down Expand Up @@ -102,4 +110,4 @@ private async Task<QuickReportAttachmentModel[]> GetPresignedAttachments(Guid el

return attachments;
}
}
}
8 changes: 7 additions & 1 deletion api/src/Feature.QuickReports/Upsert/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@ public class Request

[FromClaim(ApplicationClaimTypes.UserId)]
public Guid ObserverId { get; set; }

public Guid Id { get; set; }
public QuickReportLocationType QuickReportLocationType { get; set; }
public QuickReportIssueType IssueType { get; set; } = QuickReportIssueType.A;

public QuickReportOfficialComplaintFilingStatus OfficialComplaintFilingStatus { get; set; } =
QuickReportOfficialComplaintFilingStatus.DoesNotApplyOrOther;

public string Title { get; set; }
public string Description { get; set; }
public Guid? PollingStationId { set; get; }
public string? PollingStationDetails { get; set; }
}
}
4 changes: 4 additions & 0 deletions api/src/Vote.Monitor.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@
x.Serializer.Options.Converters.Add(new SmartEnumValueConverter<FormType, string>());
x.Serializer.Options.Converters.Add(new SmartEnumValueConverter<ExportedDataStatus, string>());
x.Serializer.Options.Converters.Add(new SmartEnumValueConverter<QuickReportLocationType, string>());
x.Serializer.Options.Converters.Add(new SmartEnumValueConverter<QuickReportIssueType, string>());
x.Serializer.Options.Converters.Add(new SmartEnumValueConverter<QuickReportOfficialComplaintFilingStatus, string>());
x.Serializer.Options.Converters.Add(new SmartEnumValueConverter<DisplayLogicCondition, string>());
x.Serializer.Options.Converters.Add(new SmartEnumValueConverter<SubmissionFollowUpStatus, string>());
x.Serializer.Options.Converters.Add(new SmartEnumValueConverter<QuickReportFollowUpStatus, string>());
Expand All @@ -220,6 +222,8 @@
SqlMapper.AddTypeHandler(typeof(FormType), new SmartEnumByValueTypeHandler<FormType, string>());
SqlMapper.AddTypeHandler(typeof(ExportedDataStatus), new SmartEnumByValueTypeHandler<ExportedDataStatus, string>());
SqlMapper.AddTypeHandler(typeof(QuickReportLocationType), new SmartEnumByValueTypeHandler<QuickReportLocationType, string>());
SqlMapper.AddTypeHandler(typeof(QuickReportIssueType), new SmartEnumByValueTypeHandler<QuickReportIssueType, string>());
SqlMapper.AddTypeHandler(typeof(QuickReportOfficialComplaintFilingStatus), new SmartEnumByValueTypeHandler<QuickReportOfficialComplaintFilingStatus, string>());
SqlMapper.AddTypeHandler(typeof(DisplayLogicCondition), new SmartEnumByValueTypeHandler<DisplayLogicCondition, string>());
SqlMapper.AddTypeHandler(typeof(SubmissionFollowUpStatus), new SmartEnumByValueTypeHandler<SubmissionFollowUpStatus, string>());
SqlMapper.AddTypeHandler(typeof(QuickReportFollowUpStatus), new SmartEnumByValueTypeHandler<QuickReportFollowUpStatus, string>());
Expand Down
Loading