diff --git a/api/Vote.Monitor.sln b/api/Vote.Monitor.sln index 93ea1e316..91be0f178 100644 --- a/api/Vote.Monitor.sln +++ b/api/Vote.Monitor.sln @@ -146,6 +146,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Feature.CitizenReports.Atta EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Feature.CitizenReports.Notes.UnitTests", "tests\Feature.CitizenReports.Notes.UnitTests\Feature.CitizenReports.Notes.UnitTests.csproj", "{CCE23C74-3E33-40B7-A1E8-7672BAC5F814}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Feature.Locations", "src\Feature.Locations\Feature.Locations.csproj", "{54B0E751-AD8A-48F5-998C-E6A5701E3EF0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Feature.Locations.UnitTests", "tests\Feature.Locations.UnitTests\Feature.Locations.UnitTests.csproj", "{6DC3922B-5AC8-4968-AE5C-557315576720}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -416,6 +420,14 @@ Global {CCE23C74-3E33-40B7-A1E8-7672BAC5F814}.Debug|Any CPU.Build.0 = Debug|Any CPU {CCE23C74-3E33-40B7-A1E8-7672BAC5F814}.Release|Any CPU.ActiveCfg = Release|Any CPU {CCE23C74-3E33-40B7-A1E8-7672BAC5F814}.Release|Any CPU.Build.0 = Release|Any CPU + {54B0E751-AD8A-48F5-998C-E6A5701E3EF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {54B0E751-AD8A-48F5-998C-E6A5701E3EF0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {54B0E751-AD8A-48F5-998C-E6A5701E3EF0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {54B0E751-AD8A-48F5-998C-E6A5701E3EF0}.Release|Any CPU.Build.0 = Release|Any CPU + {6DC3922B-5AC8-4968-AE5C-557315576720}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6DC3922B-5AC8-4968-AE5C-557315576720}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6DC3922B-5AC8-4968-AE5C-557315576720}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6DC3922B-5AC8-4968-AE5C-557315576720}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -487,6 +499,8 @@ Global {BCBCA6CB-2CEB-4C8A-8078-EC511B812CC9} = {3441EE1D-E3C6-45BE-A020-553816015081} {E0828B1D-4698-4D4B-85BA-1B2346A7B04F} = {3441EE1D-E3C6-45BE-A020-553816015081} {CCE23C74-3E33-40B7-A1E8-7672BAC5F814} = {3441EE1D-E3C6-45BE-A020-553816015081} + {54B0E751-AD8A-48F5-998C-E6A5701E3EF0} = {17945B3C-5A4C-4279-8022-65ABC606A510} + {6DC3922B-5AC8-4968-AE5C-557315576720} = {3441EE1D-E3C6-45BE-A020-553816015081} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {50C20C9F-F2AF-45D8-994A-06661772B31C} diff --git a/api/src/Feature.CitizenReports/CitizenReportsInstaller.cs b/api/src/Feature.CitizenReports/CitizenReportsInstaller.cs index 0e44f5e36..a2455d140 100644 --- a/api/src/Feature.CitizenReports/CitizenReportsInstaller.cs +++ b/api/src/Feature.CitizenReports/CitizenReportsInstaller.cs @@ -6,4 +6,4 @@ public static IServiceCollection AddCitizenReportsFeature(this IServiceCollectio { return services; } -} +} \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/EnableTesting.cs b/api/src/Feature.CitizenReports/EnableTesting.cs index 628393f77..35e8cacbe 100644 --- a/api/src/Feature.CitizenReports/EnableTesting.cs +++ b/api/src/Feature.CitizenReports/EnableTesting.cs @@ -1,3 +1,3 @@ [assembly: InternalsVisibleTo("Feature.CitizenReports.UnitTests")] [assembly: InternalsVisibleTo("Vote.Monitor.Api.IntegrationTests")] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/GetById/Endpoint.cs b/api/src/Feature.CitizenReports/GetById/Endpoint.cs index 2a488dc6f..da056a06d 100644 --- a/api/src/Feature.CitizenReports/GetById/Endpoint.cs +++ b/api/src/Feature.CitizenReports/GetById/Endpoint.cs @@ -27,6 +27,7 @@ public override async Task, NotFound>> ExecuteAsync(Request .CitizenReports .Include(x => x.Attachments) .Include(x => x.Notes) + .Include(x => x.Location) .Where(x => x.ElectionRoundId == req.ElectionRoundId && x.Form.MonitoringNgo.NgoId == req.NgoId @@ -73,9 +74,16 @@ public override async Task, NotFound>> ExecuteAsync(Request Notes = citizenReport.Notes.Select(NoteModel.FromEntity).ToArray(), Attachments = attachments, Questions = form.Questions.Select(QuestionsMapper.ToModel).ToArray(), - + TimeSubmitted = citizenReport.LastModifiedOn ?? citizenReport.CreatedOn, FollowUpStatus = citizenReport.FollowUpStatus, + + LocationId = citizenReport.Location.Level1, + LocationLevel1 = citizenReport.Location.Level1, + LocationLevel2 = citizenReport.Location.Level2, + LocationLevel3 = citizenReport.Location.Level3, + LocationLevel4 = citizenReport.Location.Level4, + LocationLevel5 = citizenReport.Location.Level5, }; return TypedResults.Ok(response); diff --git a/api/src/Feature.CitizenReports/GetById/Request.cs b/api/src/Feature.CitizenReports/GetById/Request.cs index a5963a6a3..2d32271fc 100644 --- a/api/src/Feature.CitizenReports/GetById/Request.cs +++ b/api/src/Feature.CitizenReports/GetById/Request.cs @@ -8,5 +8,6 @@ public class Request [FromClaim(ApplicationClaimTypes.NgoId)] public Guid NgoId { get; set; } + public Guid CitizenReportId { get; set; } -} +} \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/GetById/Response.cs b/api/src/Feature.CitizenReports/GetById/Response.cs index 51b81c61c..3a2669bf3 100644 --- a/api/src/Feature.CitizenReports/GetById/Response.cs +++ b/api/src/Feature.CitizenReports/GetById/Response.cs @@ -9,16 +9,23 @@ namespace Feature.CitizenReports.GetById; public class Response { - public Guid CitizenReportId { get; set; } - public DateTime TimeSubmitted { get; set; } - public Guid FormId { get; set; } - public string FormCode { get; set; } - public TranslatedString FormName { get; set; } - public string FormDefaultLanguage { get; set; } + public Guid CitizenReportId { get; init; } + public DateTime TimeSubmitted { get; init; } + public Guid FormId { get; init; } + public string FormCode { get; init; } + public TranslatedString FormName { get; init; } + public string FormDefaultLanguage { get; init; } [JsonConverter(typeof(SmartEnumNameConverter))] public CitizenReportFollowUpStatus FollowUpStatus { get; init; } + public string LocationId { get; init; } + public string LocationLevel1 { get; init; } + public string LocationLevel2 { get; init; } + public string LocationLevel3 { get; init; } + public string LocationLevel4 { get; init; } + public string LocationLevel5 { get; init; } + public BaseQuestionModel[] Questions { get; init; } = []; public BaseAnswerModel[] Answers { get; init; } = []; public NoteModel[] Notes { get; init; } = []; diff --git a/api/src/Feature.CitizenReports/GetSubmissionsAggregated/Endpoint.cs b/api/src/Feature.CitizenReports/GetSubmissionsAggregated/Endpoint.cs index 002ac4a3b..f6d5c9623 100644 --- a/api/src/Feature.CitizenReports/GetSubmissionsAggregated/Endpoint.cs +++ b/api/src/Feature.CitizenReports/GetSubmissionsAggregated/Endpoint.cs @@ -33,21 +33,33 @@ public override async Task, NotFound>> ExecuteAsync(Request return TypedResults.NotFound(); } - return await AggregateNgoFormSubmissionsAsync(form, req.ElectionRoundId, req.NgoId, req.FormId, ct); + return await AggregateNgoFormSubmissionsAsync(form, req, ct); } private async Task, NotFound>> AggregateNgoFormSubmissionsAsync(FormAggregate form, - Guid electionRoundId, - Guid ngoId, - Guid formId, + Request req, CancellationToken ct) { var citizenReports = await context.CitizenReports .Include(x => x.Notes) .Include(x => x.Attachments) - .Where(x => x.ElectionRoundId == electionRoundId - && x.Form.MonitoringNgo.NgoId == ngoId - && x.FormId == formId) + .Where(x => x.ElectionRoundId == req.ElectionRoundId + && x.Form.MonitoringNgo.NgoId == req.NgoId + && x.FormId == req.FormId) + .Where(x => string.IsNullOrWhiteSpace(req.Level1Filter) || + EF.Functions.ILike(x.Location.Level1, req.Level1Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.Level2Filter) || + EF.Functions.ILike(x.Location.Level2, req.Level2Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.Level3Filter) || + EF.Functions.ILike(x.Location.Level3, req.Level3Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.Level4Filter) || + EF.Functions.ILike(x.Location.Level4, req.Level4Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.Level5Filter) || + EF.Functions.ILike(x.Location.Level5, req.Level5Filter)) + .Where(x => req.HasFlaggedAnswers == null || req.HasFlaggedAnswers.Value + ? x.NumberOfFlaggedAnswers > 0 + : x.NumberOfFlaggedAnswers == 0) + .Where(x => req.FollowUpStatus == null || x.FollowUpStatus == req.FollowUpStatus) .AsNoTracking() .ToListAsync(ct); @@ -74,7 +86,7 @@ private async Task, NotFound>> AggregateNgoFormSubmissionsA return attachment; }); - var attachments= await Task.WhenAll(tasks); + var attachments = await Task.WhenAll(tasks); return TypedResults.Ok(new Response { diff --git a/api/src/Feature.CitizenReports/GetSubmissionsAggregated/Request.cs b/api/src/Feature.CitizenReports/GetSubmissionsAggregated/Request.cs index c4cdc2c6c..5d84baf2c 100644 --- a/api/src/Feature.CitizenReports/GetSubmissionsAggregated/Request.cs +++ b/api/src/Feature.CitizenReports/GetSubmissionsAggregated/Request.cs @@ -1,4 +1,5 @@ using Vote.Monitor.Core.Security; +using Vote.Monitor.Domain.Entities.CitizenReportAggregate; namespace Feature.CitizenReports.GetSubmissionsAggregated; @@ -10,4 +11,18 @@ public class Request public Guid NgoId { get; set; } public Guid FormId { get; set; } -} + + [QueryParam] public string? Level1Filter { get; set; } + + [QueryParam] public string? Level2Filter { get; set; } + + [QueryParam] public string? Level3Filter { get; set; } + + [QueryParam] public string? Level4Filter { get; set; } + + [QueryParam] public string? Level5Filter { get; set; } + + [QueryParam] public bool? HasFlaggedAnswers { get; set; } + + [QueryParam] public CitizenReportFollowUpStatus? FollowUpStatus { get; set; } +} \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/GetSubmissionsAggregated/Validator.cs b/api/src/Feature.CitizenReports/GetSubmissionsAggregated/Validator.cs index 8eb87116c..c50435c1f 100644 --- a/api/src/Feature.CitizenReports/GetSubmissionsAggregated/Validator.cs +++ b/api/src/Feature.CitizenReports/GetSubmissionsAggregated/Validator.cs @@ -8,4 +8,4 @@ public Validator() RuleFor(x => x.NgoId).NotEmpty(); RuleFor(x => x.FormId).NotEmpty(); } -} +} \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/GlobalUsings.cs b/api/src/Feature.CitizenReports/GlobalUsings.cs index faa358637..30b70ebfa 100644 --- a/api/src/Feature.CitizenReports/GlobalUsings.cs +++ b/api/src/Feature.CitizenReports/GlobalUsings.cs @@ -11,4 +11,4 @@ global using Vote.Monitor.Core.Models; global using Vote.Monitor.Domain.Repository; global using CitizenReportAggregate = Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport; -global using FormAggregate = Vote.Monitor.Domain.Entities.FormAggregate.Form; +global using FormAggregate = Vote.Monitor.Domain.Entities.FormAggregate.Form; \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/ListEntries/Endpoint.cs b/api/src/Feature.CitizenReports/ListEntries/Endpoint.cs index cb2a3e244..906d13f91 100644 --- a/api/src/Feature.CitizenReports/ListEntries/Endpoint.cs +++ b/api/src/Feature.CitizenReports/ListEntries/Endpoint.cs @@ -26,13 +26,20 @@ public override async Task> ExecuteAsync( "CitizenReports" CR INNER JOIN "ElectionRounds" ER ON ER."Id" = CR."ElectionRoundId" INNER JOIN "MonitoringNgos" MN ON MN."Id" = ER."MonitoringNgoForCitizenReportingId" + INNER JOIN "Locations" L on L."Id" = CR."LocationId" WHERE MN."ElectionRoundId" = @electionRoundId AND MN."NgoId" = @ngoId AND ( @followUpStatus IS NULL OR CR."FollowUpStatus" = @followUpStatus - ); + ) + AND (@level1 IS NULL OR L."Level1" = @level1) + AND (@level2 IS NULL OR L."Level2" = @level2) + AND (@level3 IS NULL OR L."Level3" = @level3) + AND (@level4 IS NULL OR L."Level4" = @level4) + AND (@level5 IS NULL OR L."Level5" = @level5) + ; WITH CITIZENREPORTS AS ( @@ -62,12 +69,18 @@ CITIZENREPORTS AS ( AND CRA."IsCompleted" = TRUE AND CRA."IsDeleted" = FALSE ) AS "MediaFilesCount", - CR."FollowUpStatus" + CR."FollowUpStatus", + L."Level1", + L."Level2", + L."Level3", + L."Level4", + L."Level5" FROM "CitizenReports" CR INNER JOIN "Forms" F ON F."Id" = CR."FormId" INNER JOIN "ElectionRounds" ER ON ER."Id" = CR."ElectionRoundId" INNER JOIN "MonitoringNgos" MN ON MN."Id" = ER."MonitoringNgoForCitizenReportingId" + INNER JOIN "Locations" L on L."Id" = CR."LocationId" WHERE CR."ElectionRoundId" = @electionRoundId AND MN."NgoId" = @ngoId @@ -86,6 +99,12 @@ @hasFlaggedAnswers IS NULL @followUpStatus IS NULL OR "FollowUpStatus" = @followUpStatus ) + AND (@level1 IS NULL OR L."Level1" = @level1) + AND (@level2 IS NULL OR L."Level2" = @level2) + AND (@level3 IS NULL OR L."Level3" = @level3) + AND (@level4 IS NULL OR L."Level4" = @level4) + AND (@level5 IS NULL OR L."Level5" = @level5) + AND (@hasFlaggedAnswers is NULL OR @hasFlaggedAnswers = false OR 1 = 2) ) SELECT "CitizenReportId", @@ -97,7 +116,12 @@ @followUpStatus IS NULL "NumberOfFlaggedAnswers", "NotesCount", "MediaFilesCount", - "FollowUpStatus" + "FollowUpStatus", + "Level1", + "Level2", + "Level3", + "Level4", + "Level5" FROM CITIZENREPORTS ORDER BY @@ -136,7 +160,21 @@ ORDER BY END ASC, CASE WHEN @sortExpression = 'NotesCount DESC' THEN "NotesCount" - END DESC + END DESC, + CASE WHEN @sortExpression = 'Level1 ASC' THEN "Level1" END ASC, + CASE WHEN @sortExpression = 'Level1 DESC' THEN "Level1" END DESC, + + CASE WHEN @sortExpression = 'Level2 ASC' THEN "Level2" END ASC, + CASE WHEN @sortExpression = 'Level2 DESC' THEN "Level2" END DESC, + + CASE WHEN @sortExpression = 'Level3 ASC' THEN "Level3" END ASC, + CASE WHEN @sortExpression = 'Level3 DESC' THEN "Level3" END DESC, + + CASE WHEN @sortExpression = 'Level4 ASC' THEN "Level4" END ASC, + CASE WHEN @sortExpression = 'Level4 DESC' THEN "Level4" END DESC, + + CASE WHEN @sortExpression = 'Level5 ASC' THEN "Level5" END ASC, + CASE WHEN @sortExpression = 'Level5 DESC' THEN "Level5" END DESC OFFSET @offset ROWS @@ -153,7 +191,12 @@ FETCH NEXT searchText = $"%{req.SearchText?.Trim() ?? string.Empty}%", hasFlaggedAnswers = req.HasFlaggedAnswers, followUpStatus = req.FollowUpStatus?.ToString(), - sortExpression = GetSortExpression(req.SortColumnName, req.IsAscendingSorting) + level1 = req.Level1Filter, + level2 = req.Level2Filter, + level3 = req.Level3Filter, + level4 = req.Level4Filter, + level5 = req.Level5Filter, + sortExpression = GetSortExpression(req.SortColumnName, req.IsAscendingSorting), }; int totalRowCount; @@ -214,6 +257,36 @@ private static string GetSortExpression(string? sortColumnName, bool isAscending return $"{nameof(CitizenReportEntryModel.TimeSubmitted)} {sortOrder}"; } + if (string.Equals(sortColumnName, nameof(CitizenReportEntryModel.Level1), + StringComparison.InvariantCultureIgnoreCase)) + { + return $"{nameof(CitizenReportEntryModel.Level1)} {sortOrder}"; + } + + if (string.Equals(sortColumnName, nameof(CitizenReportEntryModel.Level2), + StringComparison.InvariantCultureIgnoreCase)) + { + return $"{nameof(CitizenReportEntryModel.Level2)} {sortOrder}"; + } + + if (string.Equals(sortColumnName, nameof(CitizenReportEntryModel.Level3), + StringComparison.InvariantCultureIgnoreCase)) + { + return $"{nameof(CitizenReportEntryModel.Level3)} {sortOrder}"; + } + + if (string.Equals(sortColumnName, nameof(CitizenReportEntryModel.Level4), + StringComparison.InvariantCultureIgnoreCase)) + { + return $"{nameof(CitizenReportEntryModel.Level4)} {sortOrder}"; + } + + if (string.Equals(sortColumnName, nameof(CitizenReportEntryModel.Level5), + StringComparison.InvariantCultureIgnoreCase)) + { + return $"{nameof(CitizenReportEntryModel.Level5)} {sortOrder}"; + } + return $"{nameof(CitizenReportEntryModel.TimeSubmitted)} DESC"; } } \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/ListEntries/Request.cs b/api/src/Feature.CitizenReports/ListEntries/Request.cs index 440d8218b..e689ec20d 100644 --- a/api/src/Feature.CitizenReports/ListEntries/Request.cs +++ b/api/src/Feature.CitizenReports/ListEntries/Request.cs @@ -12,7 +12,19 @@ public class Request : BaseSortPaginatedRequest [QueryParam] public string? SearchText { get; set; } + [QueryParam] public string? Level1Filter { get; set; } + + [QueryParam] public string? Level2Filter { get; set; } + + [QueryParam] public string? Level3Filter { get; set; } + + [QueryParam] public string? Level4Filter { get; set; } + + [QueryParam] public string? Level5Filter { get; set; } + + [QueryParam] public bool? HasFlaggedAnswers { get; set; } + [QueryParam] public CitizenReportFollowUpStatus? FollowUpStatus { get; set; } } \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/ListFormsOverview/Request.cs b/api/src/Feature.CitizenReports/ListFormsOverview/Request.cs index 289da86e5..d13ea6558 100644 --- a/api/src/Feature.CitizenReports/ListFormsOverview/Request.cs +++ b/api/src/Feature.CitizenReports/ListFormsOverview/Request.cs @@ -8,4 +8,4 @@ public class Request [FromClaim(ApplicationClaimTypes.NgoId)] public Guid NgoId { get; set; } -} +} \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/ListFormsOverview/Validator.cs b/api/src/Feature.CitizenReports/ListFormsOverview/Validator.cs index d80467a05..78eb6352c 100644 --- a/api/src/Feature.CitizenReports/ListFormsOverview/Validator.cs +++ b/api/src/Feature.CitizenReports/ListFormsOverview/Validator.cs @@ -7,4 +7,4 @@ public Validator() RuleFor(x => x.ElectionRoundId).NotEmpty(); RuleFor(x => x.NgoId).NotEmpty(); } -} +} \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/Models/CitizenReportEntryModel.cs b/api/src/Feature.CitizenReports/Models/CitizenReportEntryModel.cs index 518fbed30..5322d6427 100644 --- a/api/src/Feature.CitizenReports/Models/CitizenReportEntryModel.cs +++ b/api/src/Feature.CitizenReports/Models/CitizenReportEntryModel.cs @@ -9,15 +9,21 @@ public record CitizenReportEntryModel public Guid CitizenReportId { get; set; } public DateTime TimeSubmitted { get; set; } public string FormCode { get; set; } - + public TranslatedString FormName { get; set; } - + public string FormDefaultLanguage { get; set; } public int NumberOfQuestionsAnswered { get; set; } public int NumberOfFlaggedAnswers { get; set; } public int NotesCount { get; set; } public int MediaFilesCount { get; set; } + public string Level1 { get; set; } + public string Level2 { get; set; } + public string Level3 { get; set; } + public string Level4 { get; set; } + public string Level5 { get; set; } + [JsonConverter(typeof(SmartEnumNameConverter))] public CitizenReportFollowUpStatus FollowUpStatus { get; init; } } \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/Models/CitizenReportModel.cs b/api/src/Feature.CitizenReports/Models/CitizenReportModel.cs index 302d33908..4eaa0e342 100644 --- a/api/src/Feature.CitizenReports/Models/CitizenReportModel.cs +++ b/api/src/Feature.CitizenReports/Models/CitizenReportModel.cs @@ -13,6 +13,7 @@ public class CitizenReportModel [JsonConverter(typeof(SmartEnumNameConverter))] public CitizenReportFollowUpStatus FollowUpStatus { get; init; } + public IReadOnlyList Answers { get; init; } public static CitizenReportModel FromEntity(CitizenReportAggregate entity) => new() @@ -23,8 +24,5 @@ public class CitizenReportModel .Select(AnswerMapper.ToModel) .ToList(), FollowUpStatus = entity.FollowUpStatus, - }; - - } \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/Specifications/GetFormSpecification.cs b/api/src/Feature.CitizenReports/Specifications/GetFormSpecification.cs index e9ea134ce..5d6d5adb3 100644 --- a/api/src/Feature.CitizenReports/Specifications/GetFormSpecification.cs +++ b/api/src/Feature.CitizenReports/Specifications/GetFormSpecification.cs @@ -7,4 +7,4 @@ public GetFormSpecification(Guid electionRondId, Guid formId) Query.Where(x => x.ElectionRoundId == electionRondId && x.Id == formId); Query.Include(x => x.ElectionRound); } -} +} \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/Specifications/GetLocationSpecification.cs b/api/src/Feature.CitizenReports/Specifications/GetLocationSpecification.cs new file mode 100644 index 000000000..c83c6fbde --- /dev/null +++ b/api/src/Feature.CitizenReports/Specifications/GetLocationSpecification.cs @@ -0,0 +1,11 @@ +using Vote.Monitor.Domain.Entities.LocationAggregate; + +namespace Feature.CitizenReports.Specifications; + +public sealed class GetLocationSpecification : SingleResultSpecification +{ + public GetLocationSpecification(Guid electionRoundId, Guid locationId) + { + Query.Where(x => x.Id == locationId && x.ElectionRoundId == electionRoundId); + } +} \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/UpdateStatus/Endpoint.cs b/api/src/Feature.CitizenReports/UpdateStatus/Endpoint.cs index 2d724d78a..58cbc9acb 100644 --- a/api/src/Feature.CitizenReports/UpdateStatus/Endpoint.cs +++ b/api/src/Feature.CitizenReports/UpdateStatus/Endpoint.cs @@ -10,10 +10,7 @@ public override void Configure() Put("/api/election-rounds/{electionRoundId}/citizen-reports/{id}:status"); DontAutoTag(); Options(x => x.WithTags("citizen-reports")); - Summary(s => - { - s.Summary = "Updates follow up status for a citizen report"; - }); + Summary(s => { s.Summary = "Updates follow up status for a citizen report"; }); Policies(PolicyNames.NgoAdminsOnly); } @@ -25,7 +22,7 @@ await context.CitizenReports && x.ElectionRoundId == req.ElectionRoundId && x.Id == req.Id) .ExecuteUpdateAsync(x => x.SetProperty(p => p.FollowUpStatus, req.FollowUpStatus), cancellationToken: ct); - + return TypedResults.NoContent(); } -} +} \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/UpdateStatus/Request.cs b/api/src/Feature.CitizenReports/UpdateStatus/Request.cs index 7df7493e7..91d481283 100644 --- a/api/src/Feature.CitizenReports/UpdateStatus/Request.cs +++ b/api/src/Feature.CitizenReports/UpdateStatus/Request.cs @@ -9,6 +9,7 @@ public class Request [FromClaim(ApplicationClaimTypes.NgoId)] public Guid NgoId { get; set; } + public Guid Id { get; set; } public CitizenReportFollowUpStatus FollowUpStatus { get; set; } -} +} \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/UpdateStatus/Validator.cs b/api/src/Feature.CitizenReports/UpdateStatus/Validator.cs index bcba41e23..472f3ddf1 100644 --- a/api/src/Feature.CitizenReports/UpdateStatus/Validator.cs +++ b/api/src/Feature.CitizenReports/UpdateStatus/Validator.cs @@ -8,4 +8,4 @@ public Validator() RuleFor(x => x.NgoId).NotEmpty(); RuleFor(x => x.Id).NotEmpty(); } -} +} \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/Upsert/Endpoint.cs b/api/src/Feature.CitizenReports/Upsert/Endpoint.cs index 90f883b5f..923e3495b 100644 --- a/api/src/Feature.CitizenReports/Upsert/Endpoint.cs +++ b/api/src/Feature.CitizenReports/Upsert/Endpoint.cs @@ -3,11 +3,13 @@ using Vote.Monitor.Answer.Module.Mappers; using Vote.Monitor.Domain.Entities.FormAnswerBase; using Vote.Monitor.Domain.Entities.FormAnswerBase.Answers; +using Vote.Monitor.Domain.Entities.LocationAggregate; namespace Feature.CitizenReports.Upsert; public class Endpoint( IRepository repository, + IReadRepository locationRepository, IReadRepository formRepository) : Endpoint, NotFound>> { public override void Configure() @@ -16,12 +18,19 @@ public override void Configure() DontAutoTag(); AllowAnonymous(); Options(x => x.WithTags("citizen-report", "public")); - Summary(s => { s.Summary = "Upserts citizen report for a given form"; }); + Summary(s => { s.Summary = "Upserts citizen report for a given form at a given location"; }); } public override async Task, NotFound>> ExecuteAsync(Request req, CancellationToken ct) { + var locationSpecification = new GetLocationSpecification(req.ElectionRoundId, req.LocationId); + var location = await locationRepository.FirstOrDefaultAsync(locationSpecification, ct); + if (location is null) + { + return TypedResults.NotFound(); + } + var formSpecification = new GetFormSpecification(req.ElectionRoundId, req.FormId); var form = await formRepository.FirstOrDefaultAsync(formSpecification, ct); if (form is null) @@ -42,7 +51,7 @@ public override async Task, NotFound>> ExecuteAsy } return citizenReport is null - ? await AddFormSubmissionAsync(req, form, answers, ct) + ? await AddFormSubmissionAsync(req, form, location, answers, ct) : await UpdateFormSubmissionAsync(form, citizenReport, answers, ct); } @@ -60,10 +69,11 @@ private async Task, NotFound>> UpdateFormSubmissi private async Task, NotFound>> AddFormSubmissionAsync(Request req, FormAggregate form, + Location location, List? answers, CancellationToken ct) { - var submission = form.CreateCitizenReport(req.CitizenReportId, answers); + var submission = form.CreateCitizenReport(req.CitizenReportId, location, answers); await repository.AddAsync(submission, ct); return TypedResults.Ok(CitizenReportModel.FromEntity(submission)); diff --git a/api/src/Feature.CitizenReports/Upsert/Request.cs b/api/src/Feature.CitizenReports/Upsert/Request.cs index fb1e71abb..b3e77e162 100644 --- a/api/src/Feature.CitizenReports/Upsert/Request.cs +++ b/api/src/Feature.CitizenReports/Upsert/Request.cs @@ -7,5 +7,6 @@ public class Request public Guid ElectionRoundId { get; set; } public Guid CitizenReportId { get; set; } public Guid FormId { get; set; } + public Guid LocationId { get; set; } public List? Answers { get; set; } -} +} \ No newline at end of file diff --git a/api/src/Feature.CitizenReports/Upsert/Validator.cs b/api/src/Feature.CitizenReports/Upsert/Validator.cs index b82bfac55..6c54335c5 100644 --- a/api/src/Feature.CitizenReports/Upsert/Validator.cs +++ b/api/src/Feature.CitizenReports/Upsert/Validator.cs @@ -9,6 +9,7 @@ public Validator() RuleFor(x => x.ElectionRoundId).NotEmpty(); RuleFor(x => x.CitizenReportId).NotEmpty(); RuleFor(x => x.FormId).NotEmpty(); + RuleFor(x => x.LocationId).NotEmpty(); RuleForEach(x => x.Answers) .SetInheritanceValidator(v => diff --git a/api/src/Feature.DataExport/Start/Endpoint.cs b/api/src/Feature.DataExport/Start/Endpoint.cs index a4f612149..6950c2773 100644 --- a/api/src/Feature.DataExport/Start/Endpoint.cs +++ b/api/src/Feature.DataExport/Start/Endpoint.cs @@ -6,7 +6,8 @@ namespace Feature.DataExport.Start; -public class Endpoint(IJobService jobService, +public class Endpoint( + IJobService jobService, IAuthorizationService authorizationService, IRepository repository, ITimeProvider timeProvider) : Endpoint, NotFound>> @@ -18,16 +19,14 @@ public override void Configure() DontAutoTag(); Options(x => x.WithTags("exported-data")); - Summary(s => - { - s.Summary = "Enqueues a job to export data and returns job id to poll for results"; - }); + Summary(s => { s.Summary = "Enqueues a job to export data and returns job id to poll for results"; }); Policies(PolicyNames.NgoAdminsOnly); } public override async Task, NotFound>> ExecuteAsync(Request req, CancellationToken ct) { - var result = await authorizationService.AuthorizeAsync(User, new MonitoringNgoAdminRequirement(req.ElectionRoundId)); + var result = + await authorizationService.AuthorizeAsync(User, new MonitoringNgoAdminRequirement(req.ElectionRoundId)); if (!result.Succeeded) { return TypedResults.NotFound(); @@ -39,17 +38,27 @@ public override async Task, NotFound>> ExecuteAsync(Reque if (req.ExportedDataType == ExportedDataType.FormSubmissions) { - jobService.ExportFormSubmissions(req.ElectionRoundId, req.NgoId, exportedData.Id); + jobService.EnqueueExportFormSubmissions(req.ElectionRoundId, req.NgoId, exportedData.Id); } if (req.ExportedDataType == ExportedDataType.QuickReports) { - jobService.ExportQuickReportsSubmissions(req.ElectionRoundId, req.NgoId, exportedData.Id); + jobService.EnqueueExportQuickReportsSubmissions(req.ElectionRoundId, req.NgoId, exportedData.Id); } if (req.ExportedDataType == ExportedDataType.PollingStations) { - jobService.ExportPollingStations(req.ElectionRoundId, exportedData.Id); + jobService.EnqueueExportPollingStations(req.ElectionRoundId, exportedData.Id); + } + + if (req.ExportedDataType == ExportedDataType.CitizenReports) + { + jobService.EnqueueExportCitizenReports(req.ElectionRoundId, req.NgoId, exportedData.Id); + } + + if (req.ExportedDataType == ExportedDataType.Locations) + { + jobService.EnqueueExportLocations(req.ElectionRoundId, exportedData.Id); } return TypedResults.Ok(new JobDetails @@ -58,4 +67,4 @@ public override async Task, NotFound>> ExecuteAsync(Reque EnqueuedAt = timeProvider.UtcNow }); } -} +} \ No newline at end of file diff --git a/api/src/Feature.Form.Submissions/GetAggregated/Endpoint.cs b/api/src/Feature.Form.Submissions/GetAggregated/Endpoint.cs index ae943966b..a6d8c2c94 100644 --- a/api/src/Feature.Form.Submissions/GetAggregated/Endpoint.cs +++ b/api/src/Feature.Form.Submissions/GetAggregated/Endpoint.cs @@ -10,7 +10,8 @@ namespace Feature.Form.Submissions.GetAggregated; -public class Endpoint(VoteMonitorContext context, +public class Endpoint( + VoteMonitorContext context, INpgsqlConnectionFactory connectionFactory, IFileStorageService fileStorageService) : Endpoint, NotFound>> { @@ -20,10 +21,7 @@ public override void Configure() DontAutoTag(); Options(x => x.WithTags("form-submissions", "mobile")); Policies(PolicyNames.NgoAdminsOnly); - Summary(s => - { - s.Summary = "Gets aggregated form with all the notes and attachments"; - }); + Summary(s => { s.Summary = "Gets aggregated form with all the notes and attachments"; }); } public override async Task, NotFound>> ExecuteAsync(Request req, CancellationToken ct) @@ -38,7 +36,7 @@ public override async Task, NotFound>> ExecuteAsync(Request if (form is not null) { - return await AggregateNgoFormSubmissionsAsync(form, req.ElectionRoundId, req.NgoId, req.FormId, ct); + return await AggregateNgoFormSubmissionsAsync(form, req, ct); } var psiForm = await context @@ -48,27 +46,45 @@ public override async Task, NotFound>> ExecuteAsync(Request if (psiForm is not null) { - return await AggregatePSIFormSubmissionsAsync(psiForm, req.ElectionRoundId, req.NgoId, req.FormId, ct); + return await AggregatePSIFormSubmissionsAsync(psiForm, req, ct); } return TypedResults.NotFound(); } - private async Task< Results, NotFound>> AggregateNgoFormSubmissionsAsync(FormAggregate form, - Guid electionRoundId, - Guid ngoId, - Guid formId, + private async Task, NotFound>> AggregateNgoFormSubmissionsAsync(FormAggregate form, + Request req, CancellationToken ct) { - var submissions = await context.FormSubmissions - .Include(x => x.MonitoringObserver) - .ThenInclude(x => x.Observer) - .ThenInclude(x => x.ApplicationUser) - .Where(x => x.ElectionRoundId == electionRoundId - && x.MonitoringObserver.MonitoringNgo.NgoId == ngoId - && x.FormId == formId) - .AsNoTracking() - .ToListAsync(ct); + var tags = req.TagsFilter ?? []; + var submissions = await context + .FormSubmissions + .Include(x => x.MonitoringObserver) + .ThenInclude(x => x.Observer) + .ThenInclude(x => x.ApplicationUser) + .Include(x => x.PollingStation) + .Where(x => x.ElectionRoundId == req.ElectionRoundId + && x.MonitoringObserver.MonitoringNgo.NgoId == req.NgoId + && x.FormId == req.FormId) + .Where(x => string.IsNullOrWhiteSpace(req.Level1Filter) || + EF.Functions.ILike(x.PollingStation.Level1, req.Level1Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.Level2Filter) || + EF.Functions.ILike(x.PollingStation.Level2, req.Level2Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.Level3Filter) || + EF.Functions.ILike(x.PollingStation.Level3, req.Level3Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.Level4Filter) || + EF.Functions.ILike(x.PollingStation.Level4, req.Level4Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.Level5Filter) || + EF.Functions.ILike(x.PollingStation.Level5, req.Level5Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.PollingStationNumberFilter) || + EF.Functions.ILike(x.PollingStation.Number, req.PollingStationNumberFilter)) + .Where(x => req.HasFlaggedAnswers == null || req.HasFlaggedAnswers.Value + ? x.NumberOfFlaggedAnswers > 0 + : x.NumberOfFlaggedAnswers == 0) + .Where(x => req.FollowUpStatus == null || x.FollowUpStatus == req.FollowUpStatus) + .Where(x => tags.Length == 0 || x.MonitoringObserver.Tags.Any(tag => tags.Contains(tag))) + .AsNoTracking() + .ToListAsync(ct); var formSubmissionsAggregate = new FormSubmissionsAggregate(form); foreach (var formSubmission in submissions) @@ -76,65 +92,74 @@ private async Task< Results, NotFound>> AggregateNgoFormSubmissions formSubmissionsAggregate.AggregateAnswers(formSubmission); } - var sql = """ - SELECT - N."Id", - N."MonitoringObserverId", - N."QuestionId", - N."Text", - COALESCE(N."LastModifiedOn", N."CreatedOn") "TimeSubmitted", - ( - SELECT - FS."Id" - FROM - "FormSubmissions" FS - WHERE - FS."MonitoringObserverId" = N."MonitoringObserverId" - AND FS."FormId" = N."FormId" - AND FS."PollingStationId" = N."PollingStationId" - AND FS."ElectionRoundId" = N."ElectionRoundId" - ) "SubmissionId" - FROM - "Notes" N - WHERE - N."ElectionRoundId" = @electionRoundId - AND N."FormId" = @formId; + var pollingStationIds = submissions.Select(x => x.PollingStationId).Distinct().ToArray(); + var monitoringObserverIds = submissions.Select(x => x.MonitoringObserverId).Distinct().ToArray(); - SELECT - A."MonitoringObserverId", - A."QuestionId", - A."FileName", - A."MimeType", - A."FilePath", - A."UploadedFileName", - COALESCE(A."LastModifiedOn", A."CreatedOn") "TimeSubmitted", - ( - SELECT - FS."Id" - FROM - "FormSubmissions" FS - WHERE - FS."MonitoringObserverId" = A."MonitoringObserverId" - AND FS."FormId" = A."FormId" - AND FS."PollingStationId" = A."PollingStationId" - AND FS."ElectionRoundId" = A."ElectionRoundId" - ) "SubmissionId" - FROM - "Attachments" A - WHERE - A."ElectionRoundId" = @electionRoundId - AND A."IsDeleted" = false AND A."IsCompleted" = true - AND A."FormId" = @formId; - """; + var sql = """ + SELECT + N."Id", + N."MonitoringObserverId", + N."QuestionId", + N."Text", + COALESCE(N."LastModifiedOn", N."CreatedOn") "TimeSubmitted", + ( + SELECT + FS."Id" + FROM + "FormSubmissions" FS + WHERE + FS."MonitoringObserverId" = N."MonitoringObserverId" + AND FS."FormId" = N."FormId" + AND FS."PollingStationId" = N."PollingStationId" + AND FS."ElectionRoundId" = N."ElectionRoundId" + ) "SubmissionId" + FROM + "Notes" N + WHERE + N."ElectionRoundId" = @electionRoundId + AND N."FormId" = @formId + AND N."MonitoringObserverId" = ANY (@monitoringObserverIds) + AND N."PollingStationId" = ANY (@pollingStationIds); + + SELECT + A."MonitoringObserverId", + A."QuestionId", + A."FileName", + A."MimeType", + A."FilePath", + A."UploadedFileName", + COALESCE(A."LastModifiedOn", A."CreatedOn") "TimeSubmitted", + ( + SELECT + FS."Id" + FROM + "FormSubmissions" FS + WHERE + FS."MonitoringObserverId" = A."MonitoringObserverId" + AND FS."FormId" = A."FormId" + AND FS."PollingStationId" = A."PollingStationId" + AND FS."ElectionRoundId" = A."ElectionRoundId" + ) "SubmissionId" + FROM + "Attachments" A + WHERE + A."ElectionRoundId" = @electionRoundId + AND A."IsDeleted" = false AND A."IsCompleted" = TRUE + AND A."FormId" = @formId + AND A."MonitoringObserverId" = ANY (@monitoringObserverIds) + AND A."PollingStationId" = ANY (@pollingStationIds); + """; var queryArgs = new { - electionRoundId = electionRoundId, - formId = formId + electionRoundId = req.ElectionRoundId, + formId = req.FormId, + monitoringObserverIds, + pollingStationIds }; - List notes = []; - List attachments = []; + List notes; + List attachments; using (var dbConnection = await connectionFactory.GetOpenConnectionAsync(ct)) { @@ -145,7 +170,8 @@ private async Task< Results, NotFound>> AggregateNgoFormSubmissions foreach (var attachment in attachments) { - var result = await fileStorageService.GetPresignedUrlAsync(attachment.FilePath, attachment.UploadedFileName); + var result = + await fileStorageService.GetPresignedUrlAsync(attachment.FilePath, attachment.UploadedFileName); if (result is GetPresignedUrlResult.Ok(var url, _, var urlValidityInSeconds)) { attachment.PresignedUrl = url; @@ -159,22 +185,40 @@ private async Task< Results, NotFound>> AggregateNgoFormSubmissions Notes = notes, Attachments = attachments }); - } - - private async Task< Results, NotFound>> AggregatePSIFormSubmissionsAsync(PollingStationInformationForm form, - Guid electionRoundId, - Guid ngoId, - Guid formId, + } + + private async Task, NotFound>> AggregatePSIFormSubmissionsAsync( + PollingStationInformationForm form, + Request req, CancellationToken ct) { + var tags = req.TagsFilter ?? []; + var submissions = await context.PollingStationInformation - .Include(x => x.MonitoringObserver) - .ThenInclude(x => x.Observer) - .ThenInclude(x => x.ApplicationUser) - .Where(x => x.ElectionRoundId == electionRoundId - && x.MonitoringObserver.MonitoringNgo.NgoId == ngoId) - .AsNoTracking() - .ToListAsync(ct); + .Include(x => x.MonitoringObserver) + .ThenInclude(x => x.Observer) + .ThenInclude(x => x.ApplicationUser) + .Where(x => x.ElectionRoundId == req.ElectionRoundId + && x.MonitoringObserver.MonitoringNgo.NgoId == req.NgoId) + .Where(x => string.IsNullOrWhiteSpace(req.Level1Filter) || + EF.Functions.ILike(x.PollingStation.Level1, req.Level1Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.Level2Filter) || + EF.Functions.ILike(x.PollingStation.Level2, req.Level2Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.Level3Filter) || + EF.Functions.ILike(x.PollingStation.Level3, req.Level3Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.Level4Filter) || + EF.Functions.ILike(x.PollingStation.Level4, req.Level4Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.Level5Filter) || + EF.Functions.ILike(x.PollingStation.Level5, req.Level5Filter)) + .Where(x => string.IsNullOrWhiteSpace(req.PollingStationNumberFilter) || + EF.Functions.ILike(x.PollingStation.Number, req.PollingStationNumberFilter)) + .Where(x => req.HasFlaggedAnswers == null || req.HasFlaggedAnswers.Value + ? x.NumberOfFlaggedAnswers > 0 + : x.NumberOfFlaggedAnswers == 0) + .Where(x => req.FollowUpStatus == null || x.FollowUpStatus == req.FollowUpStatus) + .Where(x => tags.Length == 0 || x.MonitoringObserver.Tags.Any(tag => tags.Contains(tag))) + .AsNoTracking() + .ToListAsync(ct); var formSubmissionsAggregate = new FormSubmissionsAggregate(form); foreach (var formSubmission in submissions) @@ -182,88 +226,11 @@ private async Task< Results, NotFound>> AggregatePSIFormSubmissions formSubmissionsAggregate.AggregateAnswers(formSubmission); } - var sql = """ - SELECT - N."Id", - N."MonitoringObserverId", - N."QuestionId", - N."Text", - COALESCE(N."LastModifiedOn", N."CreatedOn") "TimeSubmitted", - ( - SELECT - FS."Id" - FROM - "FormSubmissions" FS - WHERE - FS."MonitoringObserverId" = N."MonitoringObserverId" - AND FS."FormId" = N."FormId" - AND FS."PollingStationId" = N."PollingStationId" - AND FS."ElectionRoundId" = N."ElectionRoundId" - ) "SubmissionId" - FROM - "Notes" N - WHERE - N."ElectionRoundId" = @electionRoundId - AND N."FormId" = @formId; - - SELECT - A."MonitoringObserverId", - A."QuestionId", - A."FileName", - A."MimeType", - A."FilePath", - A."UploadedFileName", - COALESCE(A."LastModifiedOn", A."CreatedOn") "TimeSubmitted", - ( - SELECT - FS."Id" - FROM - "FormSubmissions" FS - WHERE - FS."MonitoringObserverId" = A."MonitoringObserverId" - AND FS."FormId" = A."FormId" - AND FS."PollingStationId" = A."PollingStationId" - AND FS."ElectionRoundId" = A."ElectionRoundId" - ) "SubmissionId" - FROM - "Attachments" A - WHERE - A."ElectionRoundId" = @electionRoundId - AND A."IsDeleted" = false AND A."IsCompleted" = true - AND A."FormId" = @formId; - """; - - var queryArgs = new - { - electionRoundId = electionRoundId, - formId = formId - }; - - List notes = []; - List attachments = []; - - using (var dbConnection = await connectionFactory.GetOpenConnectionAsync(ct)) - { - using var multi = await dbConnection.QueryMultipleAsync(sql, queryArgs); - notes = multi.Read().ToList(); - attachments = multi.Read().ToList(); - } - - foreach (var attachment in attachments) - { - var result = await fileStorageService.GetPresignedUrlAsync(attachment.FilePath, attachment.UploadedFileName); - if (result is GetPresignedUrlResult.Ok(var url, _, var urlValidityInSeconds)) - { - attachment.PresignedUrl = url; - attachment.UrlValidityInSeconds = urlValidityInSeconds; - } - } - return TypedResults.Ok(new Response { SubmissionsAggregate = formSubmissionsAggregate, - Notes = notes, - Attachments = attachments + Notes = [], + Attachments = [] }); } -} +} \ No newline at end of file diff --git a/api/src/Feature.Form.Submissions/GetAggregated/Request.cs b/api/src/Feature.Form.Submissions/GetAggregated/Request.cs index f36474870..027fa794f 100644 --- a/api/src/Feature.Form.Submissions/GetAggregated/Request.cs +++ b/api/src/Feature.Form.Submissions/GetAggregated/Request.cs @@ -10,4 +10,22 @@ public class Request public Guid NgoId { get; set; } public Guid FormId { get; set; } -} + + [QueryParam] public string? Level1Filter { get; set; } + + [QueryParam] public string? Level2Filter { get; set; } + + [QueryParam] public string? Level3Filter { get; set; } + + [QueryParam] public string? Level4Filter { get; set; } + + [QueryParam] public string? Level5Filter { get; set; } + + [QueryParam] public string? PollingStationNumberFilter { get; set; } + + [QueryParam] public bool? HasFlaggedAnswers { get; set; } + + [QueryParam] public SubmissionFollowUpStatus? FollowUpStatus { get; set; } + + [QueryParam] public string[]? TagsFilter { get; set; } = []; +} \ No newline at end of file diff --git a/api/src/Feature.Form.Submissions/ListByForm/Endpoint.cs b/api/src/Feature.Form.Submissions/ListByForm/Endpoint.cs index 107b2e2fa..6054a72e4 100644 --- a/api/src/Feature.Form.Submissions/ListByForm/Endpoint.cs +++ b/api/src/Feature.Form.Submissions/ListByForm/Endpoint.cs @@ -27,14 +27,27 @@ public override async Task ExecuteAsync(Request req, CancellationToken 'PSI' AS "FormCode", 'PSI' AS "FormType", COUNT(DISTINCT PSI."Id") "NumberOfSubmissions", - 0 "NumberOfFlaggedAnswers", + SUM(PSI."NumberOfFlaggedAnswers") "NumberOfFlaggedAnswers", 0 AS "NumberOfMediaFiles", 0 AS "NumberOfNotes" FROM "PollingStationInformationForms" F INNER JOIN "PollingStationInformation" PSI ON PSI."ElectionRoundId" = F."ElectionRoundId" + INNER JOIN "PollingStations" PS ON PSI."PollingStationId" = PS."Id" + INNER JOIN "MonitoringObservers" mo ON mo."Id" = PSI."MonitoringObserverId" + WHERE F."ElectionRoundId" = @electionRoundId + AND (@level1 IS NULL OR ps."Level1" = @level1) + AND (@level2 IS NULL OR ps."Level2" = @level2) + AND (@level3 IS NULL OR ps."Level3" = @level3) + AND (@level4 IS NULL OR ps."Level4" = @level4) + AND (@level5 IS NULL OR ps."Level5" = @level5) + AND (@pollingStationNumber IS NULL OR ps."Number" = @pollingStationNumber) + AND (@hasFlaggedAnswers is NULL OR ("NumberOfFlaggedAnswers" = 0 AND @hasFlaggedAnswers = false) OR ("NumberOfFlaggedAnswers" > 0 AND @hasFlaggedAnswers = true)) + AND (@followUpStatus is NULL OR "FollowUpStatus" = @followUpStatus) + AND (@tagsFilter IS NULL OR cardinality(@tagsFilter) = 0 OR mo."Tags" && @tagsFilter) + GROUP BY F."Id" UNION ALL @@ -65,9 +78,22 @@ UNION ALL "Forms" F INNER JOIN "MonitoringNgos" MN ON MN."Id" = F."MonitoringNgoId" INNER JOIN "FormSubmissions" FS ON FS."FormId" = F."Id" + INNER JOIN "PollingStations" ps ON ps."Id" = FS."PollingStationId" + INNER JOIN "MonitoringObservers" mo ON mo."Id" = FS."MonitoringObserverId" + WHERE F."ElectionRoundId" = @electionRoundId AND MN."NgoId" = @ngoId + AND (@level1 IS NULL OR ps."Level1" = @level1) + AND (@level2 IS NULL OR ps."Level2" = @level2) + AND (@level3 IS NULL OR ps."Level3" = @level3) + AND (@level4 IS NULL OR ps."Level4" = @level4) + AND (@level5 IS NULL OR ps."Level5" = @level5) + AND (@pollingStationNumber IS NULL OR ps."Number" = @pollingStationNumber) + AND (@hasFlaggedAnswers is NULL OR ("NumberOfFlaggedAnswers" = 0 AND @hasFlaggedAnswers = false) OR ("NumberOfFlaggedAnswers" > 0 AND @hasFlaggedAnswers = true)) + AND (@followUpStatus is NULL OR "FollowUpStatus" = @followUpStatus) + AND (@tagsFilter IS NULL OR cardinality(@tagsFilter) = 0 OR mo."Tags" && @tagsFilter) + GROUP BY F."Id", F."Code", @@ -77,7 +103,16 @@ GROUP BY var queryArgs = new { electionRoundId = req.ElectionRoundId, - ngoId = req.NgoId + ngoId = req.NgoId, + level1 = req.Level1Filter, + level2 = req.Level2Filter, + level3 = req.Level3Filter, + level4 = req.Level4Filter, + level5 = req.Level5Filter, + pollingStationNumber = req.PollingStationNumberFilter, + hasFlaggedAnswers = req.HasFlaggedAnswers, + followUpStatus = req.FollowUpStatus?.ToString(), + tagsFilter = req.TagsFilter ?? [], }; IEnumerable aggregatedFormOverviews = []; diff --git a/api/src/Feature.Form.Submissions/ListByForm/Request.cs b/api/src/Feature.Form.Submissions/ListByForm/Request.cs index 18b1de13e..edc34a427 100644 --- a/api/src/Feature.Form.Submissions/ListByForm/Request.cs +++ b/api/src/Feature.Form.Submissions/ListByForm/Request.cs @@ -8,4 +8,31 @@ public class Request [FromClaim(ApplicationClaimTypes.NgoId)] public Guid NgoId { get; set; } + + [QueryParam] + public string? Level1Filter { get; set; } + + [QueryParam] + public string? Level2Filter { get; set; } + + [QueryParam] + public string? Level3Filter { get; set; } + + [QueryParam] + public string? Level4Filter { get; set; } + + [QueryParam] + public string? Level5Filter { get; set; } + + [QueryParam] + public string? PollingStationNumberFilter { get; set; } + + [QueryParam] + public bool? HasFlaggedAnswers { get; set; } + + [QueryParam] + public SubmissionFollowUpStatus? FollowUpStatus { get; set; } + + [QueryParam] + public string[]? TagsFilter { get; set; } = []; } diff --git a/api/src/Feature.Form.Submissions/ListEntries/Endpoint.cs b/api/src/Feature.Form.Submissions/ListEntries/Endpoint.cs index 8b4b38392..f2aca6350 100644 --- a/api/src/Feature.Form.Submissions/ListEntries/Endpoint.cs +++ b/api/src/Feature.Form.Submissions/ListEntries/Endpoint.cs @@ -66,6 +66,7 @@ UNION ALL SELECT count(*) AS count AND (@pollingStationNumber IS NULL OR ps."Number" = @pollingStationNumber) AND (@hasFlaggedAnswers is NULL OR (fs."NumberOfFlaggedAnswers" = 0 AND @hasFlaggedAnswers = false) OR ("NumberOfFlaggedAnswers" > 0 AND @hasFlaggedAnswers = true)) AND (@followUpStatus is NULL OR fs."FollowUpStatus" = @followUpStatus) + AND (@tagsFilter IS NULL OR cardinality(@tagsFilter) = 0 OR mo."Tags" && @tagsFilter) ) c; WITH submissions AS @@ -75,7 +76,7 @@ WITH submissions AS psi."PollingStationId", psi."MonitoringObserverId", psi."NumberOfQuestionsAnswered", - 0 AS "NumberOfFlaggedAnswers", + psi."NumberOfFlaggedAnswers", 0 AS "MediaFilesCount", 0 AS "NotesCount", COALESCE(psi."LastModifiedOn", psi."CreatedOn") "TimeSubmitted", @@ -154,6 +155,8 @@ FROM submissions s AND (@pollingStationNumber IS NULL OR ps."Number" = @pollingStationNumber) AND (@hasFlaggedAnswers is NULL OR ("NumberOfFlaggedAnswers" = 0 AND @hasFlaggedAnswers = false) OR ("NumberOfFlaggedAnswers" > 0 AND @hasFlaggedAnswers = true)) AND (@followUpStatus is NULL OR "FollowUpStatus" = @followUpStatus) + AND (@tagsFilter IS NULL OR cardinality(@tagsFilter) = 0 OR mo."Tags" && @tagsFilter) + ORDER BY CASE WHEN @sortExpression = 'TimeSubmitted ASC' THEN s."TimeSubmitted" END ASC, CASE WHEN @sortExpression = 'TimeSubmitted DESC' THEN s."TimeSubmitted" END DESC, @@ -226,6 +229,7 @@ OFFSET @offset ROWS pollingStationNumber = req.PollingStationNumberFilter, hasFlaggedAnswers = req.HasFlaggedAnswers, followUpStatus = req.FollowUpStatus?.ToString(), + tagsFilter = req.TagsFilter ?? [], sortExpression = GetSortExpression(req.SortColumnName, req.IsAscendingSorting) }; diff --git a/api/src/Feature.Form.Submissions/ListEntries/Request.cs b/api/src/Feature.Form.Submissions/ListEntries/Request.cs index 435bb5ac2..d4d582a1e 100644 --- a/api/src/Feature.Form.Submissions/ListEntries/Request.cs +++ b/api/src/Feature.Form.Submissions/ListEntries/Request.cs @@ -43,4 +43,7 @@ public class Request : BaseSortPaginatedRequest [QueryParam] public Guid? MonitoringObserverId { get; set; } + + [QueryParam] + public string[]? TagsFilter { get; set; } = []; } diff --git a/api/src/Feature.Locations/Create/Endpoint.cs b/api/src/Feature.Locations/Create/Endpoint.cs new file mode 100644 index 000000000..65e47af0f --- /dev/null +++ b/api/src/Feature.Locations/Create/Endpoint.cs @@ -0,0 +1,67 @@ +using Feature.Locations.Specifications; +using Vote.Monitor.Core.Helpers; +using Vote.Monitor.Core.Services.Security; +using Vote.Monitor.Core.Services.Time; + +namespace Feature.Locations.Create; +public class Endpoint(IRepository repository, + IRepository electionRoundRepository, + ITimeProvider timeProvider, + ICurrentUserProvider userProvider) + : Endpoint, Conflict, NotFound>> +{ + public override void Configure() + { + Post("api/election-rounds/{electionRoundId}/locations"); + DontAutoTag(); + Options(x => x.WithTags("locations")); + Policies(PolicyNames.PlatformAdminsOnly); + } + + public override async Task, Conflict, NotFound>> ExecuteAsync(Request req, CancellationToken ct) + { + var specification = new GetLocationSpecification(req.ElectionRoundId, req.Level1, req.Level2, req.Level3, + req.Level4, req.Level5); + var haIdenticalLocation = await repository.AnyAsync(specification, ct); + + if (haIdenticalLocation) + { + AddError("A location with same address and tags exists"); + return TypedResults.Conflict(new ProblemDetails(ValidationFailures)); + } + + var electionRound = await electionRoundRepository.GetByIdAsync(req.ElectionRoundId, ct); + if (electionRound is null) + { + AddError(r => r.ElectionRoundId, "Election round not found"); + return TypedResults.NotFound(new ProblemDetails(ValidationFailures)); + } + + var location = LocationAggregate.Create(electionRound, + req.Level1, + req.Level2, + req.Level3, + req.Level4, + req.Level5, + req.DisplayOrder, + req.Tags.ToTagsObject(), + timeProvider.UtcNow, + userProvider.GetUserId()!.Value); + + await repository.AddAsync(location, ct); + electionRound.UpdateLocationsVersion(); + await electionRoundRepository.UpdateAsync(electionRound, ct); + + return TypedResults.Ok(new LocationModel + { + Id = location.Id, + Level1 = location.Level1, + Level2 = location.Level2, + Level3 = location.Level3, + Level4 = location.Level4, + Level5 = location.Level5, + DisplayOrder = location.DisplayOrder, + Tags = location.Tags.ToDictionary() + }); + } +} diff --git a/api/src/Feature.Locations/Create/Request.cs b/api/src/Feature.Locations/Create/Request.cs new file mode 100644 index 000000000..a4149a375 --- /dev/null +++ b/api/src/Feature.Locations/Create/Request.cs @@ -0,0 +1,12 @@ +namespace Feature.Locations.Create; +public class Request +{ + public Guid ElectionRoundId { get; set; } + public string Level1 { get; set; } + public string Level2 { get; set; } + public string Level3 { get; set; } + public string Level4 { get; set; } + public string Level5 { get; set; } + public int DisplayOrder { get; set; } + public Dictionary Tags { get; set; } +} diff --git a/api/src/Feature.Locations/Create/Validator.cs b/api/src/Feature.Locations/Create/Validator.cs new file mode 100644 index 000000000..fc1c1d285 --- /dev/null +++ b/api/src/Feature.Locations/Create/Validator.cs @@ -0,0 +1,16 @@ +namespace Feature.Locations.Create; + +public class Validator : Validator +{ + public Validator() + { + RuleFor(x => x.ElectionRoundId).NotEmpty(); + + RuleFor(x => x.Level1).NotEmpty(); + RuleFor(x => x.Level2).NotEmpty().When(x => !string.IsNullOrWhiteSpace(x.Level3)); + RuleFor(x => x.Level3).NotEmpty().When(x => !string.IsNullOrWhiteSpace(x.Level4)); + RuleFor(x => x.Level4).NotEmpty().When(x => !string.IsNullOrWhiteSpace(x.Level5)); + RuleFor(x => x.DisplayOrder) + .GreaterThanOrEqualTo(0); + } +} \ No newline at end of file diff --git a/api/src/Feature.Locations/Delete/Endpoint.cs b/api/src/Feature.Locations/Delete/Endpoint.cs new file mode 100644 index 000000000..0e686e10e --- /dev/null +++ b/api/src/Feature.Locations/Delete/Endpoint.cs @@ -0,0 +1,40 @@ +using Feature.Locations.Specifications; + +namespace Feature.Locations.Delete; +public class Endpoint(IRepository repository, + IRepository electionRoundRepository) + : Endpoint, ProblemDetails>> +{ + public override void Configure() + { + Delete("/api/election-rounds/{electionRoundId}/locations/{id}"); + DontAutoTag(); + Options(x => x.WithTags("locations")); + Policies(PolicyNames.PlatformAdminsOnly); + } + + public override async Task, ProblemDetails>> ExecuteAsync(Request req, CancellationToken ct) + { + var electionRound = await electionRoundRepository.GetByIdAsync(req.ElectionRoundId, ct); + if (electionRound is null) + { + AddError(r => r.ElectionRoundId, "Election round not found"); + return TypedResults.NotFound(new ProblemDetails(ValidationFailures)); + } + + var location = await repository.FirstOrDefaultAsync(new GetLocationByIdSpecification(req.ElectionRoundId, req.Id), ct); + + if (location is null) + { + AddError(r => r.Id, "Location not found"); + return TypedResults.NotFound(new ProblemDetails(ValidationFailures)); + } + + await repository.DeleteAsync(location, ct); + + electionRound.UpdateLocationsVersion(); + await electionRoundRepository.UpdateAsync(electionRound, ct); + + return TypedResults.NoContent(); + } +} diff --git a/api/src/Feature.Locations/Delete/Request.cs b/api/src/Feature.Locations/Delete/Request.cs new file mode 100644 index 000000000..0e827b0d8 --- /dev/null +++ b/api/src/Feature.Locations/Delete/Request.cs @@ -0,0 +1,7 @@ +namespace Feature.Locations.Delete; + +public class Request +{ + public Guid ElectionRoundId { get; set; } + public Guid Id { get; set; } +} \ No newline at end of file diff --git a/api/src/Feature.Locations/Delete/Validator.cs b/api/src/Feature.Locations/Delete/Validator.cs new file mode 100644 index 000000000..9cb5a48fb --- /dev/null +++ b/api/src/Feature.Locations/Delete/Validator.cs @@ -0,0 +1,11 @@ +namespace Feature.Locations.Delete; + +public class Validator : Validator +{ + public Validator() + { + RuleFor(x => x.ElectionRoundId).NotEmpty(); + RuleFor(x => x.Id) + .NotEmpty(); + } +} diff --git a/api/src/Feature.Locations/EnableTesting.cs b/api/src/Feature.Locations/EnableTesting.cs new file mode 100644 index 000000000..2919be947 --- /dev/null +++ b/api/src/Feature.Locations/EnableTesting.cs @@ -0,0 +1,5 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Feature.Locations.UnitTests")] +[assembly: InternalsVisibleTo("Vote.Monitor.Api.IntegrationTests")] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] diff --git a/api/src/Feature.Locations/Feature.Locations.csproj b/api/src/Feature.Locations/Feature.Locations.csproj new file mode 100644 index 000000000..790d82b30 --- /dev/null +++ b/api/src/Feature.Locations/Feature.Locations.csproj @@ -0,0 +1,30 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/api/src/Feature.Locations/FetchAll/Endpoint.cs b/api/src/Feature.Locations/FetchAll/Endpoint.cs new file mode 100644 index 000000000..736558dd8 --- /dev/null +++ b/api/src/Feature.Locations/FetchAll/Endpoint.cs @@ -0,0 +1,146 @@ +using Microsoft.Extensions.Caching.Memory; +using Vote.Monitor.Core.Extensions; + +namespace Feature.Locations.FetchAll; +public class Endpoint(VoteMonitorContext context, IMemoryCache cache) : Endpoint, NotFound>> +{ + public override void Configure() + { + Get("/api/election-rounds/{electionRoundId}/locations:fetchAll"); + DontAutoTag(); + AllowAnonymous(); + Options(x => x.WithTags("locations", "mobile")); + Description(x => x.Accepts()); + Summary(s => + { + s.Summary = "Gets all locations for a specific election round"; + s.Description = "Gets all locations and a cache key for the data"; + }); + } + + public override async Task, NotFound>> ExecuteAsync(Request request, CancellationToken ct) + { + var electionRound = await context.ElectionRounds + .Where(x => x.Id == request.ElectionRoundId) + .Select(x => new { x.LocationsVersion, x.Id }) + .FirstOrDefaultAsync(ct); + + if (electionRound is null) + { + return TypedResults.NotFound(); + } + + var cacheKey = $"election-rounds/{request.ElectionRoundId}/locations/{electionRound.LocationsVersion}"; + + var cachedResponse = await cache.GetOrCreateAsync(cacheKey, async (e) => + { + var locations = await context.Locations + .Where(x => x.ElectionRoundId == request.ElectionRoundId) + .OrderBy(x => x.DisplayOrder) + .Select(x => new LocationModel + { + Id = x.Id, + Level1 = x.Level1, + Level2 = x.Level2, + Level3 = x.Level3, + Level4 = x.Level4, + Level5 = x.Level5, + DisplayOrder = x.DisplayOrder + }) + .ToListAsync(cancellationToken: ct); + + e.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30); + + var nodes = GetLocationNodes(locations); + + return new Response + { + ElectionRoundId = electionRound.Id, + Version = electionRound.LocationsVersion.ToString(), + Nodes = nodes + }; + }); + + return TypedResults.Ok(cachedResponse!); + } + + private static List GetLocationNodes(List locations) + { + Dictionary cache = new(); + var result = new List(); + int id = 0; + + foreach (var location in locations) + { + var parentNode = cache.GetOrCreate(BuildKey(location.Level1), () => new LocationNode + { + Id = ++id, + Name = location.Level1, + Depth = 1 + }); + + if (!string.IsNullOrWhiteSpace(location.Level2)) + { + var level2Key = BuildKey(location.Level1, location.Level2); + parentNode = cache.GetOrCreate(level2Key, () => new LocationNode + { + Id = ++id, + Name = location.Level2, + ParentId = parentNode.Id, + Depth = 2, + DisplayOrder = location.DisplayOrder + }); + } + + if (!string.IsNullOrWhiteSpace(location.Level3)) + { + var level3Key = BuildKey(location.Level1, location.Level2, location.Level3); + parentNode = cache.GetOrCreate(level3Key, () => new LocationNode + { + Id = ++id, + Name = location.Level3, + ParentId = parentNode.Id, + Depth = 3 + }); + } + + if (!string.IsNullOrWhiteSpace(location.Level4)) + { + var level4Key = BuildKey(location.Level1, location.Level2, location.Level3, location.Level4); + parentNode = cache.GetOrCreate(level4Key, () => new LocationNode + { + Id = ++id, + Name = location.Level4, + ParentId = parentNode.Id, + Depth = 4 + }); + } + + if (!string.IsNullOrWhiteSpace(location.Level5)) + { + var level5Key = BuildKey(location.Level1, location.Level2, location.Level3, location.Level4, location.Level5); + parentNode = cache.GetOrCreate(level5Key, () => new LocationNode + { + Id = ++id, + Name = location.Level5, + ParentId = parentNode.Id, + Depth = 5 + }); + } + + result.Add(new LocationNode + { + Id = ++id, + ParentId = parentNode!.Id, + LocationId = location.Id + }); + } + + return [.. cache.Values, .. result]; + } + + private static string BuildKey(params string[] keyParts) + { + return string.Join("-", keyParts); + } +} diff --git a/api/src/Feature.Locations/FetchAll/LocationNode.cs b/api/src/Feature.Locations/FetchAll/LocationNode.cs new file mode 100644 index 000000000..0b5b82120 --- /dev/null +++ b/api/src/Feature.Locations/FetchAll/LocationNode.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; + +namespace Feature.Locations.FetchAll; + +public class LocationNode +{ + public int Id { get; set; } + public string Name { get; set; } + public int Depth { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? ParentId { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Guid? LocationId { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? DisplayOrder { get; set; } +} diff --git a/api/src/Feature.Locations/FetchAll/Request.cs b/api/src/Feature.Locations/FetchAll/Request.cs new file mode 100644 index 000000000..92e6bde6b --- /dev/null +++ b/api/src/Feature.Locations/FetchAll/Request.cs @@ -0,0 +1,5 @@ +namespace Feature.Locations.FetchAll; +public class Request +{ + public Guid ElectionRoundId { get; set; } +} diff --git a/api/src/Feature.Locations/FetchAll/Response.cs b/api/src/Feature.Locations/FetchAll/Response.cs new file mode 100644 index 000000000..9a607b6fe --- /dev/null +++ b/api/src/Feature.Locations/FetchAll/Response.cs @@ -0,0 +1,8 @@ +namespace Feature.Locations.FetchAll; + +public class Response +{ + public Guid ElectionRoundId { get; set; } + public string Version { get; set; } + public List Nodes { get; set; } = []; +} diff --git a/api/src/Feature.Locations/FetchAll/Validator.cs b/api/src/Feature.Locations/FetchAll/Validator.cs new file mode 100644 index 000000000..86712a1f1 --- /dev/null +++ b/api/src/Feature.Locations/FetchAll/Validator.cs @@ -0,0 +1,9 @@ +namespace Feature.Locations.FetchAll; + +public class Validator : Validator +{ + public Validator() + { + RuleFor(x => x.ElectionRoundId).NotEmpty(); + } +} diff --git a/api/src/Feature.Locations/FetchLevels/Endpoint.cs b/api/src/Feature.Locations/FetchLevels/Endpoint.cs new file mode 100644 index 000000000..f64c646a9 --- /dev/null +++ b/api/src/Feature.Locations/FetchLevels/Endpoint.cs @@ -0,0 +1,127 @@ +using Microsoft.Extensions.Caching.Memory; +using Vote.Monitor.Core.Extensions; + +namespace Feature.Locations.FetchLevels; +public class Endpoint(VoteMonitorContext context, IMemoryCache memoryCache) : Endpoint, NotFound>> +{ + public override void Configure() + { + Get("/api/election-rounds/{electionRoundId}/locations:fetchLevels"); + DontAutoTag(); + Options(x => x.WithTags("locations")); + Description(x => x.Accepts()); + Summary(s => + { + s.Summary = "Gets all levels for all locations"; + s.Description = "Gets all locations and a cache key for the data"; + }); + } + + public override async Task, NotFound>> ExecuteAsync(Request request, CancellationToken ct) + { + var electionRound = await context.ElectionRounds + .Where(x => x.Id == request.ElectionRoundId) + .Select(x => new { x.LocationsVersion, x.Id }) + .FirstOrDefaultAsync(ct); + + if (electionRound is null) + { + return TypedResults.NotFound(); + } + + var cacheKey = $"election-rounds/{request.ElectionRoundId}/location-nodes/{electionRound.LocationsVersion}"; + + var cachedResponse = await memoryCache.GetOrCreateAsync(cacheKey, async (e) => + { + var locations = await context.Locations + .Where(x => x.ElectionRoundId == request.ElectionRoundId) + .Select(x => new + { + x.Level1, + x.Level2, + x.Level3, + x.Level4, + x.Level5, + }) + .Distinct() + .ToListAsync(cancellationToken: ct); + + e.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30); + + Dictionary cache = new(); + int id = 0; + + foreach (var ps in locations) + { + var parentNode = cache.GetOrCreate(BuildKey(ps.Level1), () => new LevelNode + { + Id = ++id, + Name = ps.Level1, + Depth = 1 + }); + + if (!string.IsNullOrWhiteSpace(ps.Level2)) + { + var level2Key = BuildKey(ps.Level1, ps.Level2); + parentNode = cache.GetOrCreate(level2Key, () => new LevelNode + { + Id = ++id, + Name = ps.Level2, + ParentId = parentNode.Id, + Depth = 2 + }); + } + + if (!string.IsNullOrWhiteSpace(ps.Level3)) + { + var level3Key = BuildKey(ps.Level1, ps.Level2, ps.Level3); + parentNode = cache.GetOrCreate(level3Key, () => new LevelNode + { + Id = ++id, + Name = ps.Level3, + ParentId = parentNode.Id, + Depth = 3 + }); + } + + if (!string.IsNullOrWhiteSpace(ps.Level4)) + { + var level4Key = BuildKey(ps.Level1, ps.Level2, ps.Level3, ps.Level4); + parentNode = cache.GetOrCreate(level4Key, () => new LevelNode + { + Id = ++id, + Name = ps.Level4, + ParentId = parentNode.Id, + Depth = 4 + }); + } + + if (!string.IsNullOrWhiteSpace(ps.Level5)) + { + var level5Key = BuildKey(ps.Level1, ps.Level2, ps.Level3, ps.Level4, ps.Level5); + parentNode = cache.GetOrCreate(level5Key, () => new LevelNode + { + Id = ++id, + Name = ps.Level5, + ParentId = parentNode.Id, + Depth = 5 + }); + } + } + + return new Response + { + ElectionRoundId = electionRound.Id, + Version = electionRound.LocationsVersion.ToString(), + Nodes = [.. cache.Values] + }; + }); + + return TypedResults.Ok(cachedResponse!); + } + + private static string BuildKey(params string[] keyParts) + { + return string.Join("-", keyParts); + } +} diff --git a/api/src/Feature.Locations/FetchLevels/LevelNode.cs b/api/src/Feature.Locations/FetchLevels/LevelNode.cs new file mode 100644 index 000000000..90e7fc6ec --- /dev/null +++ b/api/src/Feature.Locations/FetchLevels/LevelNode.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace Feature.Locations.FetchLevels; + +public class LevelNode +{ + public int Id { get; set; } + public string Name { get; set; } + public int Depth { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? ParentId { get; set; } +} diff --git a/api/src/Feature.Locations/FetchLevels/Request.cs b/api/src/Feature.Locations/FetchLevels/Request.cs new file mode 100644 index 000000000..61ed8b680 --- /dev/null +++ b/api/src/Feature.Locations/FetchLevels/Request.cs @@ -0,0 +1,5 @@ +namespace Feature.Locations.FetchLevels; +public class Request +{ + public Guid ElectionRoundId { get; set; } +} diff --git a/api/src/Feature.Locations/FetchLevels/Response.cs b/api/src/Feature.Locations/FetchLevels/Response.cs new file mode 100644 index 000000000..ba32f8958 --- /dev/null +++ b/api/src/Feature.Locations/FetchLevels/Response.cs @@ -0,0 +1,8 @@ +namespace Feature.Locations.FetchLevels; + +public class Response +{ + public Guid ElectionRoundId { get; set; } + public string Version { get; set; } + public List Nodes { get; set; } = []; +} diff --git a/api/src/Feature.Locations/FetchLevels/Validator.cs b/api/src/Feature.Locations/FetchLevels/Validator.cs new file mode 100644 index 000000000..165b90f22 --- /dev/null +++ b/api/src/Feature.Locations/FetchLevels/Validator.cs @@ -0,0 +1,9 @@ +namespace Feature.Locations.FetchLevels; + +public class Validator : Validator +{ + public Validator() + { + RuleFor(x => x.ElectionRoundId).NotEmpty(); + } +} diff --git a/api/src/Feature.Locations/Get/Endpoint.cs b/api/src/Feature.Locations/Get/Endpoint.cs new file mode 100644 index 000000000..b68511efe --- /dev/null +++ b/api/src/Feature.Locations/Get/Endpoint.cs @@ -0,0 +1,43 @@ +using Feature.Locations.Specifications; +using Vote.Monitor.Core.Helpers; + +namespace Feature.Locations.Get; + +public class Endpoint : Endpoint, NotFound>> +{ + private readonly IReadRepository _repository; + + public Endpoint(IReadRepository repository) + { + _repository = repository; + } + + public override void Configure() + { + Get("/api/election-rounds/{electionRoundId}/locations/{id}"); + DontAutoTag(); + Options(x => x.WithTags("locations")); + } + + public override async Task, NotFound>> ExecuteAsync(Request req, CancellationToken ct) + { + var location = await _repository.FirstOrDefaultAsync(new GetLocationByIdSpecification(req.ElectionRoundId, req.Id), ct); + + if (location is null) + { + return TypedResults.NotFound(); + } + + return TypedResults.Ok(new LocationModel + { + Id = location.Id, + Level1 = location.Level1, + Level2 = location.Level2, + Level3 = location.Level3, + Level4 = location.Level4, + Level5 = location.Level5, + DisplayOrder = location.DisplayOrder, + Tags = location.Tags.ToDictionary() + }); + } +} diff --git a/api/src/Feature.Locations/Get/Request.cs b/api/src/Feature.Locations/Get/Request.cs new file mode 100644 index 000000000..af4689d01 --- /dev/null +++ b/api/src/Feature.Locations/Get/Request.cs @@ -0,0 +1,7 @@ +namespace Feature.Locations.Get; + +public class Request +{ + public Guid ElectionRoundId { get; set; } + public Guid Id { get; set; } +} diff --git a/api/src/Feature.Locations/Get/Validator.cs b/api/src/Feature.Locations/Get/Validator.cs new file mode 100644 index 000000000..dd709240d --- /dev/null +++ b/api/src/Feature.Locations/Get/Validator.cs @@ -0,0 +1,11 @@ +namespace Feature.Locations.Get; + +public class Validator : Validator +{ + public Validator() + { + RuleFor(x => x.ElectionRoundId).NotEmpty(); + RuleFor(x => x.Id) + .NotEmpty(); + } +} diff --git a/api/src/Feature.Locations/GetLocationsVersion/Endpoint.cs b/api/src/Feature.Locations/GetLocationsVersion/Endpoint.cs new file mode 100644 index 000000000..bbd23bb7a --- /dev/null +++ b/api/src/Feature.Locations/GetLocationsVersion/Endpoint.cs @@ -0,0 +1,45 @@ +using Authorization.Policies.Requirements; +using Microsoft.AspNetCore.Authorization; + +namespace Feature.Locations.GetLocationsVersion; + +public class Endpoint(IAuthorizationService authorizationService, VoteMonitorContext context) : Endpoint, NotFound>> +{ + public override void Configure() + { + Get("/api/election-rounds/{electionRoundId}/locations:version"); + DontAutoTag(); + Options(x => x.WithTags("locations", "mobile")); + Summary(s => + { + s.Summary = "Gets current version of locations for an election round"; + s.Description = "Cache key changes every time any location changes"; + }); + } + + public override async Task, NotFound>> ExecuteAsync(Request req, CancellationToken ct) + { + var requirement = new MonitoringObserverRequirement(req.ElectionRoundId); + var authorizationResult = await authorizationService.AuthorizeAsync(User, requirement); + if (!authorizationResult.Succeeded) + { + return TypedResults.NotFound(); + } + + var electionRound = await context.ElectionRounds + .Where(x => x.Id == req.ElectionRoundId) + .Select(x => new { x.LocationsVersion, x.Id }) + .FirstOrDefaultAsync(ct); + + if (electionRound is null) + { + return TypedResults.NotFound(); + } + + return TypedResults.Ok(new Response + { + ElectionRoundId = electionRound.Id, + CacheKey = electionRound.LocationsVersion.ToString() + }); + } +} diff --git a/api/src/Feature.Locations/GetLocationsVersion/Request.cs b/api/src/Feature.Locations/GetLocationsVersion/Request.cs new file mode 100644 index 000000000..bcfad81ba --- /dev/null +++ b/api/src/Feature.Locations/GetLocationsVersion/Request.cs @@ -0,0 +1,6 @@ +namespace Feature.Locations.GetLocationsVersion; + +public class Request +{ + public required Guid ElectionRoundId { get; set; } +} diff --git a/api/src/Feature.Locations/GetLocationsVersion/Response.cs b/api/src/Feature.Locations/GetLocationsVersion/Response.cs new file mode 100644 index 000000000..c8f24b787 --- /dev/null +++ b/api/src/Feature.Locations/GetLocationsVersion/Response.cs @@ -0,0 +1,7 @@ +namespace Feature.Locations.GetLocationsVersion; + +public class Response +{ + public Guid ElectionRoundId { get; set; } + public string CacheKey { get; set; } +} diff --git a/api/src/Feature.Locations/GetLocationsVersion/Validator.cs b/api/src/Feature.Locations/GetLocationsVersion/Validator.cs new file mode 100644 index 000000000..9f202a317 --- /dev/null +++ b/api/src/Feature.Locations/GetLocationsVersion/Validator.cs @@ -0,0 +1,9 @@ +namespace Feature.Locations.GetLocationsVersion; + +public class Validator : Validator +{ + public Validator() + { + RuleFor(x => x.ElectionRoundId).NotEmpty(); + } +} diff --git a/api/src/Feature.Locations/GlobalUsings.cs b/api/src/Feature.Locations/GlobalUsings.cs new file mode 100644 index 000000000..bb43fd94e --- /dev/null +++ b/api/src/Feature.Locations/GlobalUsings.cs @@ -0,0 +1,20 @@ +// Global using directives + +global using System.Text.Json; +global using Ardalis.Specification; +global using Authorization.Policies; +global using CsvHelper; +global using EFCore.BulkExtensions; +global using FastEndpoints; +global using FluentValidation; +global using FluentValidation.Results; +global using Microsoft.AspNetCore.Http; +global using Microsoft.AspNetCore.Http.HttpResults; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.Extensions.Logging; +global using Microsoft.Extensions.Options; +global using Vote.Monitor.Core.Services.Csv; +global using Vote.Monitor.Domain; +global using Vote.Monitor.Domain.Repository; +global using LocationAggregate = Vote.Monitor.Domain.Entities.LocationAggregate.Location; +global using ElectionRoundAggregate = Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound; diff --git a/api/src/Feature.Locations/Import/Endpoint.cs b/api/src/Feature.Locations/Import/Endpoint.cs new file mode 100644 index 000000000..a4c760928 --- /dev/null +++ b/api/src/Feature.Locations/Import/Endpoint.cs @@ -0,0 +1,68 @@ +using Feature.Locations.Services; +using Vote.Monitor.Core.Helpers; +using Vote.Monitor.Core.Services.Security; +using Vote.Monitor.Core.Services.Time; + +namespace Feature.Locations.Import; +public class Endpoint( + IRepository electionRoundRepository, + VoteMonitorContext context, + ILocationsParser parser, + ITimeProvider timeProvider, + ICurrentUserProvider userProvider) + : Endpoint, NotFound, ProblemDetails>> +{ + public override void Configure() + { + Post("/api/election-rounds/{electionRoundId}/locations:import"); + DontAutoTag(); + Options(x => x.WithTags("locations")); + AllowFileUploads(); + Policies(PolicyNames.PlatformAdminsOnly); + } + + public override async Task, NotFound, ProblemDetails>> ExecuteAsync(Request req, CancellationToken ct) + { + var electionRound = await electionRoundRepository.GetByIdAsync(req.ElectionRoundId, ct); + if (electionRound is null) + { + AddError(r => r.ElectionRoundId, "Election round not found"); + return TypedResults.NotFound(new ProblemDetails(ValidationFailures)); + } + + var parsingResult = parser.Parse(req.File.OpenReadStream()); + if (parsingResult is LocationParsingResult.Fail failedResult) + { + foreach (var validationFailure in failedResult.ValidationErrors.SelectMany(x => x.Errors)) + { + AddError(validationFailure); + } + + ThrowIfAnyErrors(); + } + + var successResult = parsingResult as LocationParsingResult.Success; + + var entities = successResult! + .Locations + .Select(x => LocationAggregate.Create(electionRound, + x.Level1, + x.Level2, + x.Level3, + x.Level4, + x.Level5, + x.DisplayOrder, + x.Tags.ToTagsObject(), + timeProvider.UtcNow, + userProvider.GetUserId()!.Value)) + .ToList(); + + await context.BulkInsertAsync(entities, cancellationToken: ct); + + electionRound.UpdateLocationsVersion(); + + await electionRoundRepository.UpdateAsync(electionRound, cancellationToken: ct); + + return TypedResults.Ok(new Response { RowsImported = entities.Count }); + } +} diff --git a/api/src/Feature.Locations/Import/Request.cs b/api/src/Feature.Locations/Import/Request.cs new file mode 100644 index 000000000..147a9c3db --- /dev/null +++ b/api/src/Feature.Locations/Import/Request.cs @@ -0,0 +1,7 @@ +namespace Feature.Locations.Import; + +public class Request +{ + public required Guid ElectionRoundId { get; set; } + public required IFormFile File { get; set; } +} diff --git a/api/src/Feature.Locations/Import/Response.cs b/api/src/Feature.Locations/Import/Response.cs new file mode 100644 index 000000000..ddbb03c84 --- /dev/null +++ b/api/src/Feature.Locations/Import/Response.cs @@ -0,0 +1,6 @@ +namespace Feature.Locations.Import; + +public class Response +{ + public required int RowsImported { get; set; } +} diff --git a/api/src/Feature.Locations/Import/Validator.cs b/api/src/Feature.Locations/Import/Validator.cs new file mode 100644 index 000000000..41e75f071 --- /dev/null +++ b/api/src/Feature.Locations/Import/Validator.cs @@ -0,0 +1,16 @@ +namespace Feature.Locations.Import; + +public class Validator : Validator +{ + public Validator() + { + RuleFor(x => x.ElectionRoundId).NotEmpty(); + RuleFor(x => x.File) + .NotEmpty(); + + RuleFor(x => x.File) + .Must(file => Path.GetExtension(file.FileName).ToLower() == ".csv") + .When(x => x.File != null) + .WithMessage("Only CSV files are accepted."); + } +} diff --git a/api/src/Feature.Locations/List/Endpoint.cs b/api/src/Feature.Locations/List/Endpoint.cs new file mode 100644 index 000000000..1e16a33b3 --- /dev/null +++ b/api/src/Feature.Locations/List/Endpoint.cs @@ -0,0 +1,41 @@ +using Feature.Locations.Specifications; +using Vote.Monitor.Core.Helpers; +using Vote.Monitor.Core.Models; + +namespace Feature.Locations.List; +public class Endpoint : Endpoint>, ProblemDetails>> +{ + private readonly IReadRepository _repository; + + public Endpoint(IReadRepository repository) + { + _repository = repository; + } + + public override void Configure() + { + Get("/api/election-rounds/{electionRoundId}/locations:list"); + DontAutoTag(); + Options(x => x.WithTags("locations")); + } + + public override async Task>, ProblemDetails>> ExecuteAsync(Request request, CancellationToken ct) + { + var specification = new ListLocationsSpecification(request); + var locations = await _repository.ListAsync(specification, ct); + var locationsCount = await _repository.CountAsync(specification, ct); + var result = locations.Select(x => new LocationModel + { + Id = x.Id, + Level1 = x.Level1, + Level2 = x.Level2, + Level3 = x.Level3, + Level4 = x.Level4, + Level5 = x.Level5, + DisplayOrder = x.DisplayOrder, + Tags = x.Tags.ToDictionary() + }).ToList(); + + return TypedResults.Ok(new PagedResponse(result, locationsCount, request.PageNumber, request.PageSize)); + } +} diff --git a/api/src/Feature.Locations/List/Request.cs b/api/src/Feature.Locations/List/Request.cs new file mode 100644 index 000000000..47b099f2a --- /dev/null +++ b/api/src/Feature.Locations/List/Request.cs @@ -0,0 +1,22 @@ +using Vote.Monitor.Core.Models; + +namespace Feature.Locations.List; +public class Request : BaseSortPaginatedRequest +{ + public Guid ElectionRoundId { get; set; } + + [QueryParam] + public string? Level1Filter { get; set; } + + [QueryParam] + public string? Level2Filter { get; set; } + + [QueryParam] + public string? Level3Filter { get; set; } + + [QueryParam] + public string? Level4Filter { get; set; } + + [QueryParam] + public string? Level5Filter { get; set; } +} diff --git a/api/src/Feature.Locations/List/Validator.cs b/api/src/Feature.Locations/List/Validator.cs new file mode 100644 index 000000000..000d8c553 --- /dev/null +++ b/api/src/Feature.Locations/List/Validator.cs @@ -0,0 +1,11 @@ +namespace Feature.Locations.List; + +public class Validator : Validator +{ + public Validator() + { + RuleFor(x => x.ElectionRoundId).NotEmpty(); + RuleFor(x => x.PageSize).InclusiveBetween(1, 100); + RuleFor(x => x.PageNumber).GreaterThan(0); + } +} diff --git a/api/src/Feature.Locations/LocationModel.cs b/api/src/Feature.Locations/LocationModel.cs new file mode 100644 index 000000000..a284b1ac1 --- /dev/null +++ b/api/src/Feature.Locations/LocationModel.cs @@ -0,0 +1,12 @@ +namespace Feature.Locations; +public class LocationModel +{ + public Guid Id { get; set; } + public string Level1 { get; set; } + public string Level2 { get; set; } + public string Level3 { get; set; } + public string Level4 { get; set; } + public string Level5 { get; set; } + public int DisplayOrder { get; set; } + public Dictionary Tags { get; set; } +} diff --git a/api/src/Feature.Locations/LocationsFeatureInstaller.cs b/api/src/Feature.Locations/LocationsFeatureInstaller.cs new file mode 100644 index 000000000..faa18d763 --- /dev/null +++ b/api/src/Feature.Locations/LocationsFeatureInstaller.cs @@ -0,0 +1,18 @@ +using Feature.Locations.Options; +using Feature.Locations.Services; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace Feature.Locations; +public static class LocationsFeatureInstaller +{ + public const string SectionKey = "LocationsFeatureConfig"; + + public static IServiceCollection AddLocationsFeature(this IServiceCollection services, IConfigurationSection config) + { + services.Configure(config.GetSection(LocationParserConfig.Key)); + + services.AddSingleton(); + return services; + } +} diff --git a/api/src/Feature.Locations/Options/LocationParserConfig.cs b/api/src/Feature.Locations/Options/LocationParserConfig.cs new file mode 100644 index 000000000..44f84f10b --- /dev/null +++ b/api/src/Feature.Locations/Options/LocationParserConfig.cs @@ -0,0 +1,7 @@ +namespace Feature.Locations.Options; + +public class LocationParserConfig +{ + public const string Key = "ParserConfig"; + public int MaxParserErrorsReturned { get; set; } +} diff --git a/api/src/Feature.Locations/Services/ILocationsParser.cs b/api/src/Feature.Locations/Services/ILocationsParser.cs new file mode 100644 index 000000000..8e46e7d99 --- /dev/null +++ b/api/src/Feature.Locations/Services/ILocationsParser.cs @@ -0,0 +1,6 @@ +namespace Feature.Locations.Services; + +public interface ILocationsParser +{ + LocationParsingResult Parse(Stream stream); +} diff --git a/api/src/Feature.Locations/Services/LocationImportModel.cs b/api/src/Feature.Locations/Services/LocationImportModel.cs new file mode 100644 index 000000000..30cbd4c65 --- /dev/null +++ b/api/src/Feature.Locations/Services/LocationImportModel.cs @@ -0,0 +1,14 @@ +using Vote.Monitor.Core.Models; + +namespace Feature.Locations.Services; +public class LocationImportModel +{ + public int DisplayOrder { get; set; } + public string Level1 { get; set; } + public string Level2 { get; set; } + public string Level3 { get; set; } + public string Level4 { get; set; } + public string Level5 { get; set; } + public List Tags { get; set; } +} + diff --git a/api/src/Feature.Locations/Services/LocationImportModelMapper.cs b/api/src/Feature.Locations/Services/LocationImportModelMapper.cs new file mode 100644 index 000000000..67e8a71f7 --- /dev/null +++ b/api/src/Feature.Locations/Services/LocationImportModelMapper.cs @@ -0,0 +1,35 @@ +using CsvHelper.Configuration; +using Vote.Monitor.Core.Models; + +namespace Feature.Locations.Services; +internal sealed class LocationImportModelMapper : ClassMap +{ + public LocationImportModelMapper() + { + Map(m => m.Level1).Name("level1"); // 0 + Map(m => m.Level2).Name("level2"); // 1 + Map(m => m.Level3).Name("level3"); // 2 + Map(m => m.Level4).Name("level4"); // 3 + Map(m => m.Level5).Name("level5"); // 4 + Map(m => m.DisplayOrder).Name("displayOrder").Optional(); //5 + Map(m => m.Tags).Convert(ReadTags); // 6 -> end + } + + private static List ReadTags(ConvertFromStringArgs row) + { + var tags = new List(); + + for (var i = 6; i < row.Row?.HeaderRecord?.Length; i++) + { + var name = row.Row.HeaderRecord[i]; + var value = row.Row[i]; + tags.Add(new() + { + Name = name, + Value = value + }); + } + + return tags; + } +} diff --git a/api/src/Feature.Locations/Services/LocationImportModelValidator.cs b/api/src/Feature.Locations/Services/LocationImportModelValidator.cs new file mode 100644 index 000000000..6ff201af9 --- /dev/null +++ b/api/src/Feature.Locations/Services/LocationImportModelValidator.cs @@ -0,0 +1,33 @@ +namespace Feature.Locations.Services; + +public class LocationImportModelValidator : Validator +{ + public LocationImportModelValidator() + { + RuleFor(x => x.Level1) + .NotEmpty(); + + RuleFor(x => x.Level2) + .NotEmpty() + .When(x => !string.IsNullOrWhiteSpace(x.Level3)) + .WithMessage("Location on row {RowIndex} has invalid {PropertyName}. {PropertyName} should not be empty."); + + RuleFor(x => x.Level3) + .NotEmpty() + .When(x => !string.IsNullOrWhiteSpace(x.Level4)) + .WithMessage("Location on row {RowIndex} has invalid {PropertyName}. {PropertyName} should not be empty."); + + RuleFor(x => x.Level4) + .NotEmpty() + .When(x => !string.IsNullOrWhiteSpace(x.Level5)) + .WithMessage("Location on row {RowIndex} has invalid {PropertyName}. {PropertyName} should not be empty."); + + RuleFor(x => x.DisplayOrder) + .Must((_, displayOrder, context) => + { + context.MessageFormatter.AppendArgument("RowIndex", context.RootContextData["RowIndex"]); + return displayOrder >= 0; + }) + .WithMessage("Location on row {RowIndex} has invalid {PropertyName}. {PropertyName} should be greater than 0."); + } +} diff --git a/api/src/Feature.Locations/Services/LocationParser.cs b/api/src/Feature.Locations/Services/LocationParser.cs new file mode 100644 index 000000000..e3d6cb552 --- /dev/null +++ b/api/src/Feature.Locations/Services/LocationParser.cs @@ -0,0 +1,91 @@ +using Feature.Locations.Options; + +namespace Feature.Locations.Services; + +public class LocationParser : ILocationsParser +{ + private readonly LocationImportModelValidator _locationImportModelValidator = new(); + private readonly ICsvReader _reader; + private readonly ILogger _logger; + private readonly LocationParserConfig _parserConfig; + + public LocationParser(ICsvReader reader, + ILogger logger, + IOptions options) + { + _reader = reader; + _logger = logger; + _parserConfig = options.Value; + } + + public LocationParsingResult Parse(Stream stream) + { + try + { + var locations = _reader + .Read(stream) + .ToList(); + + int numberOfInvalidRows = 0; + int rowIndex = 1; + var validationErrors = new List(); + + foreach (var location in locations) + { + var validationResult = Validate(location, rowIndex); + if (!validationResult.IsValid) + { + validationErrors.Add(validationResult); + ++numberOfInvalidRows; + if (numberOfInvalidRows >= _parserConfig.MaxParserErrorsReturned) + { + break; + } + } + + rowIndex++; + } + + if (validationErrors.Any()) + { + return new LocationParsingResult.Fail(validationErrors.ToArray()); + } + + return new LocationParsingResult.Success(locations); + } + catch (HeaderValidationException e) + { + SentrySdk.CaptureException(e); + _logger.LogError(e, "Cannot parse the header."); + return new LocationParsingResult.Fail(new ValidationFailure("Header", + "Invalid header provided in import locations file.")); + } + catch (CsvHelper.MissingFieldException e) + { + SentrySdk.CaptureException(e); + _logger.LogError(e, "Malformed csv provided."); + return new LocationParsingResult.Fail(new ValidationFailure("Csv File", + "Malformed import locations file provided.")); + } + catch (CsvHelper.TypeConversion.TypeConverterException e) + { + SentrySdk.CaptureException(e); + _logger.LogError(e, "Invalid data found in columns."); + return new LocationParsingResult.Fail(new ValidationFailure("Csv File", + "Malformed import locations file provided.")); + } + } + + private ValidationResult Validate(LocationImportModel location, int rowIndex) + { + var validationContext = new FluentValidation.ValidationContext(location) + { + RootContextData = + { + ["RowIndex"] = rowIndex + } + }; + + return _locationImportModelValidator.Validate(validationContext); + } +} \ No newline at end of file diff --git a/api/src/Feature.Locations/Services/LocationParsingResult.cs b/api/src/Feature.Locations/Services/LocationParsingResult.cs new file mode 100644 index 000000000..6265a2f79 --- /dev/null +++ b/api/src/Feature.Locations/Services/LocationParsingResult.cs @@ -0,0 +1,19 @@ +namespace Feature.Locations.Services; + +public abstract record LocationParsingResult +{ + public sealed record Success(List Locations) : LocationParsingResult; + public sealed record Fail(params ValidationResult[] ValidationErrors) : LocationParsingResult + { + public Fail(ValidationFailure validationFailure) : this(new ValidationResult(new[] { validationFailure })) + { + } + + public void Deconstruct(out ValidationResult[] validationErrors) + { + validationErrors = ValidationErrors; + } + } + + private LocationParsingResult() { } +} diff --git a/api/src/Feature.Locations/Specifications/GetLocationByIdSpecification.cs b/api/src/Feature.Locations/Specifications/GetLocationByIdSpecification.cs new file mode 100644 index 000000000..705bba8f0 --- /dev/null +++ b/api/src/Feature.Locations/Specifications/GetLocationByIdSpecification.cs @@ -0,0 +1,10 @@ +namespace Feature.Locations.Specifications; + +public sealed class GetLocationByIdSpecification : Specification, + ISingleResultSpecification +{ + public GetLocationByIdSpecification(Guid electionRoundId, Guid id) + { + Query.Where(location => location.ElectionRoundId == electionRoundId && location.Id == id); + } +} diff --git a/api/src/Feature.Locations/Specifications/GetLocationSpecification.cs b/api/src/Feature.Locations/Specifications/GetLocationSpecification.cs new file mode 100644 index 000000000..31527210d --- /dev/null +++ b/api/src/Feature.Locations/Specifications/GetLocationSpecification.cs @@ -0,0 +1,16 @@ +namespace Feature.Locations.Specifications; + +public sealed class GetLocationSpecification : Specification +{ + public GetLocationSpecification(Guid electionRoundId, string level1, string level2, string level3, string level4, + string level5) + { + Query + .Where(x => x.ElectionRoundId == electionRoundId) + .Where(x => x.Level1 == level1) + .Where(x => x.Level2 == level2) + .Where(x => x.Level3 == level3) + .Where(x => x.Level4 == level4) + .Where(x => x.Level5 == level5); + } +} \ No newline at end of file diff --git a/api/src/Feature.Locations/Specifications/ListLocationsSpecification.cs b/api/src/Feature.Locations/Specifications/ListLocationsSpecification.cs new file mode 100644 index 000000000..760615487 --- /dev/null +++ b/api/src/Feature.Locations/Specifications/ListLocationsSpecification.cs @@ -0,0 +1,20 @@ +using Vote.Monitor.Domain.Specifications; + +namespace Feature.Locations.Specifications; + +public sealed class ListLocationsSpecification : Specification +{ + public ListLocationsSpecification(List.Request request) + { + Query + .Where(x => x.ElectionRoundId == request.ElectionRoundId) + .Where(x => x.Level1 == request.Level1Filter, !string.IsNullOrWhiteSpace(request.Level1Filter)) + .Where(x => x.Level2 == request.Level2Filter, !string.IsNullOrWhiteSpace(request.Level2Filter)) + .Where(x => x.Level3 == request.Level3Filter, !string.IsNullOrWhiteSpace(request.Level3Filter)) + .Where(x => x.Level4 == request.Level4Filter, !string.IsNullOrWhiteSpace(request.Level4Filter)) + .Where(x => x.Level5 == request.Level5Filter, !string.IsNullOrWhiteSpace(request.Level5Filter)) + .ApplyOrdering(request) + .Paginate(request) + .AsNoTracking(); + } +} diff --git a/api/src/Feature.Locations/Specifications/SpecificationExtensions.cs b/api/src/Feature.Locations/Specifications/SpecificationExtensions.cs new file mode 100644 index 000000000..d52e7f637 --- /dev/null +++ b/api/src/Feature.Locations/Specifications/SpecificationExtensions.cs @@ -0,0 +1,86 @@ +using Vote.Monitor.Core.Models; + +namespace Feature.Locations.Specifications; + +public static class SpecificationExtensions +{ + public static ISpecificationBuilder ApplyOrdering( + this ISpecificationBuilder builder, BaseSortPaginatedRequest request) + { + if (string.Equals(request.SortColumnName, nameof(LocationAggregate.Level1), + StringComparison.InvariantCultureIgnoreCase)) + { + return request.IsAscendingSorting + ? builder + .OrderBy(x => x.Level1) + .ThenBy(x => x.Id) + : builder + .OrderByDescending(x => x.Level1) + .ThenBy(x => x.Id); + } + + if (string.Equals(request.SortColumnName, nameof(LocationAggregate.Level2), + StringComparison.InvariantCultureIgnoreCase)) + { + return request.IsAscendingSorting + ? builder + .OrderBy(x => x.Level2) + .ThenBy(x => x.Id) + : builder + .OrderByDescending(x => x.Level2) + .ThenBy(x => x.Id); + } + + if (string.Equals(request.SortColumnName, nameof(LocationAggregate.Level3), + StringComparison.InvariantCultureIgnoreCase)) + { + return request.IsAscendingSorting + ? builder + .OrderBy(x => x.Level3) + .ThenBy(x => x.Id) + : builder + .OrderByDescending(x => x.Level3) + .ThenBy(x => x.Id); + } + + if (string.Equals(request.SortColumnName, nameof(LocationAggregate.Level4), + StringComparison.InvariantCultureIgnoreCase)) + { + return request.IsAscendingSorting + ? builder + .OrderBy(x => x.Level4) + .ThenBy(x => x.Id) + : builder + .OrderByDescending(x => x.Level4) + .ThenBy(x => x.Id); + } + + if (string.Equals(request.SortColumnName, nameof(LocationAggregate.Level5), + StringComparison.InvariantCultureIgnoreCase)) + { + return request.IsAscendingSorting + ? builder + .OrderBy(x => x.Level5) + .ThenBy(x => x.Id) + : builder + .OrderByDescending(x => x.Level5) + .ThenBy(x => x.Id); + } + + if (string.Equals(request.SortColumnName, nameof(LocationAggregate.Tags), + StringComparison.InvariantCultureIgnoreCase)) + { + return request.IsAscendingSorting + ? builder + .OrderBy(x => x.Tags) + .ThenBy(x => x.Id) + : builder + .OrderByDescending(x => x.Tags) + .ThenBy(x => x.Id); + } + + return builder + .OrderBy(x => x.DisplayOrder) + .ThenBy(x => x.Id); + } +} \ No newline at end of file diff --git a/api/src/Feature.Locations/Update/Endpoint.cs b/api/src/Feature.Locations/Update/Endpoint.cs new file mode 100644 index 000000000..34c273865 --- /dev/null +++ b/api/src/Feature.Locations/Update/Endpoint.cs @@ -0,0 +1,41 @@ +using Feature.Locations.Specifications; +using Vote.Monitor.Core.Helpers; + +namespace Feature.Locations.Update; + +public class Endpoint(IRepository repository, + IRepository electionRoundRepository) + : Endpoint, Conflict>> +{ + public override void Configure() + { + Put("/api/election-rounds/{electionRoundId}/locations/{id}"); + DontAutoTag(); + Options(x => x.WithTags("locations")); + Policies(PolicyNames.PlatformAdminsOnly); + } + + public override async Task, Conflict>> ExecuteAsync(Request req, CancellationToken ct) + { + var electionRound = await electionRoundRepository.GetByIdAsync(req.ElectionRoundId, ct); + if (electionRound is null) + { + AddError(r => r.ElectionRoundId, "Election round not found"); + return TypedResults.NotFound(new ProblemDetails(ValidationFailures)); + } + + var location = await repository.SingleOrDefaultAsync(new GetLocationByIdSpecification(req.ElectionRoundId, req.Id), ct); + if (location is null) + { + AddError(r => r.Id, "Location not found."); + return TypedResults.NotFound(new ProblemDetails(ValidationFailures)); + } + + location.UpdateDetails(req.Level1, req.Level2, req.Level3, req.Level4, req.Level5, req.DisplayOrder, req.Tags.ToTagsObject()); + await repository.UpdateAsync(location, ct); + electionRound.UpdateLocationsVersion(); + await electionRoundRepository.UpdateAsync(electionRound, ct); + + return TypedResults.NoContent(); + } +} diff --git a/api/src/Feature.Locations/Update/Request.cs b/api/src/Feature.Locations/Update/Request.cs new file mode 100644 index 000000000..4ee5ee62a --- /dev/null +++ b/api/src/Feature.Locations/Update/Request.cs @@ -0,0 +1,13 @@ +namespace Feature.Locations.Update; +public class Request +{ + public Guid ElectionRoundId { get; set; } + public Guid Id { get; set; } + public string Level1 { get; set; } + public string Level2 { get; set; } + public string Level3 { get; set; } + public string Level4 { get; set; } + public string Level5 { get; set; } + public int DisplayOrder { get; set; } + public Dictionary Tags { get; set; } +} diff --git a/api/src/Feature.Locations/Update/Validator.cs b/api/src/Feature.Locations/Update/Validator.cs new file mode 100644 index 000000000..ede0c5219 --- /dev/null +++ b/api/src/Feature.Locations/Update/Validator.cs @@ -0,0 +1,22 @@ +namespace Feature.Locations.Update; + +public class Validator : Validator +{ + public Validator() + { + RuleFor(x => x.ElectionRoundId).NotEmpty(); + RuleFor(x => x.Id).NotEmpty(); + + RuleFor(x => x.Level1).NotEmpty(); + RuleFor(x => x.Level2).NotEmpty().When(x => !string.IsNullOrWhiteSpace(x.Level3)); + RuleFor(x => x.Level3).NotEmpty().When(x => !string.IsNullOrWhiteSpace(x.Level4)); + RuleFor(x => x.Level4).NotEmpty().When(x => !string.IsNullOrWhiteSpace(x.Level5)); + + RuleFor(x => x.DisplayOrder) + .GreaterThanOrEqualTo(0); + + RuleFor(x => x.Tags) + .Must(filter => { return filter.Keys.All(tag => !string.IsNullOrWhiteSpace(tag)); }) + .When(x => x.Tags != null && x.Tags.Any()); + } +} \ No newline at end of file diff --git a/api/src/Feature.MonitoringObservers/Assign/Endpoint.cs b/api/src/Feature.MonitoringObservers/Assign/Endpoint.cs index 40a68bbbc..5241eb01a 100644 --- a/api/src/Feature.MonitoringObservers/Assign/Endpoint.cs +++ b/api/src/Feature.MonitoringObservers/Assign/Endpoint.cs @@ -96,7 +96,7 @@ public override async Task, NotFound, Conflict> ExecuteAsync(Request re NgoName: ngoName, ElectionRoundDetails: electionRoundName); var email = emailFactory.GenerateEmail(EmailTemplateType.InvitationNewUser, invitationNewUserEmailProps); - jobService.SendEmail(monitoringObserver.Email!, email.Subject, email.Body); + jobService.EnqueueSendEmail(monitoringObserver.Email!, email.Subject, email.Body); } return TypedResults.NoContent(); diff --git a/api/src/Feature.MonitoringObservers/Services/ObserverImportService.cs b/api/src/Feature.MonitoringObservers/Services/ObserverImportService.cs index 8112d847a..0f6131a0b 100644 --- a/api/src/Feature.MonitoringObservers/Services/ObserverImportService.cs +++ b/api/src/Feature.MonitoringObservers/Services/ObserverImportService.cs @@ -117,7 +117,7 @@ public async Task ImportAsync(Guid electionRoundId, Guid ngoId, var email = emailFactory.GenerateEmail(EmailTemplateType.InvitationNewUser, invitationNewUserEmailProps); - jobService.SendEmail(observer.Email, email.Subject, email.Body); + jobService.EnqueueSendEmail(observer.Email, email.Subject, email.Body); } else { @@ -132,7 +132,7 @@ public async Task ImportAsync(Guid electionRoundId, Guid ngoId, var email = emailFactory.GenerateEmail(EmailTemplateType.InvitationExistingUser, invitationExistingUserEmailProps); - jobService.SendEmail(observer.Email, email.Subject, email.Body); + jobService.EnqueueSendEmail(observer.Email, email.Subject, email.Body); } } else @@ -162,7 +162,7 @@ public async Task ImportAsync(Guid electionRoundId, Guid ngoId, ElectionRoundDetails: electionRoundName); var email = emailFactory.GenerateEmail(EmailTemplateType.InvitationNewUser, invitationNewUserEmailProps); - jobService.SendEmail(observer.Email, email.Subject, email.Body); + jobService.EnqueueSendEmail(observer.Email, email.Subject, email.Body); } } diff --git a/api/src/Feature.PollingStation.Information.Form/Upsert/Endpoint.cs b/api/src/Feature.PollingStation.Information.Form/Upsert/Endpoint.cs index d71f963de..149ed1317 100644 --- a/api/src/Feature.PollingStation.Information.Form/Upsert/Endpoint.cs +++ b/api/src/Feature.PollingStation.Information.Form/Upsert/Endpoint.cs @@ -1,7 +1,12 @@ -namespace Feature.PollingStation.Information.Form.Upsert; +using Vote.Monitor.Core.Models; +using Vote.Monitor.Domain.Entities.FormAggregate; -public class Endpoint(IRepository repository, - IRepository electionRoundRepository) : Endpoint, NotFound>> +namespace Feature.PollingStation.Information.Form.Upsert; + +public class Endpoint( + IRepository repository, + IRepository electionRoundRepository) + : Endpoint, NotFound>> { public override void Configure() { @@ -11,30 +16,35 @@ public override void Configure() Policies(PolicyNames.PlatformAdminsOnly); } - public override async Task, NotFound>> ExecuteAsync(Request req, CancellationToken ct) + public override async Task, NotFound>> ExecuteAsync(Request req, + CancellationToken ct) { var formSpecification = new GetPollingStationInformationFormSpecification(req.ElectionRoundId); var form = await repository.FirstOrDefaultAsync(formSpecification, ct); var questions = req.Questions.Select(QuestionsMapper.ToEntity).ToList(); return form is null - ? await AddPollingStationInfoFormAsync(req.ElectionRoundId, req.DefaultLanguage, req.Languages, questions, ct) + ? await AddPollingStationInfoFormAsync(req.ElectionRoundId, req.DefaultLanguage, req.Languages, questions, + ct) : await UpdateForm(form, req.DefaultLanguage, req.Languages, questions, ct); } - private async Task, NotFound>> UpdateForm(PollingStationInfoFormAggregate pollingStationInformationForm, + private async Task, NotFound>> UpdateForm( + PollingStationInfoFormAggregate pollingStationInformationForm, string defaultLanguage, List languages, List questions, CancellationToken ct) { - pollingStationInformationForm.UpdateDetails(defaultLanguage, languages, questions); + pollingStationInformationForm.UpdateDetails("PSI", TranslatedString.New(languages, "PSI"), + TranslatedString.New(languages, "PSI"), FormType.PSI, defaultLanguage, languages, questions); await repository.UpdateAsync(pollingStationInformationForm, ct); return TypedResults.Ok(PollingStationInformationFormModel.FromEntity(pollingStationInformationForm)); } - private async Task, NotFound>> AddPollingStationInfoFormAsync(Guid electionRoundId, + private async Task, NotFound>> AddPollingStationInfoFormAsync( + Guid electionRoundId, string defaultLanguage, List languages, List questions, @@ -46,9 +56,10 @@ private async Task, NotFound>> Ad return TypedResults.NotFound(); } - var pollingStationInformationForm = PollingStationInfoFormAggregate.Create(electionRound, defaultLanguage, languages, questions); + var pollingStationInformationForm = + PollingStationInfoFormAggregate.Create(electionRound, defaultLanguage, languages, questions); await repository.AddAsync(pollingStationInformationForm, ct); return TypedResults.Ok(PollingStationInformationFormModel.FromEntity(pollingStationInformationForm)); } -} +} \ No newline at end of file diff --git a/api/src/Job.Contracts/IJobService.cs b/api/src/Job.Contracts/IJobService.cs index a7a2ef366..b0c9f79bc 100644 --- a/api/src/Job.Contracts/IJobService.cs +++ b/api/src/Job.Contracts/IJobService.cs @@ -2,8 +2,10 @@ public interface IJobService { - void SendEmail(string to, string subject, string body); - void ExportFormSubmissions(Guid electionRoundId, Guid ngoId, Guid exportedDataId); - void ExportQuickReportsSubmissions(Guid electionRoundId, Guid ngoId, Guid exportedDataId); - void ExportPollingStations(Guid electionRoundId, Guid exportedDataId); -} + void EnqueueSendEmail(string to, string subject, string body); + void EnqueueExportFormSubmissions(Guid electionRoundId, Guid ngoId, Guid exportedDataId); + void EnqueueExportQuickReportsSubmissions(Guid electionRoundId, Guid ngoId, Guid exportedDataId); + void EnqueueExportPollingStations(Guid electionRoundId, Guid exportedDataId); + void EnqueueExportCitizenReports(Guid electionRoundId, Guid ngoId, Guid exportedDataId); + void EnqueueExportLocations(Guid electionRoundId, Guid exportedDataId); +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Answer.Module/Aggregators/FormSubmissionsAggregate.cs b/api/src/Vote.Monitor.Answer.Module/Aggregators/FormSubmissionsAggregate.cs index c4484e8e7..441fc7b07 100644 --- a/api/src/Vote.Monitor.Answer.Module/Aggregators/FormSubmissionsAggregate.cs +++ b/api/src/Vote.Monitor.Answer.Module/Aggregators/FormSubmissionsAggregate.cs @@ -8,17 +8,18 @@ namespace Vote.Monitor.Answer.Module.Aggregators; - public record Responder(Guid ResponderId, string FirstName, string LastName, string Email, string PhoneNumber); + public class FormSubmissionsAggregate { public Guid ElectionRoundId { get; } public Guid MonitoringNgoId { get; } public Guid FormId { get; } public string FormCode { get; } - + [JsonConverter(typeof(SmartEnumNameConverter))] public FormType FormType { get; } + public TranslatedString Name { get; } public TranslatedString Description { get; } public string DefaultLanguage { get; } @@ -30,6 +31,7 @@ public class FormSubmissionsAggregate public int SubmissionCount { get; private set; } public int TotalNumberOfQuestionsAnswered { get; private set; } public int TotalNumberOfFlaggedAnswers { get; private set; } + /// /// Aggregated answers per question id /// @@ -61,8 +63,8 @@ public FormSubmissionsAggregate(PollingStationInformationForm form) FormId = form.Id; FormCode = FormType.PSI; FormType = FormType.PSI; - Name = GetName(form.Languages, "PSI"); - Description = GetName(form.Languages, "PSI"); + Name = TranslatedString.New(form.Languages, "PSI"); + Description = TranslatedString.New(form.Languages, "PSI"); Languages = form.Languages; DefaultLanguage = form.DefaultLanguage; @@ -73,21 +75,11 @@ public FormSubmissionsAggregate(PollingStationInformationForm form) .AsReadOnly(); } - private TranslatedString GetName(string[] languages, string value) - { - var translatedString = new TranslatedString(); - foreach (var language in languages) - { - translatedString.Add(language, value); - } - - return translatedString; - } - public FormSubmissionsAggregate AggregateAnswers(FormSubmission formSubmission) { var observer = formSubmission.MonitoringObserver.Observer.ApplicationUser; - _responders.Add(new Responder(formSubmission.MonitoringObserverId, observer.FirstName, observer.LastName, observer.Email, observer.PhoneNumber)); + _responders.Add(new Responder(formSubmission.MonitoringObserverId, observer.FirstName, observer.LastName, + observer.Email, observer.PhoneNumber)); SubmissionCount++; TotalNumberOfFlaggedAnswers += formSubmission.NumberOfFlaggedAnswers; @@ -105,19 +97,27 @@ public FormSubmissionsAggregate AggregateAnswers(FormSubmission formSubmission) return this; } + public FormSubmissionsAggregate AggregateAnswers(PollingStationInformation formSubmission) { var observer = formSubmission.MonitoringObserver.Observer.ApplicationUser; - _responders.Add(new Responder(formSubmission.MonitoringObserverId, observer.FirstName, observer.LastName, observer.Email, observer.PhoneNumber)); + _responders.Add(new Responder(formSubmission.MonitoringObserverId, observer.FirstName, observer.LastName, + observer.Email, observer.PhoneNumber)); SubmissionCount++; + TotalNumberOfFlaggedAnswers += formSubmission.NumberOfFlaggedAnswers; TotalNumberOfQuestionsAnswered += formSubmission.NumberOfQuestionsAnswered; foreach (var answer in formSubmission.Answers) { + if (!Aggregates.ContainsKey(answer.QuestionId)) + { + continue; + } + Aggregates[answer.QuestionId].Aggregate(formSubmission.Id, formSubmission.MonitoringObserverId, answer); } return this; } -} +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Api.Feature.Auth/ForgotPassword/Endpoint.cs b/api/src/Vote.Monitor.Api.Feature.Auth/ForgotPassword/Endpoint.cs index ba04e03a2..bc1f85d4f 100644 --- a/api/src/Vote.Monitor.Api.Feature.Auth/ForgotPassword/Endpoint.cs +++ b/api/src/Vote.Monitor.Api.Feature.Auth/ForgotPassword/Endpoint.cs @@ -42,7 +42,7 @@ public override async Task> ExecuteAsync(Request var emailProps = new ResetPasswordEmailProps(FullName: user.FirstName + " " + user.LastName, CdnUrl: _apiConfig.WebAppUrl, ResetPasswordUrl: passwordResetUrl); var mail = emailFactory.GenerateEmail(EmailTemplateType.ResetPassword, emailProps); - jobService.SendEmail(request.Email, mail.Subject, mail.Body); + jobService.EnqueueSendEmail(request.Email, mail.Subject, mail.Body); return TypedResults.Ok(); } diff --git a/api/src/Vote.Monitor.Api.Feature.PollingStation/Create/Endpoint.cs b/api/src/Vote.Monitor.Api.Feature.PollingStation/Create/Endpoint.cs index 071271c9c..160aee0be 100644 --- a/api/src/Vote.Monitor.Api.Feature.PollingStation/Create/Endpoint.cs +++ b/api/src/Vote.Monitor.Api.Feature.PollingStation/Create/Endpoint.cs @@ -1,4 +1,4 @@ -using Vote.Monitor.Api.Feature.PollingStation.Helpers; +using Vote.Monitor.Core.Helpers; using Vote.Monitor.Core.Services.Security; using Vote.Monitor.Core.Services.Time; diff --git a/api/src/Vote.Monitor.Api.Feature.PollingStation/FetchLevels/Endpoint.cs b/api/src/Vote.Monitor.Api.Feature.PollingStation/FetchLevels/Endpoint.cs index ce74007cc..e989e1b2e 100644 --- a/api/src/Vote.Monitor.Api.Feature.PollingStation/FetchLevels/Endpoint.cs +++ b/api/src/Vote.Monitor.Api.Feature.PollingStation/FetchLevels/Endpoint.cs @@ -29,7 +29,7 @@ public override async Task, NotFound>> ExecuteAsync(Request return TypedResults.NotFound(); } - var cacheKey = $"election-rounds/{request.ElectionRoundId}/nodes/{electionRound.PollingStationsVersion}"; + var cacheKey = $"election-rounds/{request.ElectionRoundId}/polling-station-nodes/{electionRound.PollingStationsVersion}"; var cachedResponse = await memoryCache.GetOrCreateAsync(cacheKey, async (e) => { diff --git a/api/src/Vote.Monitor.Api.Feature.PollingStation/Get/Endpoint.cs b/api/src/Vote.Monitor.Api.Feature.PollingStation/Get/Endpoint.cs index 2caa4d9c8..40e609a7f 100644 --- a/api/src/Vote.Monitor.Api.Feature.PollingStation/Get/Endpoint.cs +++ b/api/src/Vote.Monitor.Api.Feature.PollingStation/Get/Endpoint.cs @@ -1,4 +1,4 @@ -using Vote.Monitor.Api.Feature.PollingStation.Helpers; +using Vote.Monitor.Core.Helpers; namespace Vote.Monitor.Api.Feature.PollingStation.Get; diff --git a/api/src/Vote.Monitor.Api.Feature.PollingStation/Import/Endpoint.cs b/api/src/Vote.Monitor.Api.Feature.PollingStation/Import/Endpoint.cs index 81308b659..342915b22 100644 --- a/api/src/Vote.Monitor.Api.Feature.PollingStation/Import/Endpoint.cs +++ b/api/src/Vote.Monitor.Api.Feature.PollingStation/Import/Endpoint.cs @@ -1,5 +1,5 @@ -using Vote.Monitor.Api.Feature.PollingStation.Helpers; -using Vote.Monitor.Api.Feature.PollingStation.Services; +using Vote.Monitor.Api.Feature.PollingStation.Services; +using Vote.Monitor.Core.Helpers; using Vote.Monitor.Core.Services.Security; using Vote.Monitor.Core.Services.Time; diff --git a/api/src/Vote.Monitor.Api.Feature.PollingStation/List/Endpoint.cs b/api/src/Vote.Monitor.Api.Feature.PollingStation/List/Endpoint.cs index 87b92dae7..78e89b5fa 100644 --- a/api/src/Vote.Monitor.Api.Feature.PollingStation/List/Endpoint.cs +++ b/api/src/Vote.Monitor.Api.Feature.PollingStation/List/Endpoint.cs @@ -1,4 +1,4 @@ -using Vote.Monitor.Api.Feature.PollingStation.Helpers; +using Vote.Monitor.Core.Helpers; using Vote.Monitor.Core.Models; namespace Vote.Monitor.Api.Feature.PollingStation.List; diff --git a/api/src/Vote.Monitor.Api.Feature.PollingStation/Services/PollingStationImportModel.cs b/api/src/Vote.Monitor.Api.Feature.PollingStation/Services/PollingStationImportModel.cs index efbb58d04..df7bd6024 100644 --- a/api/src/Vote.Monitor.Api.Feature.PollingStation/Services/PollingStationImportModel.cs +++ b/api/src/Vote.Monitor.Api.Feature.PollingStation/Services/PollingStationImportModel.cs @@ -1,4 +1,7 @@ -namespace Vote.Monitor.Api.Feature.PollingStation.Services; +using Vote.Monitor.Core.Models; + +namespace Vote.Monitor.Api.Feature.PollingStation.Services; + public class PollingStationImportModel { public int DisplayOrder { get; set; } @@ -10,12 +13,5 @@ public class PollingStationImportModel public string Number { get; set; } public string Address { get; set; } - public List Tags { get; set; } -} - -public class TagImportModel -{ - public string? Name { get; set; } - public string? Value { get; set; } -} +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Api.Feature.PollingStation/Services/PollingStationImportModelMapper.cs b/api/src/Vote.Monitor.Api.Feature.PollingStation/Services/PollingStationImportModelMapper.cs index b41452de9..4f2dc91e3 100644 --- a/api/src/Vote.Monitor.Api.Feature.PollingStation/Services/PollingStationImportModelMapper.cs +++ b/api/src/Vote.Monitor.Api.Feature.PollingStation/Services/PollingStationImportModelMapper.cs @@ -1,4 +1,5 @@ using CsvHelper.Configuration; +using Vote.Monitor.Core.Models; namespace Vote.Monitor.Api.Feature.PollingStation.Services; internal sealed class PollingStationImportModelMapper : ClassMap diff --git a/api/src/Vote.Monitor.Api.Feature.PollingStation/Update/Endpoint.cs b/api/src/Vote.Monitor.Api.Feature.PollingStation/Update/Endpoint.cs index 869203486..127e1f398 100644 --- a/api/src/Vote.Monitor.Api.Feature.PollingStation/Update/Endpoint.cs +++ b/api/src/Vote.Monitor.Api.Feature.PollingStation/Update/Endpoint.cs @@ -1,4 +1,4 @@ -using Vote.Monitor.Api.Feature.PollingStation.Helpers; +using Vote.Monitor.Core.Helpers; namespace Vote.Monitor.Api.Feature.PollingStation.Update; diff --git a/api/src/Vote.Monitor.Api/Dockerfile b/api/src/Vote.Monitor.Api/Dockerfile index 69f5d7cda..d311feea8 100644 --- a/api/src/Vote.Monitor.Api/Dockerfile +++ b/api/src/Vote.Monitor.Api/Dockerfile @@ -42,8 +42,9 @@ COPY ["src/Vote.Monitor.Module.Notifications/Vote.Monitor.Module.Notifications.c COPY ["src/Vote.Monitor.Api.Feature.Observer/Vote.Monitor.Api.Feature.Observer.csproj", "src/Vote.Monitor.Api.Feature.Observer/"] COPY ["src/Feature.Attachments/Feature.Attachments.csproj", "src/Feature.Attachments/"] COPY ["src/Feature.Notes/Feature.Notes.csproj", "src/Feature.Notes/"] -COPY ["src/Vote.Monitor.Api.Feature.PollingStation/Vote.Monitor.Api.Feature.PollingStation.csproj", "src/Vote.Monitor.Api.Feature.PollingStation/"] COPY ["src/Vote.Monitor.Api.Feature.UserPreferences/Vote.Monitor.Api.Feature.UserPreferences.csproj", "src/Vote.Monitor.Api.Feature.UserPreferences/"] +COPY ["src/Vote.Monitor.Api.Feature.PollingStation/Vote.Monitor.Api.Feature.PollingStation.csproj", "src/Vote.Monitor.Api.Feature.PollingStation/"] +COPY ["src/Feature.Locations/Feature.Locations.csproj", "src/Feature.Locations/"] RUN dotnet restore "src/Vote.Monitor.Api/Vote.Monitor.Api.csproj" COPY . . WORKDIR "/src/src/Vote.Monitor.Api" diff --git a/api/src/Vote.Monitor.Api/Program.cs b/api/src/Vote.Monitor.Api/Program.cs index 111daeb66..93cf0c032 100644 --- a/api/src/Vote.Monitor.Api/Program.cs +++ b/api/src/Vote.Monitor.Api/Program.cs @@ -38,6 +38,7 @@ using Feature.DataExport; using Feature.Feedback; using Feature.ImportErrors; +using Feature.Locations; using Feature.Monitoring; using Feature.Statistics; using Vote.Monitor.Domain.Entities.FormSubmissionAggregate; @@ -152,6 +153,7 @@ builder.Services.AddCitizenReportsFeature(); builder.Services.AddCitizenReportsNotesFeature(); builder.Services.AddCitizenReportsAttachmentsFeature(); +builder.Services.AddLocationsFeature(builder.Configuration.GetSection(LocationsFeatureInstaller.SectionKey)); builder.Services.AddAuthorization(); diff --git a/api/src/Vote.Monitor.Api/Vote.Monitor.Api.csproj b/api/src/Vote.Monitor.Api/Vote.Monitor.Api.csproj index 8475ab9f6..233202bed 100644 --- a/api/src/Vote.Monitor.Api/Vote.Monitor.Api.csproj +++ b/api/src/Vote.Monitor.Api/Vote.Monitor.Api.csproj @@ -48,6 +48,7 @@ + diff --git a/api/src/Vote.Monitor.Api/appsettings.json b/api/src/Vote.Monitor.Api/appsettings.json index a7ae5013a..b556b2e54 100644 --- a/api/src/Vote.Monitor.Api/appsettings.json +++ b/api/src/Vote.Monitor.Api/appsettings.json @@ -104,5 +104,10 @@ }, "Statistics": { "ApiKey": "" + }, + "LocationsFeatureConfig": { + "ParserConfig": { + "MaxParserErrorsReturned": 100 + } } } diff --git a/api/src/Vote.Monitor.Core/CoreServicesInstaller.cs b/api/src/Vote.Monitor.Core/CoreServicesInstaller.cs index 38637c9cb..4783fffdc 100644 --- a/api/src/Vote.Monitor.Core/CoreServicesInstaller.cs +++ b/api/src/Vote.Monitor.Core/CoreServicesInstaller.cs @@ -41,10 +41,10 @@ public static IServiceCollection AddCoreServices(this IServiceCollection service .UseSimpleAssemblyNameTypeSerializer() .UseRecommendedSerializerSettings() .UsePostgreSqlStorage(c => - c.UseNpgsqlConnection(configuration.GetNpgsqlConnectionString("HangfireConnectionConfig")), new PostgreSqlStorageOptions { PrepareSchemaIfNecessary = false }); + c.UseNpgsqlConnection(configuration.GetNpgsqlConnectionString("HangfireConnectionConfig")), + new PostgreSqlStorageOptions { PrepareSchemaIfNecessary = false }); config.UseSerilogLogProvider(); - }); services.AddTransient(); @@ -61,21 +61,28 @@ public static IServiceCollection AddCoreServices(this IServiceCollection service internal class NoopJobService : IJobService { - public void SendEmail(string to, string subject, string body) + public void EnqueueSendEmail(string to, string subject, string body) { } - public void ExportFormSubmissions(Guid electionRoundId, Guid ngoId, Guid exportedDataId) + public void EnqueueExportFormSubmissions(Guid electionRoundId, Guid ngoId, Guid exportedDataId) { } - public void ExportQuickReportsSubmissions(Guid electionRoundId, Guid ngoId, Guid exportedDataId) + public void EnqueueExportQuickReportsSubmissions(Guid electionRoundId, Guid ngoId, Guid exportedDataId) { } - public void ExportPollingStations(Guid electionRoundId, Guid exportedDataId) + public void EnqueueExportPollingStations(Guid electionRoundId, Guid exportedDataId) + { + } + + public void EnqueueExportCitizenReports(Guid electionRoundId, Guid ngoId, Guid exportedDataId) { } - } -} + public void EnqueueExportLocations(Guid electionRoundId, Guid exportedDataId) + { + } + } +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Api.Feature.PollingStation/Helpers/TagHelpers.cs b/api/src/Vote.Monitor.Core/Helpers/TagHelpers.cs similarity index 83% rename from api/src/Vote.Monitor.Api.Feature.PollingStation/Helpers/TagHelpers.cs rename to api/src/Vote.Monitor.Core/Helpers/TagHelpers.cs index 50b4110d6..a754bea70 100644 --- a/api/src/Vote.Monitor.Api.Feature.PollingStation/Helpers/TagHelpers.cs +++ b/api/src/Vote.Monitor.Core/Helpers/TagHelpers.cs @@ -1,6 +1,7 @@ -using Vote.Monitor.Api.Feature.PollingStation.Services; +using System.Text.Json; +using Vote.Monitor.Core.Models; -namespace Vote.Monitor.Api.Feature.PollingStation.Helpers; +namespace Vote.Monitor.Core.Helpers; public static class TagHelpers { diff --git a/api/src/Vote.Monitor.Core/Models/TagImportModel.cs b/api/src/Vote.Monitor.Core/Models/TagImportModel.cs new file mode 100644 index 000000000..d5b21f9bc --- /dev/null +++ b/api/src/Vote.Monitor.Core/Models/TagImportModel.cs @@ -0,0 +1,7 @@ +namespace Vote.Monitor.Core.Models; + +public class TagImportModel +{ + public string? Name { get; set; } + public string? Value { get; set; } +} diff --git a/api/src/Vote.Monitor.Core/Models/TranslatedString.cs b/api/src/Vote.Monitor.Core/Models/TranslatedString.cs index 7126104f8..39f50de39 100644 --- a/api/src/Vote.Monitor.Core/Models/TranslatedString.cs +++ b/api/src/Vote.Monitor.Core/Models/TranslatedString.cs @@ -51,4 +51,17 @@ public void RemoveTranslation(string languageCode) Remove(languageCode); } } + + public static TranslatedString New(IEnumerable languages, string value) + { + var languagesArray = languages.ToArray(); + + var translatedString = new TranslatedString(); + foreach (var language in languagesArray) + { + translatedString.Add(language, value); + } + + return translatedString; + } } \ No newline at end of file diff --git a/api/src/Vote.Monitor.Core/Services/Csv/CsvReader.cs b/api/src/Vote.Monitor.Core/Services/Csv/CsvReader.cs index 8bc4c0e2f..c084dfcc3 100644 --- a/api/src/Vote.Monitor.Core/Services/Csv/CsvReader.cs +++ b/api/src/Vote.Monitor.Core/Services/Csv/CsvReader.cs @@ -7,8 +7,13 @@ public class CsvReader : ICsvReader { public IEnumerable Read(Stream stream) where TMap : ClassMap { + var config = new CsvConfiguration(CultureInfo.InvariantCulture) + { + PrepareHeaderForMatch = args => args.Header.ToLower(), + }; + using var reader = new StreamReader(stream); - using var csv = new CsvHelper.CsvReader(reader, CultureInfo.InvariantCulture); + using var csv = new CsvHelper.CsvReader(reader, config); csv.Context.RegisterClassMap(); @@ -17,9 +22,14 @@ public IEnumerable Read(Stream stream) where TMap : ClassMap public IEnumerable Read(Stream stream) { + var config = new CsvConfiguration(CultureInfo.InvariantCulture) + { + PrepareHeaderForMatch = args => args.Header.ToLower(), + }; + using var reader = new StreamReader(stream); - using var csv = new CsvHelper.CsvReader(reader, CultureInfo.InvariantCulture); + using var csv = new CsvHelper.CsvReader(reader, config); return csv.GetRecords().ToList(); } -} +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Core/Services/Hangfire/HangfireJobService.cs b/api/src/Vote.Monitor.Core/Services/Hangfire/HangfireJobService.cs index 6ad44fd19..7fe53c226 100644 --- a/api/src/Vote.Monitor.Core/Services/Hangfire/HangfireJobService.cs +++ b/api/src/Vote.Monitor.Core/Services/Hangfire/HangfireJobService.cs @@ -5,23 +5,38 @@ namespace Vote.Monitor.Core.Services.Hangfire; public class HangfireJobService(IBackgroundJobClient backgroundJobClient) : IJobService { - public void SendEmail(string to, string subject, string body) + public void EnqueueSendEmail(string to, string subject, string body) { backgroundJobClient.Enqueue(job => job.SendAsync(to, subject, body)); } - public void ExportFormSubmissions(Guid electionRoundId, Guid ngoId, Guid exportedDataId) + public void EnqueueExportFormSubmissions(Guid electionRoundId, Guid ngoId, Guid exportedDataId) { - backgroundJobClient.Enqueue(job => job.Run(electionRoundId, ngoId, exportedDataId, CancellationToken.None)); + backgroundJobClient.Enqueue(job => + job.Run(electionRoundId, ngoId, exportedDataId, CancellationToken.None)); } - public void ExportQuickReportsSubmissions(Guid electionRoundId, Guid ngoId, Guid exportedDataId) + public void EnqueueExportQuickReportsSubmissions(Guid electionRoundId, Guid ngoId, Guid exportedDataId) { - backgroundJobClient.Enqueue(job => job.Run(electionRoundId, ngoId, exportedDataId, CancellationToken.None)); + backgroundJobClient.Enqueue(job => + job.Run(electionRoundId, ngoId, exportedDataId, CancellationToken.None)); } - public void ExportPollingStations(Guid electionRoundId, Guid exportedDataId) + public void EnqueueExportPollingStations(Guid electionRoundId, Guid exportedDataId) { - backgroundJobClient.Enqueue(job => job.Run(electionRoundId, exportedDataId, CancellationToken.None)); + backgroundJobClient.Enqueue(job => + job.Run(electionRoundId, exportedDataId, CancellationToken.None)); } -} + + public void EnqueueExportCitizenReports(Guid electionRoundId, Guid ngoId, Guid exportedDataId) + { + backgroundJobClient.Enqueue(job => + job.Run(electionRoundId, ngoId, exportedDataId, CancellationToken.None)); + } + + public void EnqueueExportLocations(Guid electionRoundId, Guid exportedDataId) + { + backgroundJobClient.Enqueue(job => + job.Run(electionRoundId, exportedDataId, CancellationToken.None)); + } +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Core/Services/Hangfire/IExportCitizenReportsJob.cs b/api/src/Vote.Monitor.Core/Services/Hangfire/IExportCitizenReportsJob.cs new file mode 100644 index 000000000..67702f63e --- /dev/null +++ b/api/src/Vote.Monitor.Core/Services/Hangfire/IExportCitizenReportsJob.cs @@ -0,0 +1,6 @@ +namespace Vote.Monitor.Core.Services.Hangfire; + +public interface IExportCitizenReportsJob +{ + Task Run(Guid electionRoundId, Guid ngoId, Guid exportedDataId, CancellationToken ct); +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Core/Services/Hangfire/IExportLocationsJob.cs b/api/src/Vote.Monitor.Core/Services/Hangfire/IExportLocationsJob.cs new file mode 100644 index 000000000..6fd01530b --- /dev/null +++ b/api/src/Vote.Monitor.Core/Services/Hangfire/IExportLocationsJob.cs @@ -0,0 +1,6 @@ +namespace Vote.Monitor.Core.Services.Hangfire; + +public interface IExportLocationsJob +{ + Task Run(Guid electionRoundId, Guid exportedDataId, CancellationToken ct); +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Core/Services/Hangfire/IExportPollingStationsJob.cs b/api/src/Vote.Monitor.Core/Services/Hangfire/IExportPollingStationsJob.cs index a3c574b47..ebb4c3ca0 100644 --- a/api/src/Vote.Monitor.Core/Services/Hangfire/IExportPollingStationsJob.cs +++ b/api/src/Vote.Monitor.Core/Services/Hangfire/IExportPollingStationsJob.cs @@ -3,4 +3,4 @@ public interface IExportPollingStationsJob { Task Run(Guid electionRoundId, Guid exportedDataId, CancellationToken ct); -} +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Domain/Entities/CitizenReportAggregate/CitizenReport.cs b/api/src/Vote.Monitor.Domain/Entities/CitizenReportAggregate/CitizenReport.cs index 4d646e7ca..6326baced 100644 --- a/api/src/Vote.Monitor.Domain/Entities/CitizenReportAggregate/CitizenReport.cs +++ b/api/src/Vote.Monitor.Domain/Entities/CitizenReportAggregate/CitizenReport.cs @@ -2,6 +2,7 @@ using Vote.Monitor.Domain.Entities.CitizenReportNoteAggregate; using Vote.Monitor.Domain.Entities.FormAggregate; using Vote.Monitor.Domain.Entities.FormAnswerBase.Answers; +using Vote.Monitor.Domain.Entities.LocationAggregate; namespace Vote.Monitor.Domain.Entities.CitizenReportAggregate; @@ -21,11 +22,14 @@ public class CitizenReport : AuditableBaseEntity, IAggregateRoot private readonly List _attachments = new(); public virtual IReadOnlyList Attachments => _attachments.ToList().AsReadOnly(); + public Guid LocationId { get; private set; } + public Location Location { get; private set; } private CitizenReport( Guid id, ElectionRound electionRound, Form form, + Location location, List answers, int numberOfQuestionsAnswered, int numberOfFlaggedAnswers) : base(id) @@ -38,16 +42,19 @@ private CitizenReport( NumberOfQuestionsAnswered = numberOfQuestionsAnswered; NumberOfFlaggedAnswers = numberOfFlaggedAnswers; FollowUpStatus = CitizenReportFollowUpStatus.NotApplicable; + Location = location; + LocationId = location.Id; } internal static CitizenReport Create( Guid id, ElectionRound electionRound, Form form, + Location location, List answers, int numberOfQuestionAnswered, int numberOfFlaggedAnswers) => - new(id, electionRound, form, answers, numberOfQuestionAnswered, numberOfFlaggedAnswers); + new(id, electionRound, form, location, answers, numberOfQuestionAnswered, numberOfFlaggedAnswers); internal void UpdateAnswers(int numberOfQuestionsAnswered, int numberOfFlaggedAnswers, IEnumerable answers) diff --git a/api/src/Vote.Monitor.Domain/Entities/ElectionRoundAggregate/ElectionRound.cs b/api/src/Vote.Monitor.Domain/Entities/ElectionRoundAggregate/ElectionRound.cs index 0b3dd697c..01b57751e 100644 --- a/api/src/Vote.Monitor.Domain/Entities/ElectionRoundAggregate/ElectionRound.cs +++ b/api/src/Vote.Monitor.Domain/Entities/ElectionRoundAggregate/ElectionRound.cs @@ -22,6 +22,7 @@ internal ElectionRound() public virtual IReadOnlyList MonitoringNgos => _monitoringNgos.ToList().AsReadOnly(); public Guid PollingStationsVersion { get; private set; } + public Guid LocationsVersion { get; private set; } public bool CitizenReportingEnabled { get; private set; } public Guid? MonitoringNgoForCitizenReportingId { get; private set; } @@ -38,6 +39,7 @@ public ElectionRound(Guid countryId, CountryId = countryId; Status = ElectionRoundStatus.NotStarted; PollingStationsVersion = Guid.NewGuid(); + LocationsVersion = Guid.NewGuid(); } internal ElectionRound(Guid id, @@ -103,6 +105,10 @@ public void UpdatePollingStationsVersion() { PollingStationsVersion = Guid.NewGuid(); } + public void UpdateLocationsVersion() + { + PollingStationsVersion = Guid.NewGuid(); + } public void EnableCitizenReporting(MonitoringNgo monitoringNgo) { diff --git a/api/src/Vote.Monitor.Domain/Entities/ExportedDataAggregate/ExportedDataType.cs b/api/src/Vote.Monitor.Domain/Entities/ExportedDataAggregate/ExportedDataType.cs index a9aa8de57..a2dc74887 100644 --- a/api/src/Vote.Monitor.Domain/Entities/ExportedDataAggregate/ExportedDataType.cs +++ b/api/src/Vote.Monitor.Domain/Entities/ExportedDataAggregate/ExportedDataType.cs @@ -8,6 +8,7 @@ public sealed class ExportedDataType : SmartEnum public static readonly ExportedDataType QuickReports = new(nameof(QuickReports), nameof(QuickReports)); public static readonly ExportedDataType PollingStations = new(nameof(PollingStations), nameof(PollingStations)); public static readonly ExportedDataType CitizenReports = new(nameof(CitizenReports), nameof(CitizenReports)); + public static readonly ExportedDataType Locations = new(nameof(Locations), nameof(Locations)); /// Gets an item associated with the specified value. Parses SmartEnum when used as query params /// this issue diff --git a/api/src/Vote.Monitor.Domain/Entities/FormAggregate/Form.cs b/api/src/Vote.Monitor.Domain/Entities/FormAggregate/Form.cs index b60622575..1b21ecc9e 100644 --- a/api/src/Vote.Monitor.Domain/Entities/FormAggregate/Form.cs +++ b/api/src/Vote.Monitor.Domain/Entities/FormAggregate/Form.cs @@ -2,32 +2,21 @@ using FluentValidation; using Vote.Monitor.Core.Models; using Vote.Monitor.Domain.Entities.CitizenReportAggregate; -using Vote.Monitor.Domain.Entities.FormAnswerBase.Answers; using Vote.Monitor.Domain.Entities.FormAnswerBase; +using Vote.Monitor.Domain.Entities.FormAnswerBase.Answers; +using Vote.Monitor.Domain.Entities.FormBase; using Vote.Monitor.Domain.Entities.FormBase.Questions; using Vote.Monitor.Domain.Entities.FormSubmissionAggregate; +using Vote.Monitor.Domain.Entities.LocationAggregate; using Vote.Monitor.Domain.Entities.MonitoringNgoAggregate; using Vote.Monitor.Domain.Entities.MonitoringObserverAggregate; namespace Vote.Monitor.Domain.Entities.FormAggregate; -public class Form : AuditableBaseEntity, IAggregateRoot +public class Form : BaseForm { - public Guid ElectionRoundId { get; set; } - public ElectionRound ElectionRound { get; set; } public Guid MonitoringNgoId { get; set; } public MonitoringNgo MonitoringNgo { get; set; } - public FormType FormType { get; private set; } - public string Code { get; private set; } - public TranslatedString Name { get; private set; } - public TranslatedString Description { get; private set; } - public FormStatus Status { get; private set; } - public string DefaultLanguage { get; private set; } - public string[] Languages { get; private set; } = []; - public int NumberOfQuestions { get; private set; } - - public LanguagesTranslationStatus LanguagesTranslationStatus { get; private set; } = new(); - public IReadOnlyList Questions { get; private set; } = new List().AsReadOnly(); private Form( ElectionRound electionRound, @@ -38,10 +27,10 @@ private Form( TranslatedString description, string defaultLanguage, IEnumerable languages, - IEnumerable questions) : this(electionRound.Id, monitoringNgo.Id, formType, code, name, + IEnumerable questions) : base(electionRound, formType, code, name, description, defaultLanguage, languages, questions) { - ElectionRound = electionRound; + MonitoringNgoId = monitoringNgo.Id; MonitoringNgo = monitoringNgo; } @@ -54,40 +43,17 @@ private Form( TranslatedString description, string defaultLanguage, IEnumerable languages, - IEnumerable questions) : base(Guid.NewGuid()) + IEnumerable questions) : base( + electionRoundId, + formType, + code, + name, + description, + defaultLanguage, + languages, + questions) { - ElectionRoundId = electionRoundId; MonitoringNgoId = monitoringNgoId; - - FormType = formType; - Code = code; - Name = name; - Description = description; - DefaultLanguage = defaultLanguage; - Languages = languages.ToArray(); - Status = FormStatus.Drafted; - Questions = questions.ToList().AsReadOnly(); - NumberOfQuestions = Questions.Count; - LanguagesTranslationStatus = ComputeLanguagesTranslationStatus(Questions, defaultLanguage, Languages); - } - - private LanguagesTranslationStatus ComputeLanguagesTranslationStatus(IReadOnlyList questions, - string defaultLanguage, string[] languages) - { - var languagesTranslationStatus = new LanguagesTranslationStatus(); - - foreach (var languageCode in languages) - { - var status = - Questions.Any(x => - x.GetTranslationStatus(defaultLanguage, languageCode) == TranslationStatus.MissingTranslations) - ? TranslationStatus.MissingTranslations - : TranslationStatus.Translated; - - languagesTranslationStatus.AddOrUpdateTranslationStatus(languageCode, status); - } - - return languagesTranslationStatus; } [JsonConstructor] @@ -102,19 +68,10 @@ public Form(Guid id, string defaultLanguage, string[] languages, int numberOfQuestions, - LanguagesTranslationStatus languagesTranslationStatus) : base(id) + LanguagesTranslationStatus languagesTranslationStatus) : base(id, electionRoundId, formType, code, name, + description, status, defaultLanguage, languages, numberOfQuestions, languagesTranslationStatus) { - ElectionRoundId = electionRoundId; MonitoringNgoId = monitoringNgoId; - FormType = formType; - Code = code; - Name = name; - Description = description; - Status = status; - DefaultLanguage = defaultLanguage; - Languages = languages; - NumberOfQuestions = numberOfQuestions; - LanguagesTranslationStatus = languagesTranslationStatus; } public static Form Create( @@ -141,49 +98,8 @@ public static Form Create( IEnumerable questions) => new(electionRoundId, monitoringNgoId, formType, code, name, description, defaultLanguage, languages, questions); - public PublishResult Publish() - { - var validator = new FormValidator(); - var validationResult = validator.Validate(this); - - if (!validationResult.IsValid) - { - return new PublishResult.InvalidForm(validationResult); - } - - Status = FormStatus.Published; - - return new PublishResult.Published(); - } - - public void Draft() - { - Status = FormStatus.Drafted; - } - - public void Obsolete() - { - Status = FormStatus.Obsolete; - } - - public void UpdateDetails(string code, - TranslatedString name, - TranslatedString description, - FormType formType, - string defaultLanguage, - IEnumerable languages, - IEnumerable questions) - { - Code = code; - Name = name; - Description = description; - FormType = formType; - DefaultLanguage = defaultLanguage; - Languages = languages.ToArray(); - Questions = questions.ToList().AsReadOnly(); - NumberOfQuestions = Questions.Count; - LanguagesTranslationStatus = ComputeLanguagesTranslationStatus(Questions, defaultLanguage, Languages); - } + public Form Duplicate() => + new(ElectionRoundId, MonitoringNgoId, FormType, Code, Name, Description, DefaultLanguage, Languages, Questions); public FormSubmission CreateFormSubmission( PollingStation pollingStation, @@ -195,8 +111,8 @@ public FormSubmission CreateFormSubmission( return FormSubmission.Create(ElectionRound, pollingStation, monitoringObserver, this, [], 0, 0); } - var numberOfQuestionAnswered = CountNumberOfQuestionsAnswered(answers); - var numberOfFlaggedAnswers = CountNumberOfFlaggedAnswers(answers); + var numberOfQuestionAnswered = AnswersHelpers.CountNumberOfQuestionsAnswered(Questions, answers); + var numberOfFlaggedAnswers = AnswersHelpers.CountNumberOfFlaggedAnswers(Questions, answers); var validationResult = AnswersValidator.GetValidationResults(answers, Questions); @@ -209,123 +125,15 @@ public FormSubmission CreateFormSubmission( numberOfQuestionAnswered, numberOfFlaggedAnswers); } - public CitizenReport CreateCitizenReport(Guid citizenReportId, List? answers) - { - if (answers == null) - { - return CitizenReport.Create(citizenReportId, ElectionRound, this, [], 0, 0); - } - - var numberOfQuestionAnswered = CountNumberOfQuestionsAnswered(answers); - var numberOfFlaggedAnswers = CountNumberOfFlaggedAnswers(answers); - - var validationResult = AnswersValidator.GetValidationResults(answers, Questions); - - if (!validationResult.IsValid) - { - throw new ValidationException(validationResult.Errors); - } - - return CitizenReport.Create(citizenReportId, ElectionRound, this, answers, numberOfQuestionAnswered, numberOfFlaggedAnswers); - } - - private int CountNumberOfFlaggedAnswers(List answers) - { - var singleSelectQuestions = - Questions - .OfType() - .ToList(); - - var multiSelectQuestions = - Questions - .OfType() - .ToList(); - - int flaggedAnswers = 0; - foreach (var singleSelectAnswer in answers.OfType()) - { - var option = singleSelectQuestions - .FirstOrDefault(x => x.Id == singleSelectAnswer.QuestionId) - ?.Options - ?.FirstOrDefault(x => x.Id == singleSelectAnswer.Selection.OptionId); - - // Just in case - if (option is null) - { - continue; - } - - if (option.IsFlagged) - { - flaggedAnswers++; - } - } - - foreach (var multiSelectAnswer in answers.OfType()) - { - var options = multiSelectQuestions - .FirstOrDefault(x => x.Id == multiSelectAnswer.QuestionId) - ?.Options - ?.Where(x => multiSelectAnswer.Selection.Select(x => x.OptionId).Contains(x.Id)); - - // Just in case - if (options is null) - { - continue; - } - - flaggedAnswers += options.Count(x => x.IsFlagged); - } - - return flaggedAnswers; - } - - private int CountNumberOfQuestionsAnswered(List answers) - { - var questionIds = Questions.Select(x => x.Id).ToList(); - - return answers.Count(x => questionIds.Contains(x.QuestionId)); - } - - public FormSubmission FillIn(FormSubmission submission, List? answers) - { - if (answers == null) - { - return submission; - } - - if (!answers.Any()) - { - submission.ClearAnswers(); - return submission; - } - - var validationResult = AnswersValidator.GetValidationResults(answers, Questions); - - if (!validationResult.IsValid) - { - throw new ValidationException(validationResult.Errors); - } - - var numberOfQuestionsAnswered = CountNumberOfQuestionsAnswered(answers); - var numberOfFlaggedAnswers = CountNumberOfFlaggedAnswers(answers); - - submission.UpdateAnswers(numberOfQuestionsAnswered, numberOfFlaggedAnswers, answers); - - return submission; - } - public CitizenReport FillIn(CitizenReport citizenReport, List? answers) + public CitizenReport CreateCitizenReport(Guid citizenReportId, Location location, List? answers) { if (answers == null) { - return citizenReport; + return CitizenReport.Create(citizenReportId, ElectionRound, this, location, [], 0, 0); } - if (!answers.Any()) - { - citizenReport.ClearAnswers(); - return citizenReport; - } + var numberOfQuestionAnswered = AnswersHelpers.CountNumberOfQuestionsAnswered(Questions, answers); + var numberOfFlaggedAnswers = AnswersHelpers.CountNumberOfFlaggedAnswers(Questions, answers); var validationResult = AnswersValidator.GetValidationResults(answers, Questions); @@ -334,82 +142,13 @@ public CitizenReport FillIn(CitizenReport citizenReport, List? answe throw new ValidationException(validationResult.Errors); } - var numberOfQuestionsAnswered = CountNumberOfQuestionsAnswered(answers); - var numberOfFlaggedAnswers = CountNumberOfFlaggedAnswers(answers); - - citizenReport.UpdateAnswers(numberOfQuestionsAnswered, numberOfFlaggedAnswers, answers); - - return citizenReport; + return CitizenReport.Create(citizenReportId, ElectionRound, this, location, answers, numberOfQuestionAnswered, + numberOfFlaggedAnswers); } - public void AddTranslations(string[] languageCodes) - { - var newLanguages = languageCodes.Except(Languages); - Languages = Languages.Union(languageCodes).ToArray(); - - foreach (var languageCode in newLanguages) - { - Description.AddTranslation(languageCode); - Name.AddTranslation(languageCode); - - foreach (var question in Questions) - { - question.AddTranslation(languageCode); - } - } - - LanguagesTranslationStatus = ComputeLanguagesTranslationStatus(Questions, DefaultLanguage, Languages); - } - - public bool HasTranslation(string languageCode) - { - return Languages.Contains(languageCode); - } - - public void SetDefaultLanguage(string languageCode) - { - if (!HasTranslation(languageCode)) - { - throw new ArgumentException("Form does not have translations for language code"); - } - - DefaultLanguage = languageCode; - - LanguagesTranslationStatus = ComputeLanguagesTranslationStatus(Questions, DefaultLanguage, Languages); - } - - public void RemoveTranslation(string languageCode) - { - bool hasLanguageCode = languageCode.Contains(languageCode); - - if (!hasLanguageCode) - { - return; - } - - if (DefaultLanguage == languageCode) - { - throw new ArgumentException("Cannot remove default language"); - } - - Languages = Languages.Except([languageCode]).ToArray(); - Description.RemoveTranslation(languageCode); - Name.RemoveTranslation(languageCode); - - foreach (var question in Questions) - { - question.RemoveTranslation(languageCode); - } - - LanguagesTranslationStatus = ComputeLanguagesTranslationStatus(Questions, DefaultLanguage, Languages); - } - - - public Form Duplicate() => - new(ElectionRoundId, MonitoringNgoId, FormType, Code, Name, Description, DefaultLanguage, Languages, Questions); #pragma warning disable CS8618 // Required by Entity Framework - private Form() + private Form() : base() { } #pragma warning restore CS8618 diff --git a/api/src/Vote.Monitor.Domain/Entities/FormAggregate/FormValidator.cs b/api/src/Vote.Monitor.Domain/Entities/FormAggregate/FormValidator.cs index a5133d377..1104b52f9 100644 --- a/api/src/Vote.Monitor.Domain/Entities/FormAggregate/FormValidator.cs +++ b/api/src/Vote.Monitor.Domain/Entities/FormAggregate/FormValidator.cs @@ -1,11 +1,12 @@ using FastEndpoints; using FluentValidation; using Vote.Monitor.Core.Validation; +using Vote.Monitor.Domain.Entities.FormBase; using Vote.Monitor.Domain.Entities.FormBase.Validation; namespace Vote.Monitor.Domain.Entities.FormAggregate; -public class FormValidator : Validator
+public class FormValidator : Validator { public FormValidator() { @@ -22,4 +23,4 @@ public FormValidator() v.Add(new RatingQuestionValidator()); }); } -} +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Domain/Entities/FormBase/AnswersHelpers.cs b/api/src/Vote.Monitor.Domain/Entities/FormBase/AnswersHelpers.cs new file mode 100644 index 000000000..c7c568797 --- /dev/null +++ b/api/src/Vote.Monitor.Domain/Entities/FormBase/AnswersHelpers.cs @@ -0,0 +1,92 @@ +using Vote.Monitor.Core.Models; +using Vote.Monitor.Domain.Entities.FormAnswerBase.Answers; +using Vote.Monitor.Domain.Entities.FormBase.Questions; + +namespace Vote.Monitor.Domain.Entities.FormBase; + +public class AnswersHelpers +{ + public static LanguagesTranslationStatus ComputeLanguagesTranslationStatus(IEnumerable questions, + string defaultLanguage, IEnumerable languages) + { + var questionsArray = questions.ToArray(); + var languagesArray = languages.ToArray(); + + var languagesTranslationStatus = new LanguagesTranslationStatus(); + + foreach (var languageCode in languagesArray) + { + var status = + questionsArray.Any(x => + x.GetTranslationStatus(defaultLanguage, languageCode) == TranslationStatus.MissingTranslations) + ? TranslationStatus.MissingTranslations + : TranslationStatus.Translated; + + languagesTranslationStatus.AddOrUpdateTranslationStatus(languageCode, status); + } + + return languagesTranslationStatus; + } + + + public static int CountNumberOfFlaggedAnswers(IEnumerable questions, IEnumerable answers) + { + var questionsArray = questions.ToArray(); + var answersArray = answers.ToArray(); + + var singleSelectQuestions = + questionsArray + .OfType() + .ToList(); + + var multiSelectQuestions = + questionsArray + .OfType() + .ToList(); + + int flaggedAnswers = 0; + foreach (var singleSelectAnswer in answersArray.OfType()) + { + var option = singleSelectQuestions + .FirstOrDefault(x => x.Id == singleSelectAnswer.QuestionId) + ?.Options + ?.FirstOrDefault(x => x.Id == singleSelectAnswer.Selection.OptionId); + + // Just in case + if (option is null) + { + continue; + } + + if (option.IsFlagged) + { + flaggedAnswers++; + } + } + + foreach (var multiSelectAnswer in answersArray.OfType()) + { + var options = multiSelectQuestions + .FirstOrDefault(x => x.Id == multiSelectAnswer.QuestionId) + ?.Options + ?.Where(x => multiSelectAnswer.Selection.Select(o => o.OptionId).Contains(x.Id)); + + // Just in case + if (options is null) + { + continue; + } + + flaggedAnswers += options.Count(x => x.IsFlagged); + } + + return flaggedAnswers; + } + + public static int CountNumberOfQuestionsAnswered(IEnumerable questions, List answers) + { + var questionIds = questions.Select(x => x.Id).ToList(); + + return answers.Count(x => questionIds.Contains(x.QuestionId)); + } +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Domain/Entities/FormBase/BaseForm.cs b/api/src/Vote.Monitor.Domain/Entities/FormBase/BaseForm.cs new file mode 100644 index 000000000..9a8638464 --- /dev/null +++ b/api/src/Vote.Monitor.Domain/Entities/FormBase/BaseForm.cs @@ -0,0 +1,269 @@ +using FluentValidation; +using Newtonsoft.Json; +using Vote.Monitor.Core.Models; +using Vote.Monitor.Domain.Entities.CitizenReportAggregate; +using Vote.Monitor.Domain.Entities.FormAggregate; +using Vote.Monitor.Domain.Entities.FormAnswerBase; +using Vote.Monitor.Domain.Entities.FormAnswerBase.Answers; +using Vote.Monitor.Domain.Entities.FormBase.Questions; +using Vote.Monitor.Domain.Entities.FormSubmissionAggregate; +using Vote.Monitor.Domain.Entities.PollingStationInfoAggregate; + +namespace Vote.Monitor.Domain.Entities.FormBase; + +public class BaseForm : AuditableBaseEntity, IAggregateRoot +{ + public Guid ElectionRoundId { get; set; } + public ElectionRound ElectionRound { get; set; } + public FormType FormType { get; private set; } + public string Code { get; private set; } + public TranslatedString Name { get; private set; } + public TranslatedString Description { get; private set; } + public FormStatus Status { get; private set; } + public string DefaultLanguage { get; private set; } + public string[] Languages { get; private set; } = []; + public int NumberOfQuestions { get; private set; } + + public LanguagesTranslationStatus LanguagesTranslationStatus { get; private set; } = new(); + public IReadOnlyList Questions { get; private set; } = new List().AsReadOnly(); + + protected BaseForm( + ElectionRound electionRound, + FormType formType, + string code, + TranslatedString name, + TranslatedString description, + string defaultLanguage, + IEnumerable languages, + IEnumerable questions) : this(electionRound.Id, formType, code, name, + description, defaultLanguage, languages, questions) + { + ElectionRound = electionRound; + ElectionRoundId = electionRound.Id; + } + + protected BaseForm( + Guid electionRoundId, + FormType formType, + string code, + TranslatedString name, + TranslatedString description, + string defaultLanguage, + IEnumerable languages, + IEnumerable questions) : base(Guid.NewGuid()) + { + ElectionRoundId = electionRoundId; + + FormType = formType; + Code = code; + Name = name; + Description = description; + DefaultLanguage = defaultLanguage; + Languages = languages.ToArray(); + Status = FormStatus.Drafted; + Questions = questions.ToList().AsReadOnly(); + NumberOfQuestions = Questions.Count; + LanguagesTranslationStatus = + AnswersHelpers.ComputeLanguagesTranslationStatus(Questions, defaultLanguage, Languages); + } + + [JsonConstructor] + public BaseForm(Guid id, + Guid electionRoundId, + FormType formType, + string code, + TranslatedString name, + TranslatedString description, + FormStatus status, + string defaultLanguage, + string[] languages, + int numberOfQuestions, + LanguagesTranslationStatus languagesTranslationStatus) : base(id) + { + ElectionRoundId = electionRoundId; + FormType = formType; + Code = code; + Name = name; + Description = description; + Status = status; + DefaultLanguage = defaultLanguage; + Languages = languages; + NumberOfQuestions = numberOfQuestions; + LanguagesTranslationStatus = languagesTranslationStatus; + } + + public PublishResult Publish() + { + var validator = new FormValidator(); + var validationResult = validator.Validate(this); + + if (!validationResult.IsValid) + { + return new PublishResult.InvalidForm(validationResult); + } + + Status = FormStatus.Published; + + return new PublishResult.Published(); + } + + public void Draft() + { + Status = FormStatus.Drafted; + } + + public void Obsolete() + { + Status = FormStatus.Obsolete; + } + + public void UpdateDetails(string code, + TranslatedString name, + TranslatedString description, + FormType formType, + string defaultLanguage, + IEnumerable languages, + IEnumerable questions) + { + Code = code; + Name = name; + Description = description; + FormType = formType; + DefaultLanguage = defaultLanguage; + Languages = languages.ToArray(); + Questions = questions.ToList().AsReadOnly(); + NumberOfQuestions = Questions.Count; + LanguagesTranslationStatus = + AnswersHelpers.ComputeLanguagesTranslationStatus(Questions, defaultLanguage, Languages); + } + + private T BaseFillIn(T submission, List answers, Action clearAnswers, + Action> updateAnswers) where T : class + { + if (answers == null) + { + return submission; + } + + if (!answers.Any()) + { + clearAnswers(submission); + return submission; + } + + var validationResult = AnswersValidator.GetValidationResults(answers, Questions); + + if (!validationResult.IsValid) + { + throw new ValidationException(validationResult.Errors); + } + + var numberOfQuestionsAnswered = AnswersHelpers.CountNumberOfQuestionsAnswered(Questions, answers); + var numberOfFlaggedAnswers = AnswersHelpers.CountNumberOfFlaggedAnswers(Questions, answers); + + updateAnswers(submission, numberOfQuestionsAnswered, numberOfFlaggedAnswers, answers); + + return submission; + } + + public FormSubmission FillIn(FormSubmission formSubmission, List answers) + { + return BaseFillIn( + formSubmission, + answers, + submission => submission.ClearAnswers(), + (submission, numberOfQuestionsAnswered, numberOfFlaggedAnswers, formAnswers) => + submission.UpdateAnswers(numberOfQuestionsAnswered, numberOfFlaggedAnswers, formAnswers) + ); + } + + public CitizenReport FillIn(CitizenReport citizenReport, List answers) + { + return BaseFillIn( + citizenReport, + answers, + report => report.ClearAnswers(), + (report, numberOfQuestionsAnswered, numberOfFlaggedAnswers, ans) => + report.UpdateAnswers(numberOfQuestionsAnswered, numberOfFlaggedAnswers, ans) + ); + } + + public PollingStationInformation FillIn(PollingStationInformation psiSubmission, List answers) + { + return BaseFillIn( + psiSubmission, + answers, + submission => submission.ClearAnswers(), + (submission, answered, flagged, ans) => submission.UpdateAnswers(ans, answered, flagged) + ); + } + + public void AddTranslations(string[] languageCodes) + { + var newLanguages = languageCodes.Except(Languages); + Languages = Languages.Union(languageCodes).ToArray(); + + foreach (var languageCode in newLanguages) + { + Description.AddTranslation(languageCode); + Name.AddTranslation(languageCode); + + foreach (var question in Questions) + { + question.AddTranslation(languageCode); + } + } + + LanguagesTranslationStatus = + AnswersHelpers.ComputeLanguagesTranslationStatus(Questions, DefaultLanguage, Languages); + } + + public bool HasTranslation(string languageCode) + { + return Languages.Contains(languageCode); + } + + public void SetDefaultLanguage(string languageCode) + { + if (!HasTranslation(languageCode)) + { + throw new ArgumentException("Form does not have translations for language code"); + } + + DefaultLanguage = languageCode; + + LanguagesTranslationStatus = + AnswersHelpers.ComputeLanguagesTranslationStatus(Questions, DefaultLanguage, Languages); + } + + public void RemoveTranslation(string languageCode) + { + bool hasLanguageCode = languageCode.Contains(languageCode); + + if (!hasLanguageCode) + { + return; + } + + if (DefaultLanguage == languageCode) + { + throw new ArgumentException("Cannot remove default language"); + } + + Languages = Languages.Except([languageCode]).ToArray(); + Description.RemoveTranslation(languageCode); + Name.RemoveTranslation(languageCode); + + foreach (var question in Questions) + { + question.RemoveTranslation(languageCode); + } + + LanguagesTranslationStatus = + AnswersHelpers.ComputeLanguagesTranslationStatus(Questions, DefaultLanguage, Languages); + } + + protected BaseForm() + { + } +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Domain/Entities/LocationAggregate/Location.cs b/api/src/Vote.Monitor.Domain/Entities/LocationAggregate/Location.cs new file mode 100644 index 000000000..c16fc43d4 --- /dev/null +++ b/api/src/Vote.Monitor.Domain/Entities/LocationAggregate/Location.cs @@ -0,0 +1,98 @@ +namespace Vote.Monitor.Domain.Entities.LocationAggregate; + +public class Location : AuditableBaseEntity, IAggregateRoot, IDisposable +{ +#pragma warning disable CS8618 // Required by Entity Framework + private Location() + { + } +#pragma warning restore CS8618 + + internal Location(ElectionRound electionRound, + string level1, + string level2, + string level3, + string level4, + string level5, + int displayOrder, + JsonDocument tags) : this(Guid.NewGuid(), electionRound, level1, level2, level3, level4, level5, displayOrder, + tags) + { + } + + public static Location Create(ElectionRound electionRound, + string level1, + string level2, + string level3, + string level4, + string level5, + int displayOrder, + JsonDocument tags, + DateTime createdOn, + Guid userId) + { + var pollingStation = new Location(electionRound, level1, level2, level3, level4, level5, displayOrder, + tags); + + pollingStation.CreatedOn = createdOn; + pollingStation.CreatedBy = userId; + + return pollingStation; + } + + public ElectionRound ElectionRound { get; private set; } + public Guid ElectionRoundId { get; private set; } + + internal Location( + Guid id, + ElectionRound electionRound, + string level1, + string level2, + string level3, + string level4, + string level5, + int displayOrder, + JsonDocument tags) : base(id) + { + ElectionRoundId = electionRound.Id; + ElectionRound = electionRound; + Level1 = level1; + Level2 = level2; + Level3 = level3; + Level4 = level4; + Level5 = level5; + DisplayOrder = displayOrder; + Tags = tags; + } + + public string Level1 { get; private set; } + public string Level2 { get; private set; } + public string Level3 { get; private set; } + public string Level4 { get; private set; } + public string Level5 { get; private set; } + public int DisplayOrder { get; private set; } + + public JsonDocument Tags { get; private set; } + + public void UpdateDetails(string level1, + string level2, + string level3, + string level4, + string level5, + int displayOrder, + JsonDocument tags) + { + Level1 = level1; + Level2 = level2; + Level3 = level3; + Level4 = level4; + Level5 = level5; + DisplayOrder = displayOrder; + Tags = tags; + } + + public void Dispose() + { + Tags.Dispose(); + } +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Domain/Entities/PollingStationInfoAggregate/PollingStationInformation.cs b/api/src/Vote.Monitor.Domain/Entities/PollingStationInfoAggregate/PollingStationInformation.cs index 963722f06..938bab45b 100644 --- a/api/src/Vote.Monitor.Domain/Entities/PollingStationInfoAggregate/PollingStationInformation.cs +++ b/api/src/Vote.Monitor.Domain/Entities/PollingStationInfoAggregate/PollingStationInformation.cs @@ -19,6 +19,7 @@ public class PollingStationInformation : AuditableBaseEntity, IAggregateRoot public DateTime? DepartureTime { get; private set; } public double? MinutesMonitoring { get; private set; } public int NumberOfQuestionsAnswered { get; private set; } + public int NumberOfFlaggedAnswers { get; private set; } public SubmissionFollowUpStatus FollowUpStatus { get; private set; } public IReadOnlyList Answers { get; private set; } = new List().AsReadOnly(); @@ -31,7 +32,8 @@ private PollingStationInformation( DateTime? arrivalTime, DateTime? departureTime, List answers, - int numberOfQuestionsAnswered) : base(Guid.NewGuid()) + int numberOfQuestionsAnswered, + int numberOfFlaggedAnswers) : base(Guid.NewGuid()) { ElectionRound = electionRound; ElectionRoundId = electionRound.Id; @@ -45,6 +47,7 @@ private PollingStationInformation( DepartureTime = departureTime; Answers = answers.ToList().AsReadOnly(); NumberOfQuestionsAnswered = numberOfQuestionsAnswered; + NumberOfFlaggedAnswers = numberOfFlaggedAnswers; FollowUpStatus = SubmissionFollowUpStatus.NotApplicable; } @@ -56,13 +59,15 @@ internal static PollingStationInformation Create( DateTime? arrivalTime, DateTime? departureTime, List answers, - int numberOfQuestionsAnswered) => - new(electionRound, pollingStation, monitoringObserver, pollingStationInformationForm, arrivalTime, departureTime, answers, numberOfQuestionsAnswered); + int numberOfQuestionsAnswered, + int numberOfFlaggedAnswers) => + new(electionRound, pollingStation, monitoringObserver, pollingStationInformationForm, arrivalTime, departureTime, answers, numberOfQuestionsAnswered, numberOfFlaggedAnswers); - internal void UpdateAnswers(IEnumerable answers, int numberOfQuestionsAnswered) + internal void UpdateAnswers(IEnumerable answers, int numberOfQuestionsAnswered,int numberOfFlaggedAnswers) { Answers = answers.ToList().AsReadOnly(); NumberOfQuestionsAnswered = numberOfQuestionsAnswered; + NumberOfFlaggedAnswers = numberOfFlaggedAnswers; } public void UpdateTimesOfStay(DateTime? arrivalTime, DateTime? departureTime) diff --git a/api/src/Vote.Monitor.Domain/Entities/PollingStationInfoFormAggregate/PollingStationInformationForm.cs b/api/src/Vote.Monitor.Domain/Entities/PollingStationInfoFormAggregate/PollingStationInformationForm.cs index 7ff5c8937..2535b57d2 100644 --- a/api/src/Vote.Monitor.Domain/Entities/PollingStationInfoFormAggregate/PollingStationInformationForm.cs +++ b/api/src/Vote.Monitor.Domain/Entities/PollingStationInfoFormAggregate/PollingStationInformationForm.cs @@ -1,34 +1,26 @@ using FluentValidation; +using Vote.Monitor.Core.Models; +using Vote.Monitor.Domain.Entities.FormAggregate; using Vote.Monitor.Domain.Entities.FormAnswerBase; using Vote.Monitor.Domain.Entities.FormAnswerBase.Answers; +using Vote.Monitor.Domain.Entities.FormBase; using Vote.Monitor.Domain.Entities.FormBase.Questions; using Vote.Monitor.Domain.Entities.MonitoringObserverAggregate; using Vote.Monitor.Domain.Entities.PollingStationInfoAggregate; namespace Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate; -public class PollingStationInformationForm : AuditableBaseEntity, IAggregateRoot +public class PollingStationInformationForm : BaseForm { - public Guid ElectionRoundId { get; private set; } - public ElectionRound ElectionRound { get; private set; } - public string DefaultLanguage { get; private set; } - public string[] Languages { get; private set; } - public IReadOnlyList Questions { get; private set; } = new List().AsReadOnly(); - public int NumberOfQuestions { get; private set; } - private PollingStationInformationForm( ElectionRound electionRound, string defaultLanguage, IEnumerable languages, - List questions) : base(Guid.NewGuid()) + List questions) : base(electionRound, FormType.PSI, "PSI", TranslatedString.New(languages, "PSI"), + TranslatedString.New(languages, ""), defaultLanguage, languages, questions) { - ElectionRound = electionRound; - ElectionRoundId = electionRound.Id; - DefaultLanguage = defaultLanguage; - Languages = languages.ToArray(); - Questions = questions.ToList().AsReadOnly(); - NumberOfQuestions = Questions.Count; } + private PollingStationInformationForm( ElectionRound electionRound, string defaultLanguage, @@ -49,13 +41,6 @@ public static PollingStationInformationForm Create( List questions) => new(electionRound, defaultLanguage, languages, questions); - public void UpdateDetails(string defaultLanguage, IEnumerable languages, IEnumerable questions) - { - DefaultLanguage = defaultLanguage; - Languages = languages.ToArray(); - Questions = questions.ToList().AsReadOnly(); - NumberOfQuestions = Questions.Count; - } public PollingStationInformation CreatePollingStationInformation( PollingStation pollingStation, @@ -66,7 +51,8 @@ public PollingStationInformation CreatePollingStationInformation( { if (answers == null) { - return PollingStationInformation.Create(ElectionRound, pollingStation, monitoringObserver, this, arrivalTime, departureTime, [], 0); + return PollingStationInformation.Create(ElectionRound, pollingStation, monitoringObserver, this, + arrivalTime, departureTime, [], 0, 0); } var validationResult = AnswersValidator.GetValidationResults(answers, Questions); @@ -75,49 +61,17 @@ public PollingStationInformation CreatePollingStationInformation( { throw new ValidationException(validationResult.Errors); } - var numberOfQuestionsAnswered = CountNumberOfQuestionsAnswered(answers); - - return PollingStationInformation.Create(ElectionRound, pollingStation, monitoringObserver, this, arrivalTime, departureTime, answers, numberOfQuestionsAnswered); - } - - public PollingStationInformation FillIn(PollingStationInformation filledInForm, List? answers) - { - if (answers is null) - { - return filledInForm; - } - if (!answers.Any()) - { - filledInForm.ClearAnswers(); - return filledInForm; - } - - var validationResult = AnswersValidator.GetValidationResults(answers, Questions); + var numberOfQuestionsAnswered = AnswersHelpers.CountNumberOfQuestionsAnswered(Questions, answers); + var numberOfFlaggedAnswers = AnswersHelpers.CountNumberOfFlaggedAnswers(Questions, answers); - if (!validationResult.IsValid) - { - throw new ValidationException(validationResult.Errors); - } - - var numberOfQuestionsAnswered = CountNumberOfQuestionsAnswered(answers); - - filledInForm.UpdateAnswers(answers, numberOfQuestionsAnswered); - - return filledInForm; + return PollingStationInformation.Create(ElectionRound, pollingStation, monitoringObserver, this, arrivalTime, + departureTime, answers, numberOfQuestionsAnswered, numberOfFlaggedAnswers); } - - private int CountNumberOfQuestionsAnswered(List answers) - { - var questionIds = Questions.Select(x => x.Id).ToList(); - - return answers.Count(x => questionIds.Contains(x.QuestionId)); - } - + #pragma warning disable CS8618 // Required by Entity Framework - private PollingStationInformationForm() + private PollingStationInformationForm(): base() { - } #pragma warning restore CS8618 -} +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Domain/EntitiesConfiguration/LocationConfiguration.cs b/api/src/Vote.Monitor.Domain/EntitiesConfiguration/LocationConfiguration.cs new file mode 100644 index 000000000..3c5e5fffb --- /dev/null +++ b/api/src/Vote.Monitor.Domain/EntitiesConfiguration/LocationConfiguration.cs @@ -0,0 +1,27 @@ +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Vote.Monitor.Domain.Entities.LocationAggregate; + +namespace Vote.Monitor.Domain.EntitiesConfiguration; + +public class LocationConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(p => p.Id); + + builder.Property(p => p.Id).IsRequired(); + builder.Property(p => p.DisplayOrder).IsRequired(); + builder.Property(p => p.Tags).IsRequired(false); + builder.Property(p => p.Level1).HasMaxLength(256).IsRequired(); + builder.Property(p => p.Level2).HasMaxLength(256).IsRequired(false); + builder.Property(p => p.Level3).HasMaxLength(256).IsRequired(false); + builder.Property(p => p.Level4).HasMaxLength(256).IsRequired(false); + builder.Property(p => p.Level5).HasMaxLength(256).IsRequired(false); + + builder + .HasOne(x => x.ElectionRound) + .WithMany() + .HasForeignKey(x => x.ElectionRoundId) + .OnDelete(DeleteBehavior.Cascade); + } +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Domain/EntitiesConfiguration/NotificationConfiguration.cs b/api/src/Vote.Monitor.Domain/EntitiesConfiguration/NotificationConfiguration.cs index 3a14c83d8..b171c3910 100644 --- a/api/src/Vote.Monitor.Domain/EntitiesConfiguration/NotificationConfiguration.cs +++ b/api/src/Vote.Monitor.Domain/EntitiesConfiguration/NotificationConfiguration.cs @@ -1,5 +1,4 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Vote.Monitor.Domain.Entities.MonitoringObserverAggregate; using Vote.Monitor.Domain.Entities.NotificationAggregate; namespace Vote.Monitor.Domain.EntitiesConfiguration; diff --git a/api/src/Vote.Monitor.Domain/EntitiesConfiguration/PollingStationInformationConfiguration.cs b/api/src/Vote.Monitor.Domain/EntitiesConfiguration/PollingStationInformationConfiguration.cs index 384028879..fe5bc897b 100644 --- a/api/src/Vote.Monitor.Domain/EntitiesConfiguration/PollingStationInformationConfiguration.cs +++ b/api/src/Vote.Monitor.Domain/EntitiesConfiguration/PollingStationInformationConfiguration.cs @@ -29,7 +29,7 @@ public void Configure(EntityTypeBuilder builder) builder.HasOne(x => x.ElectionRound) .WithMany() .HasForeignKey(x => x.ElectionRoundId); - + builder.HasOne(x => x.PollingStation) .WithMany() .HasForeignKey(x => x.PollingStationId); @@ -42,9 +42,10 @@ public void Configure(EntityTypeBuilder builder) builder.Property(x => x.DepartureTime); builder.Property(x => x.MinutesMonitoring); builder.Property(x => x.NumberOfQuestionsAnswered); + builder.Property(x => x.NumberOfFlaggedAnswers); builder.Property(x => x.Answers) .HasConversion() .HasColumnType("jsonb"); } -} +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Domain/EntitiesConfiguration/PollingStationInformationFormConfiguration.cs b/api/src/Vote.Monitor.Domain/EntitiesConfiguration/PollingStationInformationFormConfiguration.cs index d19331576..813030c18 100644 --- a/api/src/Vote.Monitor.Domain/EntitiesConfiguration/PollingStationInformationFormConfiguration.cs +++ b/api/src/Vote.Monitor.Domain/EntitiesConfiguration/PollingStationInformationFormConfiguration.cs @@ -20,9 +20,24 @@ public void Configure(EntityTypeBuilder builder) builder.Property(x => x.DefaultLanguage).HasMaxLength(256).IsRequired(); builder.Property(x => x.Languages).IsRequired(); builder.Property(x => x.NumberOfQuestions).IsRequired(); + builder.Property(x => x.Code).HasMaxLength(256).IsRequired(); + builder.Property(x => x.FormType).IsRequired(); + + builder.Property(x => x.Name) + .HasConversion() + .HasColumnType("jsonb"); + + builder.Property(x => x.Description) + .HasConversion() + .HasColumnType("jsonb"); + builder.Property(x => x.Questions) .HasConversion() .HasColumnType("jsonb"); + + builder.Property(x => x.LanguagesTranslationStatus) + .HasConversion() + .HasColumnType("jsonb"); } -} +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Domain/Migrations/20240913084651_RefactorFormsAndSubmissions.Designer.cs b/api/src/Vote.Monitor.Domain/Migrations/20240913084651_RefactorFormsAndSubmissions.Designer.cs new file mode 100644 index 000000000..4d47afb67 --- /dev/null +++ b/api/src/Vote.Monitor.Domain/Migrations/20240913084651_RefactorFormsAndSubmissions.Designer.cs @@ -0,0 +1,6268 @@ +// +using System; +using System.Collections.Generic; +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Vote.Monitor.Domain; + +#nullable disable + +namespace Vote.Monitor.Domain.Migrations +{ + [DbContext(typeof(VoteMonitorContext))] + [Migration("20240913084651_RefactorFormsAndSubmissions")] + partial class RefactorFormsAndSubmissions + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "hstore"); + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "uuid-ossp"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + + b.HasData( + new + { + Id = new Guid("265e94b0-50fe-4546-b21c-83cb7e94aeff"), + Name = "PlatformAdmin", + NormalizedName = "PLATFORMADMIN" + }, + new + { + Id = new Guid("3239f803-dda8-408b-93ad-0ed973a04e45"), + Name = "NgoAdmin", + NormalizedName = "NGOADMIN" + }, + new + { + Id = new Guid("d1cbef39-62e0-4120-a42b-b01b029dc6ad"), + Name = "Observer", + NormalizedName = "OBSERVER" + }); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("InvitationToken") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("RefreshToken") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("RefreshTokenExpiryTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Role") + .IsRequired() + .HasColumnType("text"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.AttachmentAggregate.Attachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("IsCompleted") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.Property("QuestionId") + .HasColumnType("uuid"); + + b.Property("UploadedFileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.ToTable("Attachments", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.Auditing.Trail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AffectedColumns") + .HasColumnType("text"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("NewValues") + .HasColumnType("text"); + + b.Property("OldValues") + .HasColumnType("text"); + + b.Property("PrimaryKey") + .HasColumnType("text"); + + b.Property("TableName") + .HasColumnType("text"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("Type") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("AuditTrails"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Answers") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FollowUpStatus") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("NotApplicable"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("NumberOfFlaggedAnswers") + .HasColumnType("integer"); + + b.Property("NumberOfQuestionsAnswered") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.ToTable("CitizenReports"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAttachmentAggregate.CitizenReportAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CitizenReportId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("IsCompleted") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("QuestionId") + .HasColumnType("uuid"); + + b.Property("UploadedFileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("CitizenReportId"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.ToTable("CitizenReportAttachments"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportNoteAggregate.CitizenReportNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CitizenReportId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("QuestionId") + .HasColumnType("uuid"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(10000) + .HasColumnType("character varying(10000)"); + + b.HasKey("Id"); + + b.HasIndex("CitizenReportId"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.ToTable("CitizenReportNotes"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CountryAggregate.Country", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Iso2") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("character varying(2)"); + + b.Property("Iso3") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("character varying(3)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NumericCode") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("character varying(3)"); + + b.HasKey("Id"); + + b.HasIndex("Iso2") + .IsUnique(); + + b.HasIndex("Iso3") + .IsUnique(); + + b.HasIndex("NumericCode") + .IsUnique(); + + b.ToTable("Countries"); + + b.HasData( + new + { + Id = new Guid("edd4319b-86f3-24cb-248c-71da624c02f7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Islamic Republic of Afghanistan", + Iso2 = "AF", + Iso3 = "AFG", + Name = "Afghanistan", + NumericCode = "004" + }, + new + { + Id = new Guid("a96fe9bb-4ef4-fca0-f38b-0ec729822f37"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Åland Islands", + Iso2 = "AX", + Iso3 = "ALA", + Name = "Åland Islands", + NumericCode = "248" + }, + new + { + Id = new Guid("5aa0aeb7-4dc8-6a29-fc2f-35daec1541dd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Albania", + Iso2 = "AL", + Iso3 = "ALB", + Name = "Albania", + NumericCode = "008" + }, + new + { + Id = new Guid("fee6f04f-c4c1-e3e4-645d-bb6bb703aeb7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "People's Democratic Republic of Algeria", + Iso2 = "DZ", + Iso3 = "DZA", + Name = "Algeria", + NumericCode = "012" + }, + new + { + Id = new Guid("538114de-7db0-9242-35e6-324fa7eff44d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "American Samoa", + Iso2 = "AS", + Iso3 = "ASM", + Name = "American Samoa", + NumericCode = "016" + }, + new + { + Id = new Guid("bd4bbfc7-d8bc-9d8d-7f7c-7b299c94e9e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Principality of Andorra", + Iso2 = "AD", + Iso3 = "AND", + Name = "Andorra", + NumericCode = "020" + }, + new + { + Id = new Guid("478786f7-1842-8c1e-921c-12e7ed5329c5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Angola", + Iso2 = "AO", + Iso3 = "AGO", + Name = "Angola", + NumericCode = "024" + }, + new + { + Id = new Guid("2b68fb11-a0e0-3d23-5fb8-99721ecfc182"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Anguilla", + Iso2 = "AI", + Iso3 = "AIA", + Name = "Anguilla", + NumericCode = "660" + }, + new + { + Id = new Guid("a0098040-b7a0-59a1-e64b-0a9778b7f74c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Antarctica (the territory South of 60 deg S)", + Iso2 = "AQ", + Iso3 = "ATA", + Name = "Antarctica", + NumericCode = "010" + }, + new + { + Id = new Guid("f3eef99a-661e-2c68-7a4c-3053e2f28007"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Antigua and Barbuda", + Iso2 = "AG", + Iso3 = "ATG", + Name = "Antigua and Barbuda", + NumericCode = "028" + }, + new + { + Id = new Guid("a7afb7b1-b26d-4571-1a1f-3fff738ff21e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Argentine Republic", + Iso2 = "AR", + Iso3 = "ARG", + Name = "Argentina", + NumericCode = "032" + }, + new + { + Id = new Guid("688af4c8-9d64-ae1c-147f-b8afd54801e3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Armenia", + Iso2 = "AM", + Iso3 = "ARM", + Name = "Armenia", + NumericCode = "051" + }, + new + { + Id = new Guid("e6c7651f-182e-cf9c-1ef9-6293b95b500c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Aruba", + Iso2 = "AW", + Iso3 = "ABW", + Name = "Aruba", + NumericCode = "533" + }, + new + { + Id = new Guid("15639386-e4fc-120c-6916-c0c980e24be1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of Australia", + Iso2 = "AU", + Iso3 = "AUS", + Name = "Australia", + NumericCode = "036" + }, + new + { + Id = new Guid("704254eb-6959-8ddc-a5df-ac8f9658dc68"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Austria", + Iso2 = "AT", + Iso3 = "AUT", + Name = "Austria", + NumericCode = "040" + }, + new + { + Id = new Guid("008c3138-73d8-dbbc-f1dd-521e4c68bcf1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Azerbaijan", + Iso2 = "AZ", + Iso3 = "AZE", + Name = "Azerbaijan", + NumericCode = "031" + }, + new + { + Id = new Guid("46e88019-c521-57b2-d1c0-c0e2478d3b05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of the Bahamas", + Iso2 = "BS", + Iso3 = "BHS", + Name = "Bahamas", + NumericCode = "044" + }, + new + { + Id = new Guid("44caa0f4-1e78-d2fb-96be-d01b3224bdc1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Bahrain", + Iso2 = "BH", + Iso3 = "BHR", + Name = "Bahrain", + NumericCode = "048" + }, + new + { + Id = new Guid("809c3424-8654-b82c-cbd4-d857d096943e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "People's Republic of Bangladesh", + Iso2 = "BD", + Iso3 = "BGD", + Name = "Bangladesh", + NumericCode = "050" + }, + new + { + Id = new Guid("316c68fc-9144-f6e1-8bf1-899fc54b2327"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Barbados", + Iso2 = "BB", + Iso3 = "BRB", + Name = "Barbados", + NumericCode = "052" + }, + new + { + Id = new Guid("d97b5460-11ab-45c5-9a6f-ffa441ed70d6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Belarus", + Iso2 = "BY", + Iso3 = "BLR", + Name = "Belarus", + NumericCode = "112" + }, + new + { + Id = new Guid("0797a7d5-bbc0-2e52-0de8-14a42fc80baa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Belgium", + Iso2 = "BE", + Iso3 = "BEL", + Name = "Belgium", + NumericCode = "056" + }, + new + { + Id = new Guid("c89e02a0-9506-90df-5545-b98a2453cd63"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Belize", + Iso2 = "BZ", + Iso3 = "BLZ", + Name = "Belize", + NumericCode = "084" + }, + new + { + Id = new Guid("96a22cee-9af7-8f03-b483-b3e774a36d3b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Benin", + Iso2 = "BJ", + Iso3 = "BEN", + Name = "Benin", + NumericCode = "204" + }, + new + { + Id = new Guid("ca2a5560-d4c4-3c87-3090-6f5436310b55"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bermuda", + Iso2 = "BM", + Iso3 = "BMU", + Name = "Bermuda", + NumericCode = "060" + }, + new + { + Id = new Guid("8ed6a34e-8135-27fa-f86a-caa247b29768"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Bhutan", + Iso2 = "BT", + Iso3 = "BTN", + Name = "Bhutan", + NumericCode = "064" + }, + new + { + Id = new Guid("f33ced84-eb43-fb39-ef79-b266e4d4cd94"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Plurinational State of Bolivia", + Iso2 = "BO", + Iso3 = "BOL", + Name = "Bolivia", + NumericCode = "068" + }, + new + { + Id = new Guid("d8101f9d-8313-4054-c5f3-42c7a1c72862"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bonaire, Sint Eustatius and Saba", + Iso2 = "BQ", + Iso3 = "BES", + Name = "Bonaire, Sint Eustatius and Saba", + NumericCode = "535" + }, + new + { + Id = new Guid("a7716d29-6ef6-b775-51c5-97094536329d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bosnia and Herzegovina", + Iso2 = "BA", + Iso3 = "BIH", + Name = "Bosnia and Herzegovina", + NumericCode = "070" + }, + new + { + Id = new Guid("14f190c6-97c9-3e12-2eba-db17c59d6a04"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Botswana", + Iso2 = "BW", + Iso3 = "BWA", + Name = "Botswana", + NumericCode = "072" + }, + new + { + Id = new Guid("32da0208-9048-1339-a8ee-6955cfff4c12"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bouvet Island (Bouvetøya)", + Iso2 = "BV", + Iso3 = "BVT", + Name = "Bouvet Island (Bouvetøya)", + NumericCode = "074" + }, + new + { + Id = new Guid("5283afbb-2744-e930-2c16-c5ea6b0ff7cc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federative Republic of Brazil", + Iso2 = "BR", + Iso3 = "BRA", + Name = "Brazil", + NumericCode = "076" + }, + new + { + Id = new Guid("b8b09512-ea4c-4a61-9331-304f55324ef7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "British Indian Ocean Territory (Chagos Archipelago)", + Iso2 = "IO", + Iso3 = "IOT", + Name = "British Indian Ocean Territory (Chagos Archipelago)", + NumericCode = "086" + }, + new + { + Id = new Guid("39be5e86-aea5-f64f-fd7e-1017fe24e543"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "British Virgin Islands", + Iso2 = "VG", + Iso3 = "VGB", + Name = "British Virgin Islands", + NumericCode = "092" + }, + new + { + Id = new Guid("ed6278e0-436c-9fd9-0b9e-44fd424cbd1b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Brunei Darussalam", + Iso2 = "BN", + Iso3 = "BRN", + Name = "Brunei Darussalam", + NumericCode = "096" + }, + new + { + Id = new Guid("46576b73-c05b-7498-5b07-9bbf59b7645d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Bulgaria", + Iso2 = "BG", + Iso3 = "BGR", + Name = "Bulgaria", + NumericCode = "100" + }, + new + { + Id = new Guid("42697d56-52cf-b411-321e-c51929f02f90"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Burkina Faso", + Iso2 = "BF", + Iso3 = "BFA", + Name = "Burkina Faso", + NumericCode = "854" + }, + new + { + Id = new Guid("75e4464b-a784-63b8-1ecc-69ee1f09f43f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Burundi", + Iso2 = "BI", + Iso3 = "BDI", + Name = "Burundi", + NumericCode = "108" + }, + new + { + Id = new Guid("c9702851-1f67-f2a6-89d4-37b3fbb12044"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Cambodia", + Iso2 = "KH", + Iso3 = "KHM", + Name = "Cambodia", + NumericCode = "116" + }, + new + { + Id = new Guid("c0b7e39e-223a-ebb0-b899-5404573bbdb7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cameroon", + Iso2 = "CM", + Iso3 = "CMR", + Name = "Cameroon", + NumericCode = "120" + }, + new + { + Id = new Guid("5c0e654b-8547-5d02-ee7b-d65e3c5c5273"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Canada", + Iso2 = "CA", + Iso3 = "CAN", + Name = "Canada", + NumericCode = "124" + }, + new + { + Id = new Guid("17ed5f0f-e091-94ff-0512-ad291bde94d7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cabo Verde", + Iso2 = "CV", + Iso3 = "CPV", + Name = "Cabo Verde", + NumericCode = "132" + }, + new + { + Id = new Guid("3c5828e0-16a8-79ba-4e5c-9b45065df113"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Cayman Islands", + Iso2 = "KY", + Iso3 = "CYM", + Name = "Cayman Islands", + NumericCode = "136" + }, + new + { + Id = new Guid("b4e0625c-7597-c185-b8ae-cfb35a731f2f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Central African Republic", + Iso2 = "CF", + Iso3 = "CAF", + Name = "Central African Republic", + NumericCode = "140" + }, + new + { + Id = new Guid("2a1ca5b6-fba0-cfa8-9928-d7a2382bc4d7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Chad", + Iso2 = "TD", + Iso3 = "TCD", + Name = "Chad", + NumericCode = "148" + }, + new + { + Id = new Guid("ad4f938a-bf7b-684b-2c9e-e824d3fa3863"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Chile", + Iso2 = "CL", + Iso3 = "CHL", + Name = "Chile", + NumericCode = "152" + }, + new + { + Id = new Guid("8250c49f-9438-7c2e-f403-54d962db0c18"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "People's Republic of China", + Iso2 = "CN", + Iso3 = "CHN", + Name = "China", + NumericCode = "156" + }, + new + { + Id = new Guid("0f1ba59e-ade5-23e5-6fce-e2fd3282e114"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Christmas Island", + Iso2 = "CX", + Iso3 = "CXR", + Name = "Christmas Island", + NumericCode = "162" + }, + new + { + Id = new Guid("a16263a5-810c-bf6a-206d-72cb914e2d5c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Cocos (Keeling) Islands", + Iso2 = "CC", + Iso3 = "CCK", + Name = "Cocos (Keeling) Islands", + NumericCode = "166" + }, + new + { + Id = new Guid("c64288fc-d941-0615-47f9-28e6c294ce26"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Colombia", + Iso2 = "CO", + Iso3 = "COL", + Name = "Colombia", + NumericCode = "170" + }, + new + { + Id = new Guid("5e7a08f2-7d59-bcdb-7ddd-876b87181420"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Union of the Comoros", + Iso2 = "KM", + Iso3 = "COM", + Name = "Comoros", + NumericCode = "174" + }, + new + { + Id = new Guid("1258ec90-c47e-ff72-b7e3-f90c3ee320f8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic Republic of the Congo", + Iso2 = "CD", + Iso3 = "COD", + Name = "Congo", + NumericCode = "180" + }, + new + { + Id = new Guid("1934954c-66c2-6226-c5b6-491065a3e4c0"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Congo", + Iso2 = "CG", + Iso3 = "COG", + Name = "Congo", + NumericCode = "178" + }, + new + { + Id = new Guid("af79558d-51fb-b08d-185b-afeb983ab99b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Cook Islands", + Iso2 = "CK", + Iso3 = "COK", + Name = "Cook Islands", + NumericCode = "184" + }, + new + { + Id = new Guid("d13935c1-8956-1399-7c4e-0354795cd37b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Costa Rica", + Iso2 = "CR", + Iso3 = "CRI", + Name = "Costa Rica", + NumericCode = "188" + }, + new + { + Id = new Guid("5be18efe-6db8-a727-7f2a-62bd71bc6593"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cote d'Ivoire", + Iso2 = "CI", + Iso3 = "CIV", + Name = "Cote d'Ivoire", + NumericCode = "384" + }, + new + { + Id = new Guid("1f8be615-5746-277e-d82b-47596b5bb922"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Croatia", + Iso2 = "HR", + Iso3 = "HRV", + Name = "Croatia", + NumericCode = "191" + }, + new + { + Id = new Guid("57765d87-2424-2c86-ad9c-1af58ef3127a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cuba", + Iso2 = "CU", + Iso3 = "CUB", + Name = "Cuba", + NumericCode = "192" + }, + new + { + Id = new Guid("3345e205-3e72-43ed-de1b-ac6e050543e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Curaçao", + Iso2 = "CW", + Iso3 = "CUW", + Name = "Curaçao", + NumericCode = "531" + }, + new + { + Id = new Guid("df20d0d7-9fbe-e725-d966-4fdf9f5c9dfb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cyprus", + Iso2 = "CY", + Iso3 = "CYP", + Name = "Cyprus", + NumericCode = "196" + }, + new + { + Id = new Guid("9d4ec95b-974a-f5bb-bb4b-ba6747440631"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Czech Republic", + Iso2 = "CZ", + Iso3 = "CZE", + Name = "Czechia", + NumericCode = "203" + }, + new + { + Id = new Guid("8a4fcb23-f3e6-fb5b-8cda-975872f600d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Denmark", + Iso2 = "DK", + Iso3 = "DNK", + Name = "Denmark", + NumericCode = "208" + }, + new + { + Id = new Guid("37a79267-d38a-aaef-577a-aa68a96880ae"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Djibouti", + Iso2 = "DJ", + Iso3 = "DJI", + Name = "Djibouti", + NumericCode = "262" + }, + new + { + Id = new Guid("19ea3a6a-1a76-23c8-8e4e-1d298f15207f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of Dominica", + Iso2 = "DM", + Iso3 = "DMA", + Name = "Dominica", + NumericCode = "212" + }, + new + { + Id = new Guid("b2c4d2d7-7ada-7864-426f-10a28d9f9eba"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Dominican Republic", + Iso2 = "DO", + Iso3 = "DOM", + Name = "Dominican Republic", + NumericCode = "214" + }, + new + { + Id = new Guid("49c82f1b-968d-b5e7-8559-e39567d46787"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Ecuador", + Iso2 = "EC", + Iso3 = "ECU", + Name = "Ecuador", + NumericCode = "218" + }, + new + { + Id = new Guid("ee5dfc29-80f1-86ae-cde7-02484a18907a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Arab Republic of Egypt", + Iso2 = "EG", + Iso3 = "EGY", + Name = "Egypt", + NumericCode = "818" + }, + new + { + Id = new Guid("4d8bcda4-5598-16cd-b379-97eb7a5e1c29"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of El Salvador", + Iso2 = "SV", + Iso3 = "SLV", + Name = "El Salvador", + NumericCode = "222" + }, + new + { + Id = new Guid("824392e8-a6cc-0cd4-af13-3067dad3258e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Equatorial Guinea", + Iso2 = "GQ", + Iso3 = "GNQ", + Name = "Equatorial Guinea", + NumericCode = "226" + }, + new + { + Id = new Guid("8b5a477a-070a-a84f-bd3b-f54dc2a172de"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Eritrea", + Iso2 = "ER", + Iso3 = "ERI", + Name = "Eritrea", + NumericCode = "232" + }, + new + { + Id = new Guid("2dc643bd-cc6c-eb0c-7314-44123576f0ee"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Estonia", + Iso2 = "EE", + Iso3 = "EST", + Name = "Estonia", + NumericCode = "233" + }, + new + { + Id = new Guid("e75515a6-63cf-3612-a3a2-befa0d7048a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federal Democratic Republic of Ethiopia", + Iso2 = "ET", + Iso3 = "ETH", + Name = "Ethiopia", + NumericCode = "231" + }, + new + { + Id = new Guid("0d4fe6e6-ea1e-d1ce-5134-6c0c1a696a00"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Faroe Islands", + Iso2 = "FO", + Iso3 = "FRO", + Name = "Faroe Islands", + NumericCode = "234" + }, + new + { + Id = new Guid("b86375dc-edbb-922c-9ed4-2f724094a5a2"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Falkland Islands (Malvinas)", + Iso2 = "FK", + Iso3 = "FLK", + Name = "Falkland Islands (Malvinas)", + NumericCode = "238" + }, + new + { + Id = new Guid("0e2a1681-d852-67ae-7387-0d04be9e7fd3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Fiji", + Iso2 = "FJ", + Iso3 = "FJI", + Name = "Fiji", + NumericCode = "242" + }, + new + { + Id = new Guid("5a5d9168-081b-1e02-1fbb-cdfa910e526c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Finland", + Iso2 = "FI", + Iso3 = "FIN", + Name = "Finland", + NumericCode = "246" + }, + new + { + Id = new Guid("b2261c50-1a57-7f1f-d72d-f8c21593874f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "French Republic", + Iso2 = "FR", + Iso3 = "FRA", + Name = "France", + NumericCode = "250" + }, + new + { + Id = new Guid("ac6cde6e-f645-d04e-8afc-0391ecf38a70"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "French Guiana", + Iso2 = "GF", + Iso3 = "GUF", + Name = "French Guiana", + NumericCode = "254" + }, + new + { + Id = new Guid("11dbce82-a154-7aee-7b5e-d5981f220572"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "French Polynesia", + Iso2 = "PF", + Iso3 = "PYF", + Name = "French Polynesia", + NumericCode = "258" + }, + new + { + Id = new Guid("903bee63-bcf0-0264-6eaf-a8cde95c5f41"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "French Southern Territories", + Iso2 = "TF", + Iso3 = "ATF", + Name = "French Southern Territories", + NumericCode = "260" + }, + new + { + Id = new Guid("4826bc0f-235e-572f-2b1a-21f1c9e05f83"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Gabonese Republic", + Iso2 = "GA", + Iso3 = "GAB", + Name = "Gabon", + NumericCode = "266" + }, + new + { + Id = new Guid("a40b91b3-cc13-2470-65f0-a0fdc946f2a2"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Gambia", + Iso2 = "GM", + Iso3 = "GMB", + Name = "Gambia", + NumericCode = "270" + }, + new + { + Id = new Guid("980176e8-7d9d-9729-b3e9-ebc455fb8fc4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Georgia", + Iso2 = "GE", + Iso3 = "GEO", + Name = "Georgia", + NumericCode = "268" + }, + new + { + Id = new Guid("46ef1468-86f6-0c99-f4e9-46f966167b05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federal Republic of Germany", + Iso2 = "DE", + Iso3 = "DEU", + Name = "Germany", + NumericCode = "276" + }, + new + { + Id = new Guid("6d0c77a7-a4aa-c2bd-2db6-0e2ad2d61f8a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Ghana", + Iso2 = "GH", + Iso3 = "GHA", + Name = "Ghana", + NumericCode = "288" + }, + new + { + Id = new Guid("8e0de349-f9ab-2bca-3910-efd48bf1170a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Gibraltar", + Iso2 = "GI", + Iso3 = "GIB", + Name = "Gibraltar", + NumericCode = "292" + }, + new + { + Id = new Guid("4fc1a9dc-cc74-f6ce-5743-c5cee8d709ef"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Hellenic Republic of Greece", + Iso2 = "GR", + Iso3 = "GRC", + Name = "Greece", + NumericCode = "300" + }, + new + { + Id = new Guid("2f00fe86-a06b-dc95-0ea7-4520d1dec784"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Greenland", + Iso2 = "GL", + Iso3 = "GRL", + Name = "Greenland", + NumericCode = "304" + }, + new + { + Id = new Guid("ff5b4d88-c179-ff0d-6285-cf46ba475d7d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Grenada", + Iso2 = "GD", + Iso3 = "GRD", + Name = "Grenada", + NumericCode = "308" + }, + new + { + Id = new Guid("3bcd2aad-fb69-09f4-1ad7-2c7f5fa23f9f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Guadeloupe", + Iso2 = "GP", + Iso3 = "GLP", + Name = "Guadeloupe", + NumericCode = "312" + }, + new + { + Id = new Guid("096a8586-9702-6fec-5f6a-6eb3b7b7837f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Guam", + Iso2 = "GU", + Iso3 = "GUM", + Name = "Guam", + NumericCode = "316" + }, + new + { + Id = new Guid("d24b46ba-8e9d-2a09-7995-e35e8ae54f6b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Guatemala", + Iso2 = "GT", + Iso3 = "GTM", + Name = "Guatemala", + NumericCode = "320" + }, + new + { + Id = new Guid("5b0ee3be-596d-bdc1-f101-00ef33170655"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bailiwick of Guernsey", + Iso2 = "GG", + Iso3 = "GGY", + Name = "Guernsey", + NumericCode = "831" + }, + new + { + Id = new Guid("3ffe68ca-7350-175b-4e95-0c34f54dc1f4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Guinea", + Iso2 = "GN", + Iso3 = "GIN", + Name = "Guinea", + NumericCode = "324" + }, + new + { + Id = new Guid("a9a5f440-a9bd-487d-e7f4-914df0d52fa6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Guinea-Bissau", + Iso2 = "GW", + Iso3 = "GNB", + Name = "Guinea-Bissau", + NumericCode = "624" + }, + new + { + Id = new Guid("a9949ac7-8d2d-32b5-3f4f-e2a3ef291a67"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Co-operative Republic of Guyana", + Iso2 = "GY", + Iso3 = "GUY", + Name = "Guyana", + NumericCode = "328" + }, + new + { + Id = new Guid("2bebebe4-edaa-9160-5a0c-4d99048bd8d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Haiti", + Iso2 = "HT", + Iso3 = "HTI", + Name = "Haiti", + NumericCode = "332" + }, + new + { + Id = new Guid("592b4658-a210-ab0a-5660-3dcc673dc581"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Heard Island and McDonald Islands", + Iso2 = "HM", + Iso3 = "HMD", + Name = "Heard Island and McDonald Islands", + NumericCode = "334" + }, + new + { + Id = new Guid("d0e11a85-6623-69f5-bd95-3779dfeec297"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Holy See (Vatican City State)", + Iso2 = "VA", + Iso3 = "VAT", + Name = "Holy See (Vatican City State)", + NumericCode = "336" + }, + new + { + Id = new Guid("0aebadaa-91b2-8794-c153-4f903a2a1004"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Honduras", + Iso2 = "HN", + Iso3 = "HND", + Name = "Honduras", + NumericCode = "340" + }, + new + { + Id = new Guid("500bb0de-61f5-dc9b-0488-1c507456ea4d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Hong Kong Special Administrative Region of China", + Iso2 = "HK", + Iso3 = "HKG", + Name = "Hong Kong", + NumericCode = "344" + }, + new + { + Id = new Guid("dcf19e1d-74a6-7b8b-a5ed-76b94a8ac2a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Hungary", + Iso2 = "HU", + Iso3 = "HUN", + Name = "Hungary", + NumericCode = "348" + }, + new + { + Id = new Guid("4ee6400d-5534-7c67-1521-870d6b732366"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Iceland", + Iso2 = "IS", + Iso3 = "ISL", + Name = "Iceland", + NumericCode = "352" + }, + new + { + Id = new Guid("72d8d1fe-d5f6-f440-1185-82ec69427027"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of India", + Iso2 = "IN", + Iso3 = "IND", + Name = "India", + NumericCode = "356" + }, + new + { + Id = new Guid("1d974338-decf-08e5-3e62-89e1bbdbb003"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Indonesia", + Iso2 = "ID", + Iso3 = "IDN", + Name = "Indonesia", + NumericCode = "360" + }, + new + { + Id = new Guid("b3460bab-2a35-57bc-17e2-4e117748bbb1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Islamic Republic of Iran", + Iso2 = "IR", + Iso3 = "IRN", + Name = "Iran", + NumericCode = "364" + }, + new + { + Id = new Guid("6c8be2e6-8c2e-cd80-68a6-d18c80d0eedc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Iraq", + Iso2 = "IQ", + Iso3 = "IRQ", + Name = "Iraq", + NumericCode = "368" + }, + new + { + Id = new Guid("294978f0-2702-d35d-cfc4-e676148aea2e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Ireland", + Iso2 = "IE", + Iso3 = "IRL", + Name = "Ireland", + NumericCode = "372" + }, + new + { + Id = new Guid("a1b83be0-6a9b-c8a9-2cce-531705a29664"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Isle of Man", + Iso2 = "IM", + Iso3 = "IMN", + Name = "Isle of Man", + NumericCode = "833" + }, + new + { + Id = new Guid("7ffa909b-8a6a-3028-9589-fcc3dfa530a8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Israel", + Iso2 = "IL", + Iso3 = "ISR", + Name = "Israel", + NumericCode = "376" + }, + new + { + Id = new Guid("7bbf15f4-a907-c0b2-7029-144aafb3c59d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Italy", + Iso2 = "IT", + Iso3 = "ITA", + Name = "Italy", + NumericCode = "380" + }, + new + { + Id = new Guid("6699efd5-0939-7812-315e-21f37b279ee9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Jamaica", + Iso2 = "JM", + Iso3 = "JAM", + Name = "Jamaica", + NumericCode = "388" + }, + new + { + Id = new Guid("13c69e56-375d-8a7e-c326-be2be2fd4cd8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Japan", + Iso2 = "JP", + Iso3 = "JPN", + Name = "Japan", + NumericCode = "392" + }, + new + { + Id = new Guid("65d871be-4a1d-a632-9cdb-62e3ff04928d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bailiwick of Jersey", + Iso2 = "JE", + Iso3 = "JEY", + Name = "Jersey", + NumericCode = "832" + }, + new + { + Id = new Guid("9ae7ad80-9ce7-6657-75cf-28b4c0254238"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Hashemite Kingdom of Jordan", + Iso2 = "JO", + Iso3 = "JOR", + Name = "Jordan", + NumericCode = "400" + }, + new + { + Id = new Guid("b723594d-7800-0f37-db86-0f6b85bb6cf9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Kazakhstan", + Iso2 = "KZ", + Iso3 = "KAZ", + Name = "Kazakhstan", + NumericCode = "398" + }, + new + { + Id = new Guid("b32fe2b5-a06e-0d76-ffd2-f186c3e64b15"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Kenya", + Iso2 = "KE", + Iso3 = "KEN", + Name = "Kenya", + NumericCode = "404" + }, + new + { + Id = new Guid("914618fd-86f9-827a-91b8-826f0db9e02d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Kiribati", + Iso2 = "KI", + Iso3 = "KIR", + Name = "Kiribati", + NumericCode = "296" + }, + new + { + Id = new Guid("f70ae426-f130-5637-0383-a5b63a06c500"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic People's Republic of Korea", + Iso2 = "KP", + Iso3 = "PRK", + Name = "Korea", + NumericCode = "408" + }, + new + { + Id = new Guid("7bf934fa-bcf4-80b5-fd7d-ab4cca45c67b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Korea", + Iso2 = "KR", + Iso3 = "KOR", + Name = "Korea", + NumericCode = "410" + }, + new + { + Id = new Guid("b6f70436-9515-7ef8-af57-aad196503499"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Kuwait", + Iso2 = "KW", + Iso3 = "KWT", + Name = "Kuwait", + NumericCode = "414" + }, + new + { + Id = new Guid("0932ed88-c79f-591a-d684-9a77735f947e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kyrgyz Republic", + Iso2 = "KG", + Iso3 = "KGZ", + Name = "Kyrgyz Republic", + NumericCode = "417" + }, + new + { + Id = new Guid("c4754c00-cfa5-aa6f-a9c8-a200457de7a8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Lao People's Democratic Republic", + Iso2 = "LA", + Iso3 = "LAO", + Name = "Lao People's Democratic Republic", + NumericCode = "418" + }, + new + { + Id = new Guid("9205dbfc-60cd-91d9-b0b8-8a18a3755286"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Latvia", + Iso2 = "LV", + Iso3 = "LVA", + Name = "Latvia", + NumericCode = "428" + }, + new + { + Id = new Guid("1e5c0dcc-83e9-f275-c81d-3bc49f88e70c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Lebanese Republic", + Iso2 = "LB", + Iso3 = "LBN", + Name = "Lebanon", + NumericCode = "422" + }, + new + { + Id = new Guid("bf210ee6-6c75-cf08-052e-5c3e608aed15"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Lesotho", + Iso2 = "LS", + Iso3 = "LSO", + Name = "Lesotho", + NumericCode = "426" + }, + new + { + Id = new Guid("ee926d09-799c-7c6a-2419-a6ff814b2c03"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Liberia", + Iso2 = "LR", + Iso3 = "LBR", + Name = "Liberia", + NumericCode = "430" + }, + new + { + Id = new Guid("695c85b3-a6c6-c217-9be8-3baebc7719ce"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Libya", + Iso2 = "LY", + Iso3 = "LBY", + Name = "Libya", + NumericCode = "434" + }, + new + { + Id = new Guid("9d6e6446-185e-235e-8771-9eb2d19f22e7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Principality of Liechtenstein", + Iso2 = "LI", + Iso3 = "LIE", + Name = "Liechtenstein", + NumericCode = "438" + }, + new + { + Id = new Guid("52538361-bbdf-fafb-e434-5655fc7451e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Lithuania", + Iso2 = "LT", + Iso3 = "LTU", + Name = "Lithuania", + NumericCode = "440" + }, + new + { + Id = new Guid("70673250-4cc3-3ba1-a42c-6b62ea8ab1d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Grand Duchy of Luxembourg", + Iso2 = "LU", + Iso3 = "LUX", + Name = "Luxembourg", + NumericCode = "442" + }, + new + { + Id = new Guid("8d32a12d-3230-1431-8fbb-72c789184345"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Macao Special Administrative Region of China", + Iso2 = "MO", + Iso3 = "MAC", + Name = "Macao", + NumericCode = "446" + }, + new + { + Id = new Guid("976e496f-ca38-d113-1697-8af2d9a3b159"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Madagascar", + Iso2 = "MG", + Iso3 = "MDG", + Name = "Madagascar", + NumericCode = "450" + }, + new + { + Id = new Guid("fbf4479d-d70d-c76e-b053-699362443a17"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Malawi", + Iso2 = "MW", + Iso3 = "MWI", + Name = "Malawi", + NumericCode = "454" + }, + new + { + Id = new Guid("d292ea2d-fbb6-7c1e-cb7d-23d552673776"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Malaysia", + Iso2 = "MY", + Iso3 = "MYS", + Name = "Malaysia", + NumericCode = "458" + }, + new + { + Id = new Guid("1d2aa3ab-e1c3-8c76-9be6-7a3b3eca35da"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Maldives", + Iso2 = "MV", + Iso3 = "MDV", + Name = "Maldives", + NumericCode = "462" + }, + new + { + Id = new Guid("c03d71a5-b215-8672-ec0c-dd8fe5c20e05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Mali", + Iso2 = "ML", + Iso3 = "MLI", + Name = "Mali", + NumericCode = "466" + }, + new + { + Id = new Guid("f0219540-8b2c-bd29-4f76-b832de53a56f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Malta", + Iso2 = "MT", + Iso3 = "MLT", + Name = "Malta", + NumericCode = "470" + }, + new + { + Id = new Guid("943d2419-2ca6-95f8-9c3b-ed445aea0371"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Marshall Islands", + Iso2 = "MH", + Iso3 = "MHL", + Name = "Marshall Islands", + NumericCode = "584" + }, + new + { + Id = new Guid("fc78fa89-b372-dcf7-7f1c-1e1bb14ecbe7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Martinique", + Iso2 = "MQ", + Iso3 = "MTQ", + Name = "Martinique", + NumericCode = "474" + }, + new + { + Id = new Guid("74da982f-cf20-e1b4-517b-a040511af23c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Islamic Republic of Mauritania", + Iso2 = "MR", + Iso3 = "MRT", + Name = "Mauritania", + NumericCode = "478" + }, + new + { + Id = new Guid("1b634ca2-2b90-7e54-715a-74cee7e4d294"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Mauritius", + Iso2 = "MU", + Iso3 = "MUS", + Name = "Mauritius", + NumericCode = "480" + }, + new + { + Id = new Guid("08a999e4-e420-b864-2864-bef78c138448"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Mayotte", + Iso2 = "YT", + Iso3 = "MYT", + Name = "Mayotte", + NumericCode = "175" + }, + new + { + Id = new Guid("a9940e91-93ef-19f7-79c0-00d31c6a9f87"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United Mexican States", + Iso2 = "MX", + Iso3 = "MEX", + Name = "Mexico", + NumericCode = "484" + }, + new + { + Id = new Guid("a2da72dc-5866-ba2f-6283-6575af00ade5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federated States of Micronesia", + Iso2 = "FM", + Iso3 = "FSM", + Name = "Micronesia", + NumericCode = "583" + }, + new + { + Id = new Guid("daf6bc7a-92c4-ef47-3111-e13199b86b90"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Moldova", + Iso2 = "MD", + Iso3 = "MDA", + Name = "Moldova", + NumericCode = "498" + }, + new + { + Id = new Guid("5cab34ca-8c74-0766-c7ca-4a826b44c5bd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Principality of Monaco", + Iso2 = "MC", + Iso3 = "MCO", + Name = "Monaco", + NumericCode = "492" + }, + new + { + Id = new Guid("c522b3d3-74cc-846f-0394-737dff4d2b1a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Mongolia", + Iso2 = "MN", + Iso3 = "MNG", + Name = "Mongolia", + NumericCode = "496" + }, + new + { + Id = new Guid("86db2170-be87-fd1d-bf57-05ff61ae83a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Montenegro", + Iso2 = "ME", + Iso3 = "MNE", + Name = "Montenegro", + NumericCode = "499" + }, + new + { + Id = new Guid("50e5954d-7cb4-2201-b96c-f2a846ab3ae3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Montserrat", + Iso2 = "MS", + Iso3 = "MSR", + Name = "Montserrat", + NumericCode = "500" + }, + new + { + Id = new Guid("915805f0-9ff0-48ff-39b3-44a4af5e0482"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Morocco", + Iso2 = "MA", + Iso3 = "MAR", + Name = "Morocco", + NumericCode = "504" + }, + new + { + Id = new Guid("10b58d9b-42ef-edb8-54a3-712636fda55a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Mozambique", + Iso2 = "MZ", + Iso3 = "MOZ", + Name = "Mozambique", + NumericCode = "508" + }, + new + { + Id = new Guid("015a9f83-6e57-bc1e-8227-24a4e5248582"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Union of Myanmar", + Iso2 = "MM", + Iso3 = "MMR", + Name = "Myanmar", + NumericCode = "104" + }, + new + { + Id = new Guid("0c0fef20-0e8d-98ea-7724-12cea9b3b926"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Namibia", + Iso2 = "NA", + Iso3 = "NAM", + Name = "Namibia", + NumericCode = "516" + }, + new + { + Id = new Guid("e3bacefb-d79b-1569-a91c-43d7e4f6f230"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Nauru", + Iso2 = "NR", + Iso3 = "NRU", + Name = "Nauru", + NumericCode = "520" + }, + new + { + Id = new Guid("e81c5db3-401a-e047-001e-045f39bef8ef"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Nepal", + Iso2 = "NP", + Iso3 = "NPL", + Name = "Nepal", + NumericCode = "524" + }, + new + { + Id = new Guid("cfff3443-1378-9c7d-9d58-66146d7f29a6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of the Netherlands", + Iso2 = "NL", + Iso3 = "NLD", + Name = "Netherlands", + NumericCode = "528" + }, + new + { + Id = new Guid("4b0729b6-f698-5730-767c-88e2d36691bb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "New Caledonia", + Iso2 = "NC", + Iso3 = "NCL", + Name = "New Caledonia", + NumericCode = "540" + }, + new + { + Id = new Guid("360e3c61-aaac-fa2f-d731-fc0824c05107"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "New Zealand", + Iso2 = "NZ", + Iso3 = "NZL", + Name = "New Zealand", + NumericCode = "554" + }, + new + { + Id = new Guid("cd0e8275-3def-1de4-8858-61aab36851c4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Nicaragua", + Iso2 = "NI", + Iso3 = "NIC", + Name = "Nicaragua", + NumericCode = "558" + }, + new + { + Id = new Guid("97cd39d5-1aca-8f10-9f5e-3f611d7606d8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Niger", + Iso2 = "NE", + Iso3 = "NER", + Name = "Niger", + NumericCode = "562" + }, + new + { + Id = new Guid("2e1bd9d8-df06-d773-0eb9-98e274b63b43"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federal Republic of Nigeria", + Iso2 = "NG", + Iso3 = "NGA", + Name = "Nigeria", + NumericCode = "566" + }, + new + { + Id = new Guid("3eea06f4-c085-f619-6d52-b76a5f6fd2b6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Niue", + Iso2 = "NU", + Iso3 = "NIU", + Name = "Niue", + NumericCode = "570" + }, + new + { + Id = new Guid("47804b6a-e705-b925-f4fd-4adf6500180b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Norfolk Island", + Iso2 = "NF", + Iso3 = "NFK", + Name = "Norfolk Island", + NumericCode = "574" + }, + new + { + Id = new Guid("aa0f69b2-93aa-ec51-b43b-60145db79e38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of North Macedonia", + Iso2 = "MK", + Iso3 = "MKD", + Name = "North Macedonia", + NumericCode = "807" + }, + new + { + Id = new Guid("6ac64a20-5688-ccd0-4eca-88d8a2560079"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of the Northern Mariana Islands", + Iso2 = "MP", + Iso3 = "MNP", + Name = "Northern Mariana Islands", + NumericCode = "580" + }, + new + { + Id = new Guid("914d7923-3ac5-75e8-c8e2-47d72561e35d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Norway", + Iso2 = "NO", + Iso3 = "NOR", + Name = "Norway", + NumericCode = "578" + }, + new + { + Id = new Guid("6c366974-3672-3a2c-2345-0fda33942304"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Sultanate of Oman", + Iso2 = "OM", + Iso3 = "OMN", + Name = "Oman", + NumericCode = "512" + }, + new + { + Id = new Guid("cc7fabfc-4c2b-d9ff-bb45-003bfc2e468a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Islamic Republic of Pakistan", + Iso2 = "PK", + Iso3 = "PAK", + Name = "Pakistan", + NumericCode = "586" + }, + new + { + Id = new Guid("057884bc-3c2e-dea9-6522-b003c9297f7a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Palau", + Iso2 = "PW", + Iso3 = "PLW", + Name = "Palau", + NumericCode = "585" + }, + new + { + Id = new Guid("d6d31cdd-280a-56bc-24a4-a414028d2b67"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Palestine", + Iso2 = "PS", + Iso3 = "PSE", + Name = "Palestine", + NumericCode = "275" + }, + new + { + Id = new Guid("7bf4a786-3733-c670-e85f-03ee3caa6ef9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Panama", + Iso2 = "PA", + Iso3 = "PAN", + Name = "Panama", + NumericCode = "591" + }, + new + { + Id = new Guid("c926f091-fe96-35b3-56b5-d418d17e0159"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Independent State of Papua New Guinea", + Iso2 = "PG", + Iso3 = "PNG", + Name = "Papua New Guinea", + NumericCode = "598" + }, + new + { + Id = new Guid("db6ce903-ab43-3793-960c-659529bae6df"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Paraguay", + Iso2 = "PY", + Iso3 = "PRY", + Name = "Paraguay", + NumericCode = "600" + }, + new + { + Id = new Guid("75634729-8e4a-4cfd-739d-9f679bfca3ab"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Peru", + Iso2 = "PE", + Iso3 = "PER", + Name = "Peru", + NumericCode = "604" + }, + new + { + Id = new Guid("c93bccaf-1835-3c02-e2ee-c113ced19e43"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Philippines", + Iso2 = "PH", + Iso3 = "PHL", + Name = "Philippines", + NumericCode = "608" + }, + new + { + Id = new Guid("a5d0c9af-2022-2b43-9332-eb6a2ce4305d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Pitcairn Islands", + Iso2 = "PN", + Iso3 = "PCN", + Name = "Pitcairn Islands", + NumericCode = "612" + }, + new + { + Id = new Guid("de503629-2607-b948-e279-0509d8109d0f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Poland", + Iso2 = "PL", + Iso3 = "POL", + Name = "Poland", + NumericCode = "616" + }, + new + { + Id = new Guid("2a039b16-2adf-0fb8-3bdf-fbdf14358d9d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Portuguese Republic", + Iso2 = "PT", + Iso3 = "PRT", + Name = "Portugal", + NumericCode = "620" + }, + new + { + Id = new Guid("cd2c97c3-5473-0719-3803-fcacedfe2ea2"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of Puerto Rico", + Iso2 = "PR", + Iso3 = "PRI", + Name = "Puerto Rico", + NumericCode = "630" + }, + new + { + Id = new Guid("067c9448-9ad0-2c21-a1dc-fbdf5a63d18d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Qatar", + Iso2 = "QA", + Iso3 = "QAT", + Name = "Qatar", + NumericCode = "634" + }, + new + { + Id = new Guid("881b4bb8-b6da-c73e-55c0-c9f31c02aaef"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Réunion", + Iso2 = "RE", + Iso3 = "REU", + Name = "Réunion", + NumericCode = "638" + }, + new + { + Id = new Guid("51aa4900-30a6-91b7-2728-071542a064ff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Romania", + Iso2 = "RO", + Iso3 = "ROU", + Name = "Romania", + NumericCode = "642" + }, + new + { + Id = new Guid("58337ef3-3d24-43e9-a440-832306e7fc07"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Russian Federation", + Iso2 = "RU", + Iso3 = "RUS", + Name = "Russian Federation", + NumericCode = "643" + }, + new + { + Id = new Guid("f5b15ea6-133d-c2c9-7ef9-b0916ea96edb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Rwanda", + Iso2 = "RW", + Iso3 = "RWA", + Name = "Rwanda", + NumericCode = "646" + }, + new + { + Id = new Guid("77f6f69b-ec41-8818-9395-8d39bf09e653"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Barthélemy", + Iso2 = "BL", + Iso3 = "BLM", + Name = "Saint Barthélemy", + NumericCode = "652" + }, + new + { + Id = new Guid("6a76d068-49e1-da80-ddb4-9ef3d11191e6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Helena, Ascension and Tristan da Cunha", + Iso2 = "SH", + Iso3 = "SHN", + Name = "Saint Helena, Ascension and Tristan da Cunha", + NumericCode = "654" + }, + new + { + Id = new Guid("fa633273-9866-840d-9739-c6c957901e46"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federation of Saint Kitts and Nevis", + Iso2 = "KN", + Iso3 = "KNA", + Name = "Saint Kitts and Nevis", + NumericCode = "659" + }, + new + { + Id = new Guid("220e980a-7363-0150-c250-89e83b967fb4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Lucia", + Iso2 = "LC", + Iso3 = "LCA", + Name = "Saint Lucia", + NumericCode = "662" + }, + new + { + Id = new Guid("899c2a9f-f35d-5a49-a6cd-f92531bb2266"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Martin (French part)", + Iso2 = "MF", + Iso3 = "MAF", + Name = "Saint Martin", + NumericCode = "663" + }, + new + { + Id = new Guid("5476986b-11a4-8463-9bd7-0f7354ec7a20"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Pierre and Miquelon", + Iso2 = "PM", + Iso3 = "SPM", + Name = "Saint Pierre and Miquelon", + NumericCode = "666" + }, + new + { + Id = new Guid("2f49855b-ff93-c399-d72a-121f2bf28bc9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Vincent and the Grenadines", + Iso2 = "VC", + Iso3 = "VCT", + Name = "Saint Vincent and the Grenadines", + NumericCode = "670" + }, + new + { + Id = new Guid("a7c4c9db-8fe4-7d43-e830-1a70954970c3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Independent State of Samoa", + Iso2 = "WS", + Iso3 = "WSM", + Name = "Samoa", + NumericCode = "882" + }, + new + { + Id = new Guid("0a25f96f-5173-2fff-a2f8-c6872393edf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of San Marino", + Iso2 = "SM", + Iso3 = "SMR", + Name = "San Marino", + NumericCode = "674" + }, + new + { + Id = new Guid("766c1ebb-78c1-bada-37fb-c45d1bd4baff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic Republic of Sao Tome and Principe", + Iso2 = "ST", + Iso3 = "STP", + Name = "Sao Tome and Principe", + NumericCode = "678" + }, + new + { + Id = new Guid("a8f30b36-4a25-3fb9-c69e-84ce6640d785"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Saudi Arabia", + Iso2 = "SA", + Iso3 = "SAU", + Name = "Saudi Arabia", + NumericCode = "682" + }, + new + { + Id = new Guid("3175ac19-c801-0b87-8e66-7480a40dcf1e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Senegal", + Iso2 = "SN", + Iso3 = "SEN", + Name = "Senegal", + NumericCode = "686" + }, + new + { + Id = new Guid("971c7e66-c6e3-71f4-580a-5caf2852f9f4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Serbia", + Iso2 = "RS", + Iso3 = "SRB", + Name = "Serbia", + NumericCode = "688" + }, + new + { + Id = new Guid("2167da32-4f80-d31d-226c-0551970304eb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Seychelles", + Iso2 = "SC", + Iso3 = "SYC", + Name = "Seychelles", + NumericCode = "690" + }, + new + { + Id = new Guid("b0f4bdfa-17dd-9714-4fe8-3c3b1f010ffa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Sierra Leone", + Iso2 = "SL", + Iso3 = "SLE", + Name = "Sierra Leone", + NumericCode = "694" + }, + new + { + Id = new Guid("3ce3d958-7341-bd79-f294-f2e6907c186c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Singapore", + Iso2 = "SG", + Iso3 = "SGP", + Name = "Singapore", + NumericCode = "702" + }, + new + { + Id = new Guid("141e589a-7046-a265-d2f6-b2f85e6eeadd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Sint Maarten (Dutch part)", + Iso2 = "SX", + Iso3 = "SXM", + Name = "Sint Maarten (Dutch part)", + NumericCode = "534" + }, + new + { + Id = new Guid("3252e51a-5bc1-f065-7101-5b34ba493dc4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Slovakia (Slovak Republic)", + Iso2 = "SK", + Iso3 = "SVK", + Name = "Slovakia (Slovak Republic)", + NumericCode = "703" + }, + new + { + Id = new Guid("357c121b-e28d-1765-e699-cc4ec5ff86fc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Slovenia", + Iso2 = "SI", + Iso3 = "SVN", + Name = "Slovenia", + NumericCode = "705" + }, + new + { + Id = new Guid("7453c201-ecf1-d3dd-0409-e94d0733173b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Solomon Islands", + Iso2 = "SB", + Iso3 = "SLB", + Name = "Solomon Islands", + NumericCode = "090" + }, + new + { + Id = new Guid("802c05db-3866-545d-dc1a-a02c83ea6cf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federal Republic of Somalia", + Iso2 = "SO", + Iso3 = "SOM", + Name = "Somalia", + NumericCode = "706" + }, + new + { + Id = new Guid("ebf38b9a-6fbe-6e82-3977-2c4763bea072"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of South Africa", + Iso2 = "ZA", + Iso3 = "ZAF", + Name = "South Africa", + NumericCode = "710" + }, + new + { + Id = new Guid("6af4d03e-edd0-d98a-bc7e-abc7df87d3dd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "South Georgia and the South Sandwich Islands", + Iso2 = "GS", + Iso3 = "SGS", + Name = "South Georgia and the South Sandwich Islands", + NumericCode = "239" + }, + new + { + Id = new Guid("6aac6f0e-d13a-a629-4c2b-9d6eaf6680e4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of South Sudan", + Iso2 = "SS", + Iso3 = "SSD", + Name = "South Sudan", + NumericCode = "728" + }, + new + { + Id = new Guid("414a34ce-2781-8f96-2bd0-7ada86c8cf38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Spain", + Iso2 = "ES", + Iso3 = "ESP", + Name = "Spain", + NumericCode = "724" + }, + new + { + Id = new Guid("687320c8-e841-c911-6d30-b14eb998feb6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic Socialist Republic of Sri Lanka", + Iso2 = "LK", + Iso3 = "LKA", + Name = "Sri Lanka", + NumericCode = "144" + }, + new + { + Id = new Guid("f0965449-6b15-6c1a-f5cb-ebd2d575c02c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Sudan", + Iso2 = "SD", + Iso3 = "SDN", + Name = "Sudan", + NumericCode = "729" + }, + new + { + Id = new Guid("61ba1844-4d33-84b4-dbac-70718aa91d59"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Suriname", + Iso2 = "SR", + Iso3 = "SUR", + Name = "Suriname", + NumericCode = "740" + }, + new + { + Id = new Guid("d525de3a-aecc-07de-0426-68f32af2968e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Svalbard & Jan Mayen Islands", + Iso2 = "SJ", + Iso3 = "SJM", + Name = "Svalbard & Jan Mayen Islands", + NumericCode = "744" + }, + new + { + Id = new Guid("a32a9fc2-677f-43e0-97aa-9e83943d785c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Eswatini", + Iso2 = "SZ", + Iso3 = "SWZ", + Name = "Eswatini", + NumericCode = "748" + }, + new + { + Id = new Guid("0ab731f0-5326-44be-af3a-20aa33ad0f35"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Sweden", + Iso2 = "SE", + Iso3 = "SWE", + Name = "Sweden", + NumericCode = "752" + }, + new + { + Id = new Guid("37c89068-a8e9-87e8-d651-f86fac63673a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Swiss Confederation", + Iso2 = "CH", + Iso3 = "CHE", + Name = "Switzerland", + NumericCode = "756" + }, + new + { + Id = new Guid("c1a923f6-b9ec-78f7-cc1c-7025e3d69d7d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Syrian Arab Republic", + Iso2 = "SY", + Iso3 = "SYR", + Name = "Syrian Arab Republic", + NumericCode = "760" + }, + new + { + Id = new Guid("875060ca-73f6-af3b-d844-1b1416ce4583"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Taiwan, Province of China", + Iso2 = "TW", + Iso3 = "TWN", + Name = "Taiwan", + NumericCode = "158" + }, + new + { + Id = new Guid("2a848549-9777-cf48-a0f2-b32c6f942096"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Tajikistan", + Iso2 = "TJ", + Iso3 = "TJK", + Name = "Tajikistan", + NumericCode = "762" + }, + new + { + Id = new Guid("4736c1ad-54bd-c8e8-d9ee-492a88268de8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United Republic of Tanzania", + Iso2 = "TZ", + Iso3 = "TZA", + Name = "Tanzania", + NumericCode = "834" + }, + new + { + Id = new Guid("84d58b3d-d131-1506-0792-1b3228b6f71f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Thailand", + Iso2 = "TH", + Iso3 = "THA", + Name = "Thailand", + NumericCode = "764" + }, + new + { + Id = new Guid("fb9a713c-2de1-882a-64b7-0e8fef5d2f7e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic Republic of Timor-Leste", + Iso2 = "TL", + Iso3 = "TLS", + Name = "Timor-Leste", + NumericCode = "626" + }, + new + { + Id = new Guid("9dacf00b-7d0a-d744-cc60-e5fa66371e9d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Togolese Republic", + Iso2 = "TG", + Iso3 = "TGO", + Name = "Togo", + NumericCode = "768" + }, + new + { + Id = new Guid("11765ad0-30f2-bab8-b616-20f88b28b21e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Tokelau", + Iso2 = "TK", + Iso3 = "TKL", + Name = "Tokelau", + NumericCode = "772" + }, + new + { + Id = new Guid("9e7dbdc3-2c8b-e8ae-082b-e02695f8268e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Tonga", + Iso2 = "TO", + Iso3 = "TON", + Name = "Tonga", + NumericCode = "776" + }, + new + { + Id = new Guid("95467997-f989-f456-34b7-0b578302dcba"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Trinidad and Tobago", + Iso2 = "TT", + Iso3 = "TTO", + Name = "Trinidad and Tobago", + NumericCode = "780" + }, + new + { + Id = new Guid("06f8ad57-7133-9a5e-5a83-53052012b014"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Tunisian Republic", + Iso2 = "TN", + Iso3 = "TUN", + Name = "Tunisia", + NumericCode = "788" + }, + new + { + Id = new Guid("f39cca22-449e-9866-3a65-465a5510483e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Türkiye", + Iso2 = "TR", + Iso3 = "TUR", + Name = "Türkiye", + NumericCode = "792" + }, + new + { + Id = new Guid("550ca5df-3995-617c-c39d-437beb400a42"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Turkmenistan", + Iso2 = "TM", + Iso3 = "TKM", + Name = "Turkmenistan", + NumericCode = "795" + }, + new + { + Id = new Guid("0e0fefd5-9a05-fde5-bee9-ef56db7748a1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Turks and Caicos Islands", + Iso2 = "TC", + Iso3 = "TCA", + Name = "Turks and Caicos Islands", + NumericCode = "796" + }, + new + { + Id = new Guid("e0d562ca-f573-3c2f-eb83-f72d4d70d4fc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Tuvalu", + Iso2 = "TV", + Iso3 = "TUV", + Name = "Tuvalu", + NumericCode = "798" + }, + new + { + Id = new Guid("3e2cccbe-1615-c707-a97b-421a799b2559"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Uganda", + Iso2 = "UG", + Iso3 = "UGA", + Name = "Uganda", + NumericCode = "800" + }, + new + { + Id = new Guid("e087f51c-feba-19b6-5595-fcbdce170411"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Ukraine", + Iso2 = "UA", + Iso3 = "UKR", + Name = "Ukraine", + NumericCode = "804" + }, + new + { + Id = new Guid("29201cbb-ca65-1924-75a9-0c4d4db43001"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United Arab Emirates", + Iso2 = "AE", + Iso3 = "ARE", + Name = "United Arab Emirates", + NumericCode = "784" + }, + new + { + Id = new Guid("0b3b04b4-9782-79e3-bc55-9ab33b6ae9c7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United Kingdom of Great Britain & Northern Ireland", + Iso2 = "GB", + Iso3 = "GBR", + Name = "United Kingdom of Great Britain and Northern Ireland", + NumericCode = "826" + }, + new + { + Id = new Guid("cb2e209b-d4c6-6d5c-8901-d989a9188783"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United States of America", + Iso2 = "US", + Iso3 = "USA", + Name = "United States of America", + NumericCode = "840" + }, + new + { + Id = new Guid("0868cdd3-7f50-5a25-88d6-98c45f9157e3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United States Minor Outlying Islands", + Iso2 = "UM", + Iso3 = "UMI", + Name = "United States Minor Outlying Islands", + NumericCode = "581" + }, + new + { + Id = new Guid("e1947bdc-ff2c-d2c1-3c55-f1f9bf778578"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United States Virgin Islands", + Iso2 = "VI", + Iso3 = "VIR", + Name = "United States Virgin Islands", + NumericCode = "850" + }, + new + { + Id = new Guid("8e787470-aae6-575a-fe0b-d65fc78b648a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Eastern Republic of Uruguay", + Iso2 = "UY", + Iso3 = "URY", + Name = "Uruguay", + NumericCode = "858" + }, + new + { + Id = new Guid("357369e3-85a8-86f7-91c7-349772ae7744"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Uzbekistan", + Iso2 = "UZ", + Iso3 = "UZB", + Name = "Uzbekistan", + NumericCode = "860" + }, + new + { + Id = new Guid("c98174ef-8198-54ba-2ff1-b93f3c646db8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Vanuatu", + Iso2 = "VU", + Iso3 = "VUT", + Name = "Vanuatu", + NumericCode = "548" + }, + new + { + Id = new Guid("52d9992c-19bd-82b4-9188-11dabcac6171"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bolivarian Republic of Venezuela", + Iso2 = "VE", + Iso3 = "VEN", + Name = "Venezuela", + NumericCode = "862" + }, + new + { + Id = new Guid("d7236157-d5a7-6b7a-3bc1-69802313fa30"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Socialist Republic of Vietnam", + Iso2 = "VN", + Iso3 = "VNM", + Name = "Vietnam", + NumericCode = "704" + }, + new + { + Id = new Guid("e186a953-7ab3-c009-501c-a754267b770b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Wallis and Futuna", + Iso2 = "WF", + Iso3 = "WLF", + Name = "Wallis and Futuna", + NumericCode = "876" + }, + new + { + Id = new Guid("2f4cc994-53f1-1763-8220-5d89e063804f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Western Sahara", + Iso2 = "EH", + Iso3 = "ESH", + Name = "Western Sahara", + NumericCode = "732" + }, + new + { + Id = new Guid("8c4441fd-8cd4-ff1e-928e-e46f9ca12552"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Yemen", + Iso2 = "YE", + Iso3 = "YEM", + Name = "Yemen", + NumericCode = "887" + }, + new + { + Id = new Guid("ab0b7e83-bf02-16e6-e5ae-46c4bd4c093b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Zambia", + Iso2 = "ZM", + Iso3 = "ZMB", + Name = "Zambia", + NumericCode = "894" + }, + new + { + Id = new Guid("6984f722-6963-d067-d4d4-9fd3ef2edbf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Zimbabwe", + Iso2 = "ZW", + Iso3 = "ZWE", + Name = "Zimbabwe", + NumericCode = "716" + }); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CitizenReportingEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("CountryId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("EnglishTitle") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringNgoForCitizenReportingId") + .HasColumnType("uuid"); + + b.Property("PollingStationsVersion") + .HasColumnType("uuid"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("CountryId"); + + b.HasIndex("MonitoringNgoForCitizenReportingId"); + + b.ToTable("ElectionRounds"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ExportedDataAggregate.ExportedData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Base64EncodedData") + .HasColumnType("text"); + + b.Property("CompletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("ExportStatus") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExportedDataType") + .IsRequired() + .HasColumnType("text"); + + b.Property("FileName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("StartedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("Id"); + + b.ToTable("ExportedData", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FeedbackAggregate.Feedback", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property>("Metadata") + .IsRequired() + .HasColumnType("hstore"); + + b.Property("ObserverId") + .HasColumnType("uuid"); + + b.Property("TimeSubmitted") + .HasColumnType("timestamp with time zone"); + + b.Property("UserFeedback") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("ObserverId"); + + b.ToTable("UserFeedback"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormAggregate.Form", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DefaultLanguage") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Languages") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("LanguagesTranslationStatus") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringNgoId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("NumberOfQuestions") + .HasColumnType("integer"); + + b.Property("Questions") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("MonitoringNgoId"); + + b.ToTable("Forms"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormSubmissionAggregate.FormSubmission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Answers") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FollowUpStatus") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("NotApplicable"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("NumberOfFlaggedAnswers") + .HasColumnType("integer"); + + b.Property("NumberOfQuestionsAnswered") + .HasColumnType("integer"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("FormId"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.HasIndex("ElectionRoundId", "PollingStationId", "MonitoringObserverId", "FormId") + .IsUnique(); + + b.ToTable("FormSubmissions", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormTemplateAggregate.FormTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DefaultLanguage") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("FormTemplateType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Languages") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("NumberOfQuestions") + .HasColumnType("integer"); + + b.Property("Questions") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("FormTemplates"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ImportValidationErrorsAggregate.ImportValidationErrors", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Data") + .IsRequired() + .HasColumnType("text"); + + b.Property("ImportType") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("OriginalFileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("Id"); + + b.ToTable("ImportValidationErrors"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.LanguageAggregate.Language", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Iso1") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("character varying(2)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NativeName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("Id"); + + b.HasIndex("Iso1") + .IsUnique(); + + b.ToTable("Language"); + + b.HasData( + new + { + Id = new Guid("9c11bb58-5135-453a-1d24-dc20ef0e9031"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AA", + Name = "Afar", + NativeName = "Afaraf" + }, + new + { + Id = new Guid("bd4f1638-6017-733d-f696-b8b4d72664d7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AB", + Name = "Abkhaz", + NativeName = "аҧсуа бызшәа" + }, + new + { + Id = new Guid("29201cbb-ca65-1924-75a9-0c4d4db43001"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AE", + Name = "Avestan", + NativeName = "avesta" + }, + new + { + Id = new Guid("edd4319b-86f3-24cb-248c-71da624c02f7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AF", + Name = "Afrikaans", + NativeName = "Afrikaans" + }, + new + { + Id = new Guid("ef584e3c-03f2-42b0-7139-69d15d21e5a8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AK", + Name = "Akan", + NativeName = "Akan" + }, + new + { + Id = new Guid("688af4c8-9d64-ae1c-147f-b8afd54801e3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AM", + Name = "Amharic", + NativeName = "አማርኛ" + }, + new + { + Id = new Guid("d4d5c45a-d3c2-891e-6d7d-75569c3386ac"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AN", + Name = "Aragonese", + NativeName = "aragonés" + }, + new + { + Id = new Guid("a7afb7b1-b26d-4571-1a1f-3fff738ff21e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AR", + Name = "Arabic", + NativeName = "اَلْعَرَبِيَّةُ" + }, + new + { + Id = new Guid("538114de-7db0-9242-35e6-324fa7eff44d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AS", + Name = "Assamese", + NativeName = "অসমীয়া" + }, + new + { + Id = new Guid("e43a2010-14fc-63a9-f9d3-0ab2a1d0e52f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AV", + Name = "Avaric", + NativeName = "авар мацӀ" + }, + new + { + Id = new Guid("78c6e8af-fcb4-c783-987c-7e1aca3aed64"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AY", + Name = "Aymara", + NativeName = "aymar aru" + }, + new + { + Id = new Guid("008c3138-73d8-dbbc-f1dd-521e4c68bcf1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AZ", + Name = "Azerbaijani", + NativeName = "azərbaycan dili" + }, + new + { + Id = new Guid("a7716d29-6ef6-b775-51c5-97094536329d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BA", + Name = "Bashkir", + NativeName = "башҡорт теле" + }, + new + { + Id = new Guid("0797a7d5-bbc0-2e52-0de8-14a42fc80baa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BE", + Name = "Belarusian", + NativeName = "беларуская мова" + }, + new + { + Id = new Guid("46576b73-c05b-7498-5b07-9bbf59b7645d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BG", + Name = "Bulgarian", + NativeName = "български език" + }, + new + { + Id = new Guid("75e4464b-a784-63b8-1ecc-69ee1f09f43f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BI", + Name = "Bislama", + NativeName = "Bislama" + }, + new + { + Id = new Guid("ca2a5560-d4c4-3c87-3090-6f5436310b55"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BM", + Name = "Bambara", + NativeName = "bamanankan" + }, + new + { + Id = new Guid("ed6278e0-436c-9fd9-0b9e-44fd424cbd1b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BN", + Name = "Bengali", + NativeName = "বাংলা" + }, + new + { + Id = new Guid("f33ced84-eb43-fb39-ef79-b266e4d4cd94"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BO", + Name = "Tibetan", + NativeName = "བོད་ཡིག" + }, + new + { + Id = new Guid("5283afbb-2744-e930-2c16-c5ea6b0ff7cc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BR", + Name = "Breton", + NativeName = "brezhoneg" + }, + new + { + Id = new Guid("46e88019-c521-57b2-d1c0-c0e2478d3b05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BS", + Name = "Bosnian", + NativeName = "bosanski jezik" + }, + new + { + Id = new Guid("5c0e654b-8547-5d02-ee7b-d65e3c5c5273"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CA", + Name = "Catalan", + NativeName = "Català" + }, + new + { + Id = new Guid("cd5689d6-7a06-73c7-650e-f6f94387fd88"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CE", + Name = "Chechen", + NativeName = "нохчийн мотт" + }, + new + { + Id = new Guid("37c89068-a8e9-87e8-d651-f86fac63673a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CH", + Name = "Chamorro", + NativeName = "Chamoru" + }, + new + { + Id = new Guid("c64288fc-d941-0615-47f9-28e6c294ce26"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CO", + Name = "Corsican", + NativeName = "corsu" + }, + new + { + Id = new Guid("d13935c1-8956-1399-7c4e-0354795cd37b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CR", + Name = "Cree", + NativeName = "ᓀᐦᐃᔭᐍᐏᐣ" + }, + new + { + Id = new Guid("4def223a-9524-596d-cc29-ab7830c590de"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CS", + Name = "Czech", + NativeName = "čeština" + }, + new + { + Id = new Guid("57765d87-2424-2c86-ad9c-1af58ef3127a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CU", + Name = "Old Church Slavonic", + NativeName = "ѩзыкъ словѣньскъ" + }, + new + { + Id = new Guid("17ed5f0f-e091-94ff-0512-ad291bde94d7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CV", + Name = "Chuvash", + NativeName = "чӑваш чӗлхи" + }, + new + { + Id = new Guid("df20d0d7-9fbe-e725-d966-4fdf9f5c9dfb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CY", + Name = "Welsh", + NativeName = "Cymraeg" + }, + new + { + Id = new Guid("b356a541-1383-3c0a-9afd-6aebae3753cb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "DA", + Name = "Danish", + NativeName = "dansk" + }, + new + { + Id = new Guid("46ef1468-86f6-0c99-f4e9-46f966167b05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "DE", + Name = "German", + NativeName = "Deutsch" + }, + new + { + Id = new Guid("d8d4f63d-fa65-63dd-a788-de2eec3d24ec"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "DV", + Name = "Divehi", + NativeName = "ދިވެހި" + }, + new + { + Id = new Guid("fee6f04f-c4c1-e3e4-645d-bb6bb703aeb7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "DZ", + Name = "Dzongkha", + NativeName = "རྫོང་ཁ" + }, + new + { + Id = new Guid("2dc643bd-cc6c-eb0c-7314-44123576f0ee"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EE", + Name = "Ewe", + NativeName = "Eʋegbe" + }, + new + { + Id = new Guid("b9da7f73-60cd-404c-18fb-1bc5bbfffb38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EL", + Name = "Greek", + NativeName = "Ελληνικά" + }, + new + { + Id = new Guid("094b3769-68b1-6211-ba2d-6bba92d6a167"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EN", + Name = "English", + NativeName = "English" + }, + new + { + Id = new Guid("1da84244-fa39-125e-06dc-3c0cb2342ce9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EO", + Name = "Esperanto", + NativeName = "Esperanto" + }, + new + { + Id = new Guid("414a34ce-2781-8f96-2bd0-7ada86c8cf38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ES", + Name = "Spanish", + NativeName = "Español" + }, + new + { + Id = new Guid("e75515a6-63cf-3612-a3a2-befa0d7048a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ET", + Name = "Estonian", + NativeName = "eesti" + }, + new + { + Id = new Guid("b2a87091-32fb-ba34-a721-bf8b3de5935d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EU", + Name = "Basque", + NativeName = "euskara" + }, + new + { + Id = new Guid("e9da8997-dee8-0c2d-79d3-05fafc45092e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FA", + Name = "Persian", + NativeName = "فارسی" + }, + new + { + Id = new Guid("51a86a09-0d0b-31c1-90f1-f237db8e29ad"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FF", + Name = "Fula", + NativeName = "Fulfulde" + }, + new + { + Id = new Guid("5a5d9168-081b-1e02-1fbb-cdfa910e526c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FI", + Name = "Finnish", + NativeName = "suomi" + }, + new + { + Id = new Guid("0e2a1681-d852-67ae-7387-0d04be9e7fd3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FJ", + Name = "Fijian", + NativeName = "vosa Vakaviti" + }, + new + { + Id = new Guid("0d4fe6e6-ea1e-d1ce-5134-6c0c1a696a00"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FO", + Name = "Faroese", + NativeName = "føroyskt" + }, + new + { + Id = new Guid("b2261c50-1a57-7f1f-d72d-f8c21593874f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FR", + Name = "French", + NativeName = "Français" + }, + new + { + Id = new Guid("fb429393-f994-0a16-37f9-edc0510fced5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FY", + Name = "Western Frisian", + NativeName = "Frysk" + }, + new + { + Id = new Guid("4826bc0f-235e-572f-2b1a-21f1c9e05f83"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GA", + Name = "Irish", + NativeName = "Gaeilge" + }, + new + { + Id = new Guid("ff5b4d88-c179-ff0d-6285-cf46ba475d7d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GD", + Name = "Scottish Gaelic", + NativeName = "Gàidhlig" + }, + new + { + Id = new Guid("2f00fe86-a06b-dc95-0ea7-4520d1dec784"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GL", + Name = "Galician", + NativeName = "galego" + }, + new + { + Id = new Guid("3ffe68ca-7350-175b-4e95-0c34f54dc1f4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GN", + Name = "Guaraní", + NativeName = "Avañe'ẽ" + }, + new + { + Id = new Guid("096a8586-9702-6fec-5f6a-6eb3b7b7837f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GU", + Name = "Gujarati", + NativeName = "ગુજરાતી" + }, + new + { + Id = new Guid("849b5e66-dc68-a1ed-6ed3-e315fbd0a0e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GV", + Name = "Manx", + NativeName = "Gaelg" + }, + new + { + Id = new Guid("2e9cb133-68a7-2f3b-49d1-0921cf42dfae"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HA", + Name = "Hausa", + NativeName = "هَوُسَ" + }, + new + { + Id = new Guid("d685aa26-aee7-716b-9433-1b3411209f4b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HE", + Name = "Hebrew", + NativeName = "עברית" + }, + new + { + Id = new Guid("54686fcd-3f35-f468-7c9c-93217c5084bc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HI", + Name = "Hindi", + NativeName = "हिन्दी" + }, + new + { + Id = new Guid("87813ec7-4830-e4dc-5ab1-bd599057ede0"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HO", + Name = "Hiri Motu", + NativeName = "Hiri Motu" + }, + new + { + Id = new Guid("1f8be615-5746-277e-d82b-47596b5bb922"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HR", + Name = "Croatian", + NativeName = "Hrvatski" + }, + new + { + Id = new Guid("2bebebe4-edaa-9160-5a0c-4d99048bd8d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HT", + Name = "Haitian", + NativeName = "Kreyòl ayisyen" + }, + new + { + Id = new Guid("dcf19e1d-74a6-7b8b-a5ed-76b94a8ac2a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HU", + Name = "Hungarian", + NativeName = "magyar" + }, + new + { + Id = new Guid("d832c50a-112e-4591-9432-4ada24bc85b2"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HY", + Name = "Armenian", + NativeName = "Հայերեն" + }, + new + { + Id = new Guid("d5bffdfb-6a8e-6d9f-2e59-4ada912acdba"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HZ", + Name = "Herero", + NativeName = "Otjiherero" + }, + new + { + Id = new Guid("7f065da7-4ba4-81ca-5126-dbf606a73907"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IA", + Name = "Interlingua", + NativeName = "Interlingua" + }, + new + { + Id = new Guid("1d974338-decf-08e5-3e62-89e1bbdbb003"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ID", + Name = "Indonesian", + NativeName = "Bahasa Indonesia" + }, + new + { + Id = new Guid("294978f0-2702-d35d-cfc4-e676148aea2e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IE", + Name = "Interlingue", + NativeName = "Interlingue" + }, + new + { + Id = new Guid("caddae27-283a-82b2-9365-76a3d6c49eee"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IG", + Name = "Igbo", + NativeName = "Asụsụ Igbo" + }, + new + { + Id = new Guid("f21f562e-5c35-4806-4efc-416619b5b7f7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "II", + Name = "Nuosu", + NativeName = "ꆈꌠ꒿ Nuosuhxop" + }, + new + { + Id = new Guid("23785991-fef4-e625-4d3b-b6ac364d0fa0"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IK", + Name = "Inupiaq", + NativeName = "Iñupiaq" + }, + new + { + Id = new Guid("b8b09512-ea4c-4a61-9331-304f55324ef7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IO", + Name = "Ido", + NativeName = "Ido" + }, + new + { + Id = new Guid("4ee6400d-5534-7c67-1521-870d6b732366"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IS", + Name = "Icelandic", + NativeName = "Íslenska" + }, + new + { + Id = new Guid("7bbf15f4-a907-c0b2-7029-144aafb3c59d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IT", + Name = "Italian", + NativeName = "Italiano" + }, + new + { + Id = new Guid("899392d7-d54f-a1c6-407a-1bada9b85fdd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IU", + Name = "Inuktitut", + NativeName = "ᐃᓄᒃᑎᑐᑦ" + }, + new + { + Id = new Guid("6857242c-f772-38b5-b5a2-c8e8b9db551f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "JA", + Name = "Japanese", + NativeName = "日本語" + }, + new + { + Id = new Guid("e7532b00-3b1b-ff2c-b7c0-26bd7e91af55"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "JV", + Name = "Javanese", + NativeName = "basa Jawa" + }, + new + { + Id = new Guid("9204928b-c569-ef6a-446e-4853aee439b0"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KA", + Name = "Georgian", + NativeName = "ქართული" + }, + new + { + Id = new Guid("0932ed88-c79f-591a-d684-9a77735f947e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KG", + Name = "Kongo", + NativeName = "Kikongo" + }, + new + { + Id = new Guid("914618fd-86f9-827a-91b8-826f0db9e02d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KI", + Name = "Kikuyu", + NativeName = "Gĩkũyũ" + }, + new + { + Id = new Guid("80ecea2c-8969-1929-0d4a-39ed2324abc6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KJ", + Name = "Kwanyama", + NativeName = "Kuanyama" + }, + new + { + Id = new Guid("b6b2351f-4f1e-c92f-0e9a-a915f4cc5fa6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KK", + Name = "Kazakh", + NativeName = "қазақ тілі" + }, + new + { + Id = new Guid("081a5fdb-445a-015a-1e36-f2e5014265ae"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KL", + Name = "Kalaallisut", + NativeName = "kalaallisut" + }, + new + { + Id = new Guid("5e7a08f2-7d59-bcdb-7ddd-876b87181420"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KM", + Name = "Khmer", + NativeName = "ខេមរភាសា" + }, + new + { + Id = new Guid("fa633273-9866-840d-9739-c6c957901e46"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KN", + Name = "Kannada", + NativeName = "ಕನ್ನಡ" + }, + new + { + Id = new Guid("74f19a84-b1c5-fa2d-8818-2220b80a3056"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KO", + Name = "Korean", + NativeName = "한국어" + }, + new + { + Id = new Guid("7bf934fa-bcf4-80b5-fd7d-ab4cca45c67b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KR", + Name = "Kanuri", + NativeName = "Kanuri" + }, + new + { + Id = new Guid("eace47f6-5499-f4f0-8f97-ed165b681d84"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KS", + Name = "Kashmiri", + NativeName = "कश्मीरी" + }, + new + { + Id = new Guid("7451108d-ad49-940a-d479-4d868b62a7c6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KU", + Name = "Kurdish", + NativeName = "Kurdî" + }, + new + { + Id = new Guid("78b7020d-8b82-3fae-2049-30e490ae1faf"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KV", + Name = "Komi", + NativeName = "коми кыв" + }, + new + { + Id = new Guid("b6f70436-9515-7ef8-af57-aad196503499"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KW", + Name = "Cornish", + NativeName = "Kernewek" + }, + new + { + Id = new Guid("3c5828e0-16a8-79ba-4e5c-9b45065df113"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KY", + Name = "Kyrgyz", + NativeName = "Кыргызча" + }, + new + { + Id = new Guid("c4754c00-cfa5-aa6f-a9c8-a200457de7a8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LA", + Name = "Latin", + NativeName = "latine" + }, + new + { + Id = new Guid("1e5c0dcc-83e9-f275-c81d-3bc49f88e70c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LB", + Name = "Luxembourgish", + NativeName = "Lëtzebuergesch" + }, + new + { + Id = new Guid("80b770b8-4797-3d62-ef66-1ded7b0da0e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LG", + Name = "Ganda", + NativeName = "Luganda" + }, + new + { + Id = new Guid("9d6e6446-185e-235e-8771-9eb2d19f22e7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LI", + Name = "Limburgish", + NativeName = "Limburgs" + }, + new + { + Id = new Guid("ca44a869-d3b6-052d-1e1a-ad4e3682a2ed"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LN", + Name = "Lingala", + NativeName = "Lingála" + }, + new + { + Id = new Guid("e9ad0bec-7dee-bd01-9528-1fc74d1d78dd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LO", + Name = "Lao", + NativeName = "ພາສາລາວ" + }, + new + { + Id = new Guid("52538361-bbdf-fafb-e434-5655fc7451e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LT", + Name = "Lithuanian", + NativeName = "lietuvių kalba" + }, + new + { + Id = new Guid("70673250-4cc3-3ba1-a42c-6b62ea8ab1d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LU", + Name = "Luba-Katanga", + NativeName = "Kiluba" + }, + new + { + Id = new Guid("9205dbfc-60cd-91d9-b0b8-8a18a3755286"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LV", + Name = "Latvian", + NativeName = "latviešu valoda" + }, + new + { + Id = new Guid("976e496f-ca38-d113-1697-8af2d9a3b159"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MG", + Name = "Malagasy", + NativeName = "fiteny malagasy" + }, + new + { + Id = new Guid("943d2419-2ca6-95f8-9c3b-ed445aea0371"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MH", + Name = "Marshallese", + NativeName = "Kajin M̧ajeļ" + }, + new + { + Id = new Guid("54726f17-03b8-8af3-0359-c42d8fe8459d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MI", + Name = "Māori", + NativeName = "te reo Māori" + }, + new + { + Id = new Guid("aa0f69b2-93aa-ec51-b43b-60145db79e38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MK", + Name = "Macedonian", + NativeName = "македонски јазик" + }, + new + { + Id = new Guid("c03d71a5-b215-8672-ec0c-dd8fe5c20e05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ML", + Name = "Malayalam", + NativeName = "മലയാളം" + }, + new + { + Id = new Guid("c522b3d3-74cc-846f-0394-737dff4d2b1a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MN", + Name = "Mongolian", + NativeName = "Монгол хэл" + }, + new + { + Id = new Guid("74da982f-cf20-e1b4-517b-a040511af23c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MR", + Name = "Marathi", + NativeName = "मराठी" + }, + new + { + Id = new Guid("50e5954d-7cb4-2201-b96c-f2a846ab3ae3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MS", + Name = "Malay", + NativeName = "Bahasa Melayu" + }, + new + { + Id = new Guid("f0219540-8b2c-bd29-4f76-b832de53a56f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MT", + Name = "Maltese", + NativeName = "Malti" + }, + new + { + Id = new Guid("d292ea2d-fbb6-7c1e-cb7d-23d552673776"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MY", + Name = "Burmese", + NativeName = "ဗမာစာ" + }, + new + { + Id = new Guid("0c0fef20-0e8d-98ea-7724-12cea9b3b926"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NA", + Name = "Nauru", + NativeName = "Dorerin Naoero" + }, + new + { + Id = new Guid("4a3aa5a4-473f-45cd-f054-fa0465c476a4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NB", + Name = "Norwegian Bokmål", + NativeName = "Norsk bokmål" + }, + new + { + Id = new Guid("b4292ad3-3ca8-eea5-f3e0-d1983db8f61e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ND", + Name = "Northern Ndebele", + NativeName = "isiNdebele" + }, + new + { + Id = new Guid("97cd39d5-1aca-8f10-9f5e-3f611d7606d8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NE", + Name = "Nepali", + NativeName = "नेपाली" + }, + new + { + Id = new Guid("2e1bd9d8-df06-d773-0eb9-98e274b63b43"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NG", + Name = "Ndonga", + NativeName = "Owambo" + }, + new + { + Id = new Guid("cfff3443-1378-9c7d-9d58-66146d7f29a6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NL", + Name = "Dutch", + NativeName = "Nederlands" + }, + new + { + Id = new Guid("df41c815-40f8-197a-7a8b-e456d43283d9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NN", + Name = "Norwegian Nynorsk", + NativeName = "Norsk nynorsk" + }, + new + { + Id = new Guid("914d7923-3ac5-75e8-c8e2-47d72561e35d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NO", + Name = "Norwegian", + NativeName = "Norsk" + }, + new + { + Id = new Guid("e3bacefb-d79b-1569-a91c-43d7e4f6f230"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NR", + Name = "Southern Ndebele", + NativeName = "isiNdebele" + }, + new + { + Id = new Guid("67729f87-ef47-dd3f-65f7-b0f6df0d6384"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NV", + Name = "Navajo", + NativeName = "Diné bizaad" + }, + new + { + Id = new Guid("720b4e12-b001-8d38-7c07-f43194b9645d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NY", + Name = "Chichewa", + NativeName = "chiCheŵa" + }, + new + { + Id = new Guid("2b6d383a-9ab6-fcdf-bcfe-a4538faca407"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OC", + Name = "Occitan", + NativeName = "occitan" + }, + new + { + Id = new Guid("9ec46cb5-6c2b-0e22-07c5-eb2fe1b8d2ff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OJ", + Name = "Ojibwe", + NativeName = "ᐊᓂᔑᓈᐯᒧᐎᓐ" + }, + new + { + Id = new Guid("6c366974-3672-3a2c-2345-0fda33942304"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OM", + Name = "Oromo", + NativeName = "Afaan Oromoo" + }, + new + { + Id = new Guid("285b9e82-38af-33ab-79fd-0b4f3fd4f2f1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OR", + Name = "Oriya", + NativeName = "ଓଡ଼ିଆ" + }, + new + { + Id = new Guid("2d013d34-b258-8fe9-ef52-dd34e82a4672"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OS", + Name = "Ossetian", + NativeName = "ирон æвзаг" + }, + new + { + Id = new Guid("7bf4a786-3733-c670-e85f-03ee3caa6ef9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PA", + Name = "Panjabi", + NativeName = "ਪੰਜਾਬੀ" + }, + new + { + Id = new Guid("d8ef067c-1087-4ff5-8e1f-2291df7ac958"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PI", + Name = "Pāli", + NativeName = "पाऴि" + }, + new + { + Id = new Guid("de503629-2607-b948-e279-0509d8109d0f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PL", + Name = "Polish", + NativeName = "Polski" + }, + new + { + Id = new Guid("d6d31cdd-280a-56bc-24a4-a414028d2b67"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PS", + Name = "Pashto", + NativeName = "پښتو" + }, + new + { + Id = new Guid("2a039b16-2adf-0fb8-3bdf-fbdf14358d9d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PT", + Name = "Portuguese", + NativeName = "Português" + }, + new + { + Id = new Guid("93fb8ace-4156-12d5-218e-64b7d35129b1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "QU", + Name = "Quechua", + NativeName = "Runa Simi" + }, + new + { + Id = new Guid("136610e1-8115-9cf1-d671-7950c6483495"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RM", + Name = "Romansh", + NativeName = "rumantsch grischun" + }, + new + { + Id = new Guid("7a0725cf-311a-4f59-cff8-ad8b43dd226e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RN", + Name = "Kirundi", + NativeName = "Ikirundi" + }, + new + { + Id = new Guid("51aa4900-30a6-91b7-2728-071542a064ff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RO", + Name = "Romanian", + NativeName = "Română" + }, + new + { + Id = new Guid("58337ef3-3d24-43e9-a440-832306e7fc07"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RU", + Name = "Russian", + NativeName = "Русский" + }, + new + { + Id = new Guid("f5b15ea6-133d-c2c9-7ef9-b0916ea96edb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RW", + Name = "Kinyarwanda", + NativeName = "Ikinyarwanda" + }, + new + { + Id = new Guid("a8f30b36-4a25-3fb9-c69e-84ce6640d785"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SA", + Name = "Sanskrit", + NativeName = "संस्कृतम्" + }, + new + { + Id = new Guid("2167da32-4f80-d31d-226c-0551970304eb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SC", + Name = "Sardinian", + NativeName = "sardu" + }, + new + { + Id = new Guid("f0965449-6b15-6c1a-f5cb-ebd2d575c02c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SD", + Name = "Sindhi", + NativeName = "सिन्धी" + }, + new + { + Id = new Guid("0ab731f0-5326-44be-af3a-20aa33ad0f35"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SE", + Name = "Northern Sami", + NativeName = "Davvisámegiella" + }, + new + { + Id = new Guid("3ce3d958-7341-bd79-f294-f2e6907c186c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SG", + Name = "Sango", + NativeName = "yângâ tî sängö" + }, + new + { + Id = new Guid("357c121b-e28d-1765-e699-cc4ec5ff86fc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SI", + Name = "Sinhala", + NativeName = "සිංහල" + }, + new + { + Id = new Guid("3252e51a-5bc1-f065-7101-5b34ba493dc4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SK", + Name = "Slovak", + NativeName = "slovenčina" + }, + new + { + Id = new Guid("b0f4bdfa-17dd-9714-4fe8-3c3b1f010ffa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SL", + Name = "Slovenian", + NativeName = "slovenščina" + }, + new + { + Id = new Guid("0a25f96f-5173-2fff-a2f8-c6872393edf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SM", + Name = "Samoan", + NativeName = "gagana fa'a Samoa" + }, + new + { + Id = new Guid("3175ac19-c801-0b87-8e66-7480a40dcf1e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SN", + Name = "Shona", + NativeName = "chiShona" + }, + new + { + Id = new Guid("802c05db-3866-545d-dc1a-a02c83ea6cf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SO", + Name = "Somali", + NativeName = "Soomaaliga" + }, + new + { + Id = new Guid("fb1cce84-4a6c-1834-0ff2-6df002e3d56f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SQ", + Name = "Albanian", + NativeName = "Shqip" + }, + new + { + Id = new Guid("61ba1844-4d33-84b4-dbac-70718aa91d59"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SR", + Name = "Serbian", + NativeName = "српски језик" + }, + new + { + Id = new Guid("6aac6f0e-d13a-a629-4c2b-9d6eaf6680e4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SS", + Name = "Swati", + NativeName = "SiSwati" + }, + new + { + Id = new Guid("766c1ebb-78c1-bada-37fb-c45d1bd4baff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ST", + Name = "Southern Sotho", + NativeName = "Sesotho" + }, + new + { + Id = new Guid("ee1ace14-e945-4767-85ec-3d74be8b516b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SU", + Name = "Sundanese", + NativeName = "Basa Sunda" + }, + new + { + Id = new Guid("4d8bcda4-5598-16cd-b379-97eb7a5e1c29"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SV", + Name = "Swedish", + NativeName = "Svenska" + }, + new + { + Id = new Guid("5f002f07-f2c3-9fa4-2e29-225d116c10a3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SW", + Name = "Swahili", + NativeName = "Kiswahili" + }, + new + { + Id = new Guid("8bc44f03-84a5-2afc-8b0b-40c727e4ce36"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TA", + Name = "Tamil", + NativeName = "தமிழ்" + }, + new + { + Id = new Guid("3bf5a74a-6d12-e971-16bc-c75e487f2615"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TE", + Name = "Telugu", + NativeName = "తెలుగు" + }, + new + { + Id = new Guid("9dacf00b-7d0a-d744-cc60-e5fa66371e9d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TG", + Name = "Tajik", + NativeName = "тоҷикӣ" + }, + new + { + Id = new Guid("84d58b3d-d131-1506-0792-1b3228b6f71f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TH", + Name = "Thai", + NativeName = "ไทย" + }, + new + { + Id = new Guid("596e8283-10ce-d81d-2e6f-400fa259d717"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TI", + Name = "Tigrinya", + NativeName = "ትግርኛ" + }, + new + { + Id = new Guid("11765ad0-30f2-bab8-b616-20f88b28b21e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TK", + Name = "Turkmen", + NativeName = "Türkmençe" + }, + new + { + Id = new Guid("fb9a713c-2de1-882a-64b7-0e8fef5d2f7e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TL", + Name = "Tagalog", + NativeName = "Wikang Tagalog" + }, + new + { + Id = new Guid("06f8ad57-7133-9a5e-5a83-53052012b014"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TN", + Name = "Tswana", + NativeName = "Setswana" + }, + new + { + Id = new Guid("9e7dbdc3-2c8b-e8ae-082b-e02695f8268e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TO", + Name = "Tonga", + NativeName = "faka Tonga" + }, + new + { + Id = new Guid("f39cca22-449e-9866-3a65-465a5510483e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TR", + Name = "Turkish", + NativeName = "Türkçe" + }, + new + { + Id = new Guid("6200b376-9eae-d01b-de52-8674aaf5b013"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TS", + Name = "Tsonga", + NativeName = "Xitsonga" + }, + new + { + Id = new Guid("95467997-f989-f456-34b7-0b578302dcba"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TT", + Name = "Tatar", + NativeName = "татар теле" + }, + new + { + Id = new Guid("875060ca-73f6-af3b-d844-1b1416ce4583"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TW", + Name = "Twi", + NativeName = "Twi" + }, + new + { + Id = new Guid("2299a74f-3ebc-f022-da1a-44ae59335b3b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TY", + Name = "Tahitian", + NativeName = "Reo Tahiti" + }, + new + { + Id = new Guid("3e2cccbe-1615-c707-a97b-421a799b2559"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "UG", + Name = "Uyghur", + NativeName = "ئۇيغۇرچە‎" + }, + new + { + Id = new Guid("de29d5e7-2ecf-a4ff-5e40-5e83edd0d9b4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "UK", + Name = "Ukrainian", + NativeName = "Українська" + }, + new + { + Id = new Guid("f1f09549-a9bb-da4a-9b98-8655a01235aa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "UR", + Name = "Urdu", + NativeName = "اردو" + }, + new + { + Id = new Guid("357369e3-85a8-86f7-91c7-349772ae7744"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "UZ", + Name = "Uzbek", + NativeName = "Ўзбек" + }, + new + { + Id = new Guid("52d9992c-19bd-82b4-9188-11dabcac6171"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "VE", + Name = "Venda", + NativeName = "Tshivenḓa" + }, + new + { + Id = new Guid("e1947bdc-ff2c-d2c1-3c55-f1f9bf778578"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "VI", + Name = "Vietnamese", + NativeName = "Tiếng Việt" + }, + new + { + Id = new Guid("c2254fd9-159e-4064-0fbf-a7969cba06ec"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "VO", + Name = "Volapük", + NativeName = "Volapük" + }, + new + { + Id = new Guid("629b68d8-1d71-d3ce-f13e-45048ffff017"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "WA", + Name = "Walloon", + NativeName = "walon" + }, + new + { + Id = new Guid("ca6bfadf-4e87-0692-a6b3-20ea6a51555d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "WO", + Name = "Wolof", + NativeName = "Wollof" + }, + new + { + Id = new Guid("0b9b4368-7ceb-e519-153d-2c58c983852b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "XH", + Name = "Xhosa", + NativeName = "isiXhosa" + }, + new + { + Id = new Guid("13016d0c-fbf0-9503-12f2-e0f8d27394ae"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "YI", + Name = "Yiddish", + NativeName = "ייִדיש" + }, + new + { + Id = new Guid("d55a9eb2-48fc-2719-47bf-99e902c28e80"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "YO", + Name = "Yoruba", + NativeName = "Yorùbá" + }, + new + { + Id = new Guid("ebf38b9a-6fbe-6e82-3977-2c4763bea072"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ZA", + Name = "Zhuang", + NativeName = "Saɯ cueŋƅ" + }, + new + { + Id = new Guid("0ce6f5e0-0789-fa0e-b4b5-23a5b1f5e257"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ZH", + Name = "Chinese", + NativeName = "中文" + }, + new + { + Id = new Guid("2c7b808d-7786-2deb-5318-56f7c238520e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ZU", + Name = "Zulu", + NativeName = "isiZulu" + }); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormsVersion") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("NgoId") + .HasColumnType("uuid"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("NgoId"); + + b.ToTable("MonitoringNgos"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringNgoId") + .HasColumnType("uuid"); + + b.Property("ObserverId") + .HasColumnType("uuid"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("Tags") + .IsRequired() + .HasColumnType("text[]"); + + b.HasKey("Id"); + + b.HasIndex("MonitoringNgoId"); + + b.HasIndex("ObserverId"); + + b.HasIndex("ElectionRoundId", "Id") + .IsUnique(); + + b.ToTable("MonitoringObservers"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NgoAdminAggregate.NgoAdmin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ApplicationUserId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("NgoId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId"); + + b.HasIndex("NgoId"); + + b.ToTable("NgoAdmins", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NgoAggregate.Ngo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Ngos"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NoteAggregate.Note", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.Property("QuestionId") + .HasColumnType("uuid"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(10000) + .HasColumnType("character varying(10000)"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.ToTable("Notes", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationAggregate.MonitoringObserverNotification", b => + { + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("NotificationId") + .HasColumnType("uuid"); + + b.Property("IsRead") + .HasColumnType("boolean"); + + b.HasKey("MonitoringObserverId", "NotificationId"); + + b.HasIndex("NotificationId"); + + b.ToTable("MonitoringObserverNotification"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationAggregate.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Body") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("SenderId") + .HasColumnType("uuid"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("SenderId"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationStubAggregate.NotificationStub", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("HasBeenProcessed") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("SerializedData") + .IsRequired() + .HasColumnType("text"); + + b.Property("StubType") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("NotificationStubs"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationTokenAggregate.NotificationToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ObserverId") + .HasColumnType("uuid"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.HasKey("Id"); + + b.HasIndex("ObserverId"); + + b.ToTable("NotificationTokens"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ApplicationUserId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId"); + + b.ToTable("Observers", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverGuideAggregate.ObserverGuide", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("FileName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FilePath") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("GuideType") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MimeType") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MonitoringNgoId") + .HasColumnType("uuid"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UploadedFileName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("WebsiteUrl") + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.HasKey("Id"); + + b.HasIndex("MonitoringNgoId"); + + b.ToTable("ObserversGuides"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Address") + .IsRequired() + .HasMaxLength(2024) + .HasColumnType("character varying(2024)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayOrder") + .HasColumnType("integer"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Level1") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level2") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level3") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level4") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level5") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Number") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Tags") + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.ToTable("PollingStations"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationInfoAggregate.PollingStationInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Answers") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("ArrivalTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DepartureTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FollowUpStatus") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("NotApplicable"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MinutesMonitoring") + .HasColumnType("double precision"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("NumberOfFlaggedAnswers") + .HasColumnType("integer"); + + b.Property("NumberOfQuestionsAnswered") + .HasColumnType("integer"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.Property("PollingStationInformationFormId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.HasIndex("PollingStationInformationFormId"); + + b.HasIndex("ElectionRoundId", "PollingStationId", "MonitoringObserverId", "PollingStationInformationFormId") + .IsUnique(); + + b.ToTable("PollingStationInformation", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate.PollingStationInformationForm", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DefaultLanguage") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Languages") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("LanguagesTranslationStatus") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("NumberOfQuestions") + .HasColumnType("integer"); + + b.Property("Questions") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId") + .IsUnique(); + + b.ToTable("PollingStationInformationForms"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.QuickReportAggregate.QuickReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(10000) + .HasColumnType("character varying(10000)"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FollowUpStatus") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("NotApplicable"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("PollingStationDetails") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.Property("QuickReportLocationType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("Id"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.ToTable("QuickReports"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.QuickReportAttachmentAggregate.QuickReportAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasColumnType("text"); + + b.Property("FilePath") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsCompleted") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MimeType") + .IsRequired() + .HasColumnType("text"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("QuickReportId") + .HasColumnType("uuid"); + + b.Property("UploadedFileName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("MonitoringObserverId"); + + b.ToTable("QuickReportAttachments"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", b => + { + b.OwnsOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.UserPreferences", "Preferences", b1 => + { + b1.Property("ApplicationUserId") + .HasColumnType("uuid"); + + b1.Property("LanguageCode") + .IsRequired() + .HasColumnType("text"); + + b1.HasKey("ApplicationUserId"); + + b1.ToTable("AspNetUsers"); + + b1.ToJson("Preferences"); + + b1.WithOwner() + .HasForeignKey("ApplicationUserId"); + }); + + b.Navigation("Preferences") + .IsRequired(); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.AttachmentAggregate.Attachment", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAttachmentAggregate.CitizenReportAttachment", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", "CitizenReport") + .WithMany("Attachments") + .HasForeignKey("CitizenReportId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CitizenReport"); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportNoteAggregate.CitizenReportNote", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", "CitizenReport") + .WithMany("Notes") + .HasForeignKey("CitizenReportId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CitizenReport"); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.CountryAggregate.Country", "Country") + .WithMany() + .HasForeignKey("CountryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", "MonitoringNgoForCitizenReporting") + .WithMany() + .HasForeignKey("MonitoringNgoForCitizenReportingId"); + + b.Navigation("Country"); + + b.Navigation("MonitoringNgoForCitizenReporting"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ExportedDataAggregate.ExportedData", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FeedbackAggregate.Feedback", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", "Observer") + .WithMany() + .HasForeignKey("ObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Observer"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormAggregate.Form", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", "MonitoringNgo") + .WithMany() + .HasForeignKey("MonitoringNgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringNgo"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormSubmissionAggregate.FormSubmission", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany("MonitoringNgos") + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.NgoAggregate.Ngo", "Ngo") + .WithMany() + .HasForeignKey("NgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Ngo"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", "MonitoringNgo") + .WithMany("MonitoringObservers") + .HasForeignKey("MonitoringNgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", "Observer") + .WithMany("MonitoringObservers") + .HasForeignKey("ObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringNgo"); + + b.Navigation("Observer"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NgoAdminAggregate.NgoAdmin", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", "ApplicationUser") + .WithMany() + .HasForeignKey("ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.NgoAggregate.Ngo", "Ngo") + .WithMany("Admins") + .HasForeignKey("NgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApplicationUser"); + + b.Navigation("Ngo"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NoteAggregate.Note", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationAggregate.MonitoringObserverNotification", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.NotificationAggregate.Notification", "Notification") + .WithMany() + .HasForeignKey("NotificationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MonitoringObserver"); + + b.Navigation("Notification"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationAggregate.Notification", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.NgoAdminAggregate.NgoAdmin", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationTokenAggregate.NotificationToken", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", null) + .WithMany() + .HasForeignKey("ObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", "ApplicationUser") + .WithMany() + .HasForeignKey("ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApplicationUser"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverGuideAggregate.ObserverGuide", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", "MonitoringNgo") + .WithMany() + .HasForeignKey("MonitoringNgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MonitoringNgo"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationInfoAggregate.PollingStationInformation", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate.PollingStationInformationForm", "PollingStationInformationForm") + .WithMany() + .HasForeignKey("PollingStationInformationFormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + + b.Navigation("PollingStationInformationForm"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate.PollingStationInformationForm", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithOne() + .HasForeignKey("Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate.PollingStationInformationForm", "ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.QuickReportAggregate.QuickReport", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId"); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.QuickReportAttachmentAggregate.QuickReportAttachment", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringObserver"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", b => + { + b.Navigation("Attachments"); + + b.Navigation("Notes"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", b => + { + b.Navigation("MonitoringNgos"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", b => + { + b.Navigation("MonitoringObservers"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NgoAggregate.Ngo", b => + { + b.Navigation("Admins"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", b => + { + b.Navigation("MonitoringObservers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/api/src/Vote.Monitor.Domain/Migrations/20240913084651_RefactorFormsAndSubmissions.cs b/api/src/Vote.Monitor.Domain/Migrations/20240913084651_RefactorFormsAndSubmissions.cs new file mode 100644 index 000000000..9c0eea40e --- /dev/null +++ b/api/src/Vote.Monitor.Domain/Migrations/20240913084651_RefactorFormsAndSubmissions.cs @@ -0,0 +1,96 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Vote.Monitor.Domain.Migrations +{ + /// + public partial class RefactorFormsAndSubmissions : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Code", + table: "PollingStationInformationForms", + type: "character varying(256)", + maxLength: 256, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Description", + table: "PollingStationInformationForms", + type: "jsonb", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "FormType", + table: "PollingStationInformationForms", + type: "text", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "LanguagesTranslationStatus", + table: "PollingStationInformationForms", + type: "jsonb", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Name", + table: "PollingStationInformationForms", + type: "jsonb", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Status", + table: "PollingStationInformationForms", + type: "text", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "NumberOfFlaggedAnswers", + table: "PollingStationInformation", + type: "integer", + nullable: false, + defaultValue: 0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Code", + table: "PollingStationInformationForms"); + + migrationBuilder.DropColumn( + name: "Description", + table: "PollingStationInformationForms"); + + migrationBuilder.DropColumn( + name: "FormType", + table: "PollingStationInformationForms"); + + migrationBuilder.DropColumn( + name: "LanguagesTranslationStatus", + table: "PollingStationInformationForms"); + + migrationBuilder.DropColumn( + name: "Name", + table: "PollingStationInformationForms"); + + migrationBuilder.DropColumn( + name: "Status", + table: "PollingStationInformationForms"); + + migrationBuilder.DropColumn( + name: "NumberOfFlaggedAnswers", + table: "PollingStationInformation"); + } + } +} diff --git a/api/src/Vote.Monitor.Domain/Migrations/20240913125040_CitizenReportsLocationModel.Designer.cs b/api/src/Vote.Monitor.Domain/Migrations/20240913125040_CitizenReportsLocationModel.Designer.cs new file mode 100644 index 000000000..b4624b769 --- /dev/null +++ b/api/src/Vote.Monitor.Domain/Migrations/20240913125040_CitizenReportsLocationModel.Designer.cs @@ -0,0 +1,6347 @@ +// +using System; +using System.Collections.Generic; +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Vote.Monitor.Domain; + +#nullable disable + +namespace Vote.Monitor.Domain.Migrations +{ + [DbContext(typeof(VoteMonitorContext))] + [Migration("20240913125040_CitizenReportsLocationModel")] + partial class CitizenReportsLocationModel + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "hstore"); + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "uuid-ossp"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + + b.HasData( + new + { + Id = new Guid("265e94b0-50fe-4546-b21c-83cb7e94aeff"), + Name = "PlatformAdmin", + NormalizedName = "PLATFORMADMIN" + }, + new + { + Id = new Guid("3239f803-dda8-408b-93ad-0ed973a04e45"), + Name = "NgoAdmin", + NormalizedName = "NGOADMIN" + }, + new + { + Id = new Guid("d1cbef39-62e0-4120-a42b-b01b029dc6ad"), + Name = "Observer", + NormalizedName = "OBSERVER" + }); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("InvitationToken") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("RefreshToken") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("RefreshTokenExpiryTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Role") + .IsRequired() + .HasColumnType("text"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.AttachmentAggregate.Attachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("IsCompleted") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.Property("QuestionId") + .HasColumnType("uuid"); + + b.Property("UploadedFileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.ToTable("Attachments", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.Auditing.Trail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AffectedColumns") + .HasColumnType("text"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("NewValues") + .HasColumnType("text"); + + b.Property("OldValues") + .HasColumnType("text"); + + b.Property("PrimaryKey") + .HasColumnType("text"); + + b.Property("TableName") + .HasColumnType("text"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("Type") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("AuditTrails"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Answers") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FollowUpStatus") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("NotApplicable"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("LocationId") + .HasColumnType("uuid"); + + b.Property("NumberOfFlaggedAnswers") + .HasColumnType("integer"); + + b.Property("NumberOfQuestionsAnswered") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.HasIndex("LocationId"); + + b.ToTable("CitizenReports"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAttachmentAggregate.CitizenReportAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CitizenReportId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("IsCompleted") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("QuestionId") + .HasColumnType("uuid"); + + b.Property("UploadedFileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("CitizenReportId"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.ToTable("CitizenReportAttachments"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportNoteAggregate.CitizenReportNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CitizenReportId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("QuestionId") + .HasColumnType("uuid"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(10000) + .HasColumnType("character varying(10000)"); + + b.HasKey("Id"); + + b.HasIndex("CitizenReportId"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.ToTable("CitizenReportNotes"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CountryAggregate.Country", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Iso2") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("character varying(2)"); + + b.Property("Iso3") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("character varying(3)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NumericCode") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("character varying(3)"); + + b.HasKey("Id"); + + b.HasIndex("Iso2") + .IsUnique(); + + b.HasIndex("Iso3") + .IsUnique(); + + b.HasIndex("NumericCode") + .IsUnique(); + + b.ToTable("Countries"); + + b.HasData( + new + { + Id = new Guid("edd4319b-86f3-24cb-248c-71da624c02f7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Islamic Republic of Afghanistan", + Iso2 = "AF", + Iso3 = "AFG", + Name = "Afghanistan", + NumericCode = "004" + }, + new + { + Id = new Guid("a96fe9bb-4ef4-fca0-f38b-0ec729822f37"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Åland Islands", + Iso2 = "AX", + Iso3 = "ALA", + Name = "Åland Islands", + NumericCode = "248" + }, + new + { + Id = new Guid("5aa0aeb7-4dc8-6a29-fc2f-35daec1541dd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Albania", + Iso2 = "AL", + Iso3 = "ALB", + Name = "Albania", + NumericCode = "008" + }, + new + { + Id = new Guid("fee6f04f-c4c1-e3e4-645d-bb6bb703aeb7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "People's Democratic Republic of Algeria", + Iso2 = "DZ", + Iso3 = "DZA", + Name = "Algeria", + NumericCode = "012" + }, + new + { + Id = new Guid("538114de-7db0-9242-35e6-324fa7eff44d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "American Samoa", + Iso2 = "AS", + Iso3 = "ASM", + Name = "American Samoa", + NumericCode = "016" + }, + new + { + Id = new Guid("bd4bbfc7-d8bc-9d8d-7f7c-7b299c94e9e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Principality of Andorra", + Iso2 = "AD", + Iso3 = "AND", + Name = "Andorra", + NumericCode = "020" + }, + new + { + Id = new Guid("478786f7-1842-8c1e-921c-12e7ed5329c5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Angola", + Iso2 = "AO", + Iso3 = "AGO", + Name = "Angola", + NumericCode = "024" + }, + new + { + Id = new Guid("2b68fb11-a0e0-3d23-5fb8-99721ecfc182"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Anguilla", + Iso2 = "AI", + Iso3 = "AIA", + Name = "Anguilla", + NumericCode = "660" + }, + new + { + Id = new Guid("a0098040-b7a0-59a1-e64b-0a9778b7f74c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Antarctica (the territory South of 60 deg S)", + Iso2 = "AQ", + Iso3 = "ATA", + Name = "Antarctica", + NumericCode = "010" + }, + new + { + Id = new Guid("f3eef99a-661e-2c68-7a4c-3053e2f28007"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Antigua and Barbuda", + Iso2 = "AG", + Iso3 = "ATG", + Name = "Antigua and Barbuda", + NumericCode = "028" + }, + new + { + Id = new Guid("a7afb7b1-b26d-4571-1a1f-3fff738ff21e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Argentine Republic", + Iso2 = "AR", + Iso3 = "ARG", + Name = "Argentina", + NumericCode = "032" + }, + new + { + Id = new Guid("688af4c8-9d64-ae1c-147f-b8afd54801e3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Armenia", + Iso2 = "AM", + Iso3 = "ARM", + Name = "Armenia", + NumericCode = "051" + }, + new + { + Id = new Guid("e6c7651f-182e-cf9c-1ef9-6293b95b500c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Aruba", + Iso2 = "AW", + Iso3 = "ABW", + Name = "Aruba", + NumericCode = "533" + }, + new + { + Id = new Guid("15639386-e4fc-120c-6916-c0c980e24be1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of Australia", + Iso2 = "AU", + Iso3 = "AUS", + Name = "Australia", + NumericCode = "036" + }, + new + { + Id = new Guid("704254eb-6959-8ddc-a5df-ac8f9658dc68"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Austria", + Iso2 = "AT", + Iso3 = "AUT", + Name = "Austria", + NumericCode = "040" + }, + new + { + Id = new Guid("008c3138-73d8-dbbc-f1dd-521e4c68bcf1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Azerbaijan", + Iso2 = "AZ", + Iso3 = "AZE", + Name = "Azerbaijan", + NumericCode = "031" + }, + new + { + Id = new Guid("46e88019-c521-57b2-d1c0-c0e2478d3b05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of the Bahamas", + Iso2 = "BS", + Iso3 = "BHS", + Name = "Bahamas", + NumericCode = "044" + }, + new + { + Id = new Guid("44caa0f4-1e78-d2fb-96be-d01b3224bdc1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Bahrain", + Iso2 = "BH", + Iso3 = "BHR", + Name = "Bahrain", + NumericCode = "048" + }, + new + { + Id = new Guid("809c3424-8654-b82c-cbd4-d857d096943e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "People's Republic of Bangladesh", + Iso2 = "BD", + Iso3 = "BGD", + Name = "Bangladesh", + NumericCode = "050" + }, + new + { + Id = new Guid("316c68fc-9144-f6e1-8bf1-899fc54b2327"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Barbados", + Iso2 = "BB", + Iso3 = "BRB", + Name = "Barbados", + NumericCode = "052" + }, + new + { + Id = new Guid("d97b5460-11ab-45c5-9a6f-ffa441ed70d6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Belarus", + Iso2 = "BY", + Iso3 = "BLR", + Name = "Belarus", + NumericCode = "112" + }, + new + { + Id = new Guid("0797a7d5-bbc0-2e52-0de8-14a42fc80baa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Belgium", + Iso2 = "BE", + Iso3 = "BEL", + Name = "Belgium", + NumericCode = "056" + }, + new + { + Id = new Guid("c89e02a0-9506-90df-5545-b98a2453cd63"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Belize", + Iso2 = "BZ", + Iso3 = "BLZ", + Name = "Belize", + NumericCode = "084" + }, + new + { + Id = new Guid("96a22cee-9af7-8f03-b483-b3e774a36d3b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Benin", + Iso2 = "BJ", + Iso3 = "BEN", + Name = "Benin", + NumericCode = "204" + }, + new + { + Id = new Guid("ca2a5560-d4c4-3c87-3090-6f5436310b55"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bermuda", + Iso2 = "BM", + Iso3 = "BMU", + Name = "Bermuda", + NumericCode = "060" + }, + new + { + Id = new Guid("8ed6a34e-8135-27fa-f86a-caa247b29768"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Bhutan", + Iso2 = "BT", + Iso3 = "BTN", + Name = "Bhutan", + NumericCode = "064" + }, + new + { + Id = new Guid("f33ced84-eb43-fb39-ef79-b266e4d4cd94"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Plurinational State of Bolivia", + Iso2 = "BO", + Iso3 = "BOL", + Name = "Bolivia", + NumericCode = "068" + }, + new + { + Id = new Guid("d8101f9d-8313-4054-c5f3-42c7a1c72862"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bonaire, Sint Eustatius and Saba", + Iso2 = "BQ", + Iso3 = "BES", + Name = "Bonaire, Sint Eustatius and Saba", + NumericCode = "535" + }, + new + { + Id = new Guid("a7716d29-6ef6-b775-51c5-97094536329d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bosnia and Herzegovina", + Iso2 = "BA", + Iso3 = "BIH", + Name = "Bosnia and Herzegovina", + NumericCode = "070" + }, + new + { + Id = new Guid("14f190c6-97c9-3e12-2eba-db17c59d6a04"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Botswana", + Iso2 = "BW", + Iso3 = "BWA", + Name = "Botswana", + NumericCode = "072" + }, + new + { + Id = new Guid("32da0208-9048-1339-a8ee-6955cfff4c12"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bouvet Island (Bouvetøya)", + Iso2 = "BV", + Iso3 = "BVT", + Name = "Bouvet Island (Bouvetøya)", + NumericCode = "074" + }, + new + { + Id = new Guid("5283afbb-2744-e930-2c16-c5ea6b0ff7cc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federative Republic of Brazil", + Iso2 = "BR", + Iso3 = "BRA", + Name = "Brazil", + NumericCode = "076" + }, + new + { + Id = new Guid("b8b09512-ea4c-4a61-9331-304f55324ef7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "British Indian Ocean Territory (Chagos Archipelago)", + Iso2 = "IO", + Iso3 = "IOT", + Name = "British Indian Ocean Territory (Chagos Archipelago)", + NumericCode = "086" + }, + new + { + Id = new Guid("39be5e86-aea5-f64f-fd7e-1017fe24e543"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "British Virgin Islands", + Iso2 = "VG", + Iso3 = "VGB", + Name = "British Virgin Islands", + NumericCode = "092" + }, + new + { + Id = new Guid("ed6278e0-436c-9fd9-0b9e-44fd424cbd1b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Brunei Darussalam", + Iso2 = "BN", + Iso3 = "BRN", + Name = "Brunei Darussalam", + NumericCode = "096" + }, + new + { + Id = new Guid("46576b73-c05b-7498-5b07-9bbf59b7645d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Bulgaria", + Iso2 = "BG", + Iso3 = "BGR", + Name = "Bulgaria", + NumericCode = "100" + }, + new + { + Id = new Guid("42697d56-52cf-b411-321e-c51929f02f90"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Burkina Faso", + Iso2 = "BF", + Iso3 = "BFA", + Name = "Burkina Faso", + NumericCode = "854" + }, + new + { + Id = new Guid("75e4464b-a784-63b8-1ecc-69ee1f09f43f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Burundi", + Iso2 = "BI", + Iso3 = "BDI", + Name = "Burundi", + NumericCode = "108" + }, + new + { + Id = new Guid("c9702851-1f67-f2a6-89d4-37b3fbb12044"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Cambodia", + Iso2 = "KH", + Iso3 = "KHM", + Name = "Cambodia", + NumericCode = "116" + }, + new + { + Id = new Guid("c0b7e39e-223a-ebb0-b899-5404573bbdb7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cameroon", + Iso2 = "CM", + Iso3 = "CMR", + Name = "Cameroon", + NumericCode = "120" + }, + new + { + Id = new Guid("5c0e654b-8547-5d02-ee7b-d65e3c5c5273"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Canada", + Iso2 = "CA", + Iso3 = "CAN", + Name = "Canada", + NumericCode = "124" + }, + new + { + Id = new Guid("17ed5f0f-e091-94ff-0512-ad291bde94d7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cabo Verde", + Iso2 = "CV", + Iso3 = "CPV", + Name = "Cabo Verde", + NumericCode = "132" + }, + new + { + Id = new Guid("3c5828e0-16a8-79ba-4e5c-9b45065df113"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Cayman Islands", + Iso2 = "KY", + Iso3 = "CYM", + Name = "Cayman Islands", + NumericCode = "136" + }, + new + { + Id = new Guid("b4e0625c-7597-c185-b8ae-cfb35a731f2f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Central African Republic", + Iso2 = "CF", + Iso3 = "CAF", + Name = "Central African Republic", + NumericCode = "140" + }, + new + { + Id = new Guid("2a1ca5b6-fba0-cfa8-9928-d7a2382bc4d7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Chad", + Iso2 = "TD", + Iso3 = "TCD", + Name = "Chad", + NumericCode = "148" + }, + new + { + Id = new Guid("ad4f938a-bf7b-684b-2c9e-e824d3fa3863"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Chile", + Iso2 = "CL", + Iso3 = "CHL", + Name = "Chile", + NumericCode = "152" + }, + new + { + Id = new Guid("8250c49f-9438-7c2e-f403-54d962db0c18"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "People's Republic of China", + Iso2 = "CN", + Iso3 = "CHN", + Name = "China", + NumericCode = "156" + }, + new + { + Id = new Guid("0f1ba59e-ade5-23e5-6fce-e2fd3282e114"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Christmas Island", + Iso2 = "CX", + Iso3 = "CXR", + Name = "Christmas Island", + NumericCode = "162" + }, + new + { + Id = new Guid("a16263a5-810c-bf6a-206d-72cb914e2d5c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Cocos (Keeling) Islands", + Iso2 = "CC", + Iso3 = "CCK", + Name = "Cocos (Keeling) Islands", + NumericCode = "166" + }, + new + { + Id = new Guid("c64288fc-d941-0615-47f9-28e6c294ce26"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Colombia", + Iso2 = "CO", + Iso3 = "COL", + Name = "Colombia", + NumericCode = "170" + }, + new + { + Id = new Guid("5e7a08f2-7d59-bcdb-7ddd-876b87181420"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Union of the Comoros", + Iso2 = "KM", + Iso3 = "COM", + Name = "Comoros", + NumericCode = "174" + }, + new + { + Id = new Guid("1258ec90-c47e-ff72-b7e3-f90c3ee320f8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic Republic of the Congo", + Iso2 = "CD", + Iso3 = "COD", + Name = "Congo", + NumericCode = "180" + }, + new + { + Id = new Guid("1934954c-66c2-6226-c5b6-491065a3e4c0"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Congo", + Iso2 = "CG", + Iso3 = "COG", + Name = "Congo", + NumericCode = "178" + }, + new + { + Id = new Guid("af79558d-51fb-b08d-185b-afeb983ab99b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Cook Islands", + Iso2 = "CK", + Iso3 = "COK", + Name = "Cook Islands", + NumericCode = "184" + }, + new + { + Id = new Guid("d13935c1-8956-1399-7c4e-0354795cd37b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Costa Rica", + Iso2 = "CR", + Iso3 = "CRI", + Name = "Costa Rica", + NumericCode = "188" + }, + new + { + Id = new Guid("5be18efe-6db8-a727-7f2a-62bd71bc6593"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cote d'Ivoire", + Iso2 = "CI", + Iso3 = "CIV", + Name = "Cote d'Ivoire", + NumericCode = "384" + }, + new + { + Id = new Guid("1f8be615-5746-277e-d82b-47596b5bb922"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Croatia", + Iso2 = "HR", + Iso3 = "HRV", + Name = "Croatia", + NumericCode = "191" + }, + new + { + Id = new Guid("57765d87-2424-2c86-ad9c-1af58ef3127a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cuba", + Iso2 = "CU", + Iso3 = "CUB", + Name = "Cuba", + NumericCode = "192" + }, + new + { + Id = new Guid("3345e205-3e72-43ed-de1b-ac6e050543e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Curaçao", + Iso2 = "CW", + Iso3 = "CUW", + Name = "Curaçao", + NumericCode = "531" + }, + new + { + Id = new Guid("df20d0d7-9fbe-e725-d966-4fdf9f5c9dfb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cyprus", + Iso2 = "CY", + Iso3 = "CYP", + Name = "Cyprus", + NumericCode = "196" + }, + new + { + Id = new Guid("9d4ec95b-974a-f5bb-bb4b-ba6747440631"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Czech Republic", + Iso2 = "CZ", + Iso3 = "CZE", + Name = "Czechia", + NumericCode = "203" + }, + new + { + Id = new Guid("8a4fcb23-f3e6-fb5b-8cda-975872f600d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Denmark", + Iso2 = "DK", + Iso3 = "DNK", + Name = "Denmark", + NumericCode = "208" + }, + new + { + Id = new Guid("37a79267-d38a-aaef-577a-aa68a96880ae"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Djibouti", + Iso2 = "DJ", + Iso3 = "DJI", + Name = "Djibouti", + NumericCode = "262" + }, + new + { + Id = new Guid("19ea3a6a-1a76-23c8-8e4e-1d298f15207f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of Dominica", + Iso2 = "DM", + Iso3 = "DMA", + Name = "Dominica", + NumericCode = "212" + }, + new + { + Id = new Guid("b2c4d2d7-7ada-7864-426f-10a28d9f9eba"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Dominican Republic", + Iso2 = "DO", + Iso3 = "DOM", + Name = "Dominican Republic", + NumericCode = "214" + }, + new + { + Id = new Guid("49c82f1b-968d-b5e7-8559-e39567d46787"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Ecuador", + Iso2 = "EC", + Iso3 = "ECU", + Name = "Ecuador", + NumericCode = "218" + }, + new + { + Id = new Guid("ee5dfc29-80f1-86ae-cde7-02484a18907a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Arab Republic of Egypt", + Iso2 = "EG", + Iso3 = "EGY", + Name = "Egypt", + NumericCode = "818" + }, + new + { + Id = new Guid("4d8bcda4-5598-16cd-b379-97eb7a5e1c29"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of El Salvador", + Iso2 = "SV", + Iso3 = "SLV", + Name = "El Salvador", + NumericCode = "222" + }, + new + { + Id = new Guid("824392e8-a6cc-0cd4-af13-3067dad3258e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Equatorial Guinea", + Iso2 = "GQ", + Iso3 = "GNQ", + Name = "Equatorial Guinea", + NumericCode = "226" + }, + new + { + Id = new Guid("8b5a477a-070a-a84f-bd3b-f54dc2a172de"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Eritrea", + Iso2 = "ER", + Iso3 = "ERI", + Name = "Eritrea", + NumericCode = "232" + }, + new + { + Id = new Guid("2dc643bd-cc6c-eb0c-7314-44123576f0ee"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Estonia", + Iso2 = "EE", + Iso3 = "EST", + Name = "Estonia", + NumericCode = "233" + }, + new + { + Id = new Guid("e75515a6-63cf-3612-a3a2-befa0d7048a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federal Democratic Republic of Ethiopia", + Iso2 = "ET", + Iso3 = "ETH", + Name = "Ethiopia", + NumericCode = "231" + }, + new + { + Id = new Guid("0d4fe6e6-ea1e-d1ce-5134-6c0c1a696a00"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Faroe Islands", + Iso2 = "FO", + Iso3 = "FRO", + Name = "Faroe Islands", + NumericCode = "234" + }, + new + { + Id = new Guid("b86375dc-edbb-922c-9ed4-2f724094a5a2"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Falkland Islands (Malvinas)", + Iso2 = "FK", + Iso3 = "FLK", + Name = "Falkland Islands (Malvinas)", + NumericCode = "238" + }, + new + { + Id = new Guid("0e2a1681-d852-67ae-7387-0d04be9e7fd3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Fiji", + Iso2 = "FJ", + Iso3 = "FJI", + Name = "Fiji", + NumericCode = "242" + }, + new + { + Id = new Guid("5a5d9168-081b-1e02-1fbb-cdfa910e526c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Finland", + Iso2 = "FI", + Iso3 = "FIN", + Name = "Finland", + NumericCode = "246" + }, + new + { + Id = new Guid("b2261c50-1a57-7f1f-d72d-f8c21593874f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "French Republic", + Iso2 = "FR", + Iso3 = "FRA", + Name = "France", + NumericCode = "250" + }, + new + { + Id = new Guid("ac6cde6e-f645-d04e-8afc-0391ecf38a70"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "French Guiana", + Iso2 = "GF", + Iso3 = "GUF", + Name = "French Guiana", + NumericCode = "254" + }, + new + { + Id = new Guid("11dbce82-a154-7aee-7b5e-d5981f220572"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "French Polynesia", + Iso2 = "PF", + Iso3 = "PYF", + Name = "French Polynesia", + NumericCode = "258" + }, + new + { + Id = new Guid("903bee63-bcf0-0264-6eaf-a8cde95c5f41"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "French Southern Territories", + Iso2 = "TF", + Iso3 = "ATF", + Name = "French Southern Territories", + NumericCode = "260" + }, + new + { + Id = new Guid("4826bc0f-235e-572f-2b1a-21f1c9e05f83"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Gabonese Republic", + Iso2 = "GA", + Iso3 = "GAB", + Name = "Gabon", + NumericCode = "266" + }, + new + { + Id = new Guid("a40b91b3-cc13-2470-65f0-a0fdc946f2a2"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Gambia", + Iso2 = "GM", + Iso3 = "GMB", + Name = "Gambia", + NumericCode = "270" + }, + new + { + Id = new Guid("980176e8-7d9d-9729-b3e9-ebc455fb8fc4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Georgia", + Iso2 = "GE", + Iso3 = "GEO", + Name = "Georgia", + NumericCode = "268" + }, + new + { + Id = new Guid("46ef1468-86f6-0c99-f4e9-46f966167b05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federal Republic of Germany", + Iso2 = "DE", + Iso3 = "DEU", + Name = "Germany", + NumericCode = "276" + }, + new + { + Id = new Guid("6d0c77a7-a4aa-c2bd-2db6-0e2ad2d61f8a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Ghana", + Iso2 = "GH", + Iso3 = "GHA", + Name = "Ghana", + NumericCode = "288" + }, + new + { + Id = new Guid("8e0de349-f9ab-2bca-3910-efd48bf1170a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Gibraltar", + Iso2 = "GI", + Iso3 = "GIB", + Name = "Gibraltar", + NumericCode = "292" + }, + new + { + Id = new Guid("4fc1a9dc-cc74-f6ce-5743-c5cee8d709ef"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Hellenic Republic of Greece", + Iso2 = "GR", + Iso3 = "GRC", + Name = "Greece", + NumericCode = "300" + }, + new + { + Id = new Guid("2f00fe86-a06b-dc95-0ea7-4520d1dec784"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Greenland", + Iso2 = "GL", + Iso3 = "GRL", + Name = "Greenland", + NumericCode = "304" + }, + new + { + Id = new Guid("ff5b4d88-c179-ff0d-6285-cf46ba475d7d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Grenada", + Iso2 = "GD", + Iso3 = "GRD", + Name = "Grenada", + NumericCode = "308" + }, + new + { + Id = new Guid("3bcd2aad-fb69-09f4-1ad7-2c7f5fa23f9f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Guadeloupe", + Iso2 = "GP", + Iso3 = "GLP", + Name = "Guadeloupe", + NumericCode = "312" + }, + new + { + Id = new Guid("096a8586-9702-6fec-5f6a-6eb3b7b7837f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Guam", + Iso2 = "GU", + Iso3 = "GUM", + Name = "Guam", + NumericCode = "316" + }, + new + { + Id = new Guid("d24b46ba-8e9d-2a09-7995-e35e8ae54f6b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Guatemala", + Iso2 = "GT", + Iso3 = "GTM", + Name = "Guatemala", + NumericCode = "320" + }, + new + { + Id = new Guid("5b0ee3be-596d-bdc1-f101-00ef33170655"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bailiwick of Guernsey", + Iso2 = "GG", + Iso3 = "GGY", + Name = "Guernsey", + NumericCode = "831" + }, + new + { + Id = new Guid("3ffe68ca-7350-175b-4e95-0c34f54dc1f4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Guinea", + Iso2 = "GN", + Iso3 = "GIN", + Name = "Guinea", + NumericCode = "324" + }, + new + { + Id = new Guid("a9a5f440-a9bd-487d-e7f4-914df0d52fa6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Guinea-Bissau", + Iso2 = "GW", + Iso3 = "GNB", + Name = "Guinea-Bissau", + NumericCode = "624" + }, + new + { + Id = new Guid("a9949ac7-8d2d-32b5-3f4f-e2a3ef291a67"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Co-operative Republic of Guyana", + Iso2 = "GY", + Iso3 = "GUY", + Name = "Guyana", + NumericCode = "328" + }, + new + { + Id = new Guid("2bebebe4-edaa-9160-5a0c-4d99048bd8d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Haiti", + Iso2 = "HT", + Iso3 = "HTI", + Name = "Haiti", + NumericCode = "332" + }, + new + { + Id = new Guid("592b4658-a210-ab0a-5660-3dcc673dc581"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Heard Island and McDonald Islands", + Iso2 = "HM", + Iso3 = "HMD", + Name = "Heard Island and McDonald Islands", + NumericCode = "334" + }, + new + { + Id = new Guid("d0e11a85-6623-69f5-bd95-3779dfeec297"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Holy See (Vatican City State)", + Iso2 = "VA", + Iso3 = "VAT", + Name = "Holy See (Vatican City State)", + NumericCode = "336" + }, + new + { + Id = new Guid("0aebadaa-91b2-8794-c153-4f903a2a1004"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Honduras", + Iso2 = "HN", + Iso3 = "HND", + Name = "Honduras", + NumericCode = "340" + }, + new + { + Id = new Guid("500bb0de-61f5-dc9b-0488-1c507456ea4d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Hong Kong Special Administrative Region of China", + Iso2 = "HK", + Iso3 = "HKG", + Name = "Hong Kong", + NumericCode = "344" + }, + new + { + Id = new Guid("dcf19e1d-74a6-7b8b-a5ed-76b94a8ac2a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Hungary", + Iso2 = "HU", + Iso3 = "HUN", + Name = "Hungary", + NumericCode = "348" + }, + new + { + Id = new Guid("4ee6400d-5534-7c67-1521-870d6b732366"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Iceland", + Iso2 = "IS", + Iso3 = "ISL", + Name = "Iceland", + NumericCode = "352" + }, + new + { + Id = new Guid("72d8d1fe-d5f6-f440-1185-82ec69427027"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of India", + Iso2 = "IN", + Iso3 = "IND", + Name = "India", + NumericCode = "356" + }, + new + { + Id = new Guid("1d974338-decf-08e5-3e62-89e1bbdbb003"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Indonesia", + Iso2 = "ID", + Iso3 = "IDN", + Name = "Indonesia", + NumericCode = "360" + }, + new + { + Id = new Guid("b3460bab-2a35-57bc-17e2-4e117748bbb1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Islamic Republic of Iran", + Iso2 = "IR", + Iso3 = "IRN", + Name = "Iran", + NumericCode = "364" + }, + new + { + Id = new Guid("6c8be2e6-8c2e-cd80-68a6-d18c80d0eedc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Iraq", + Iso2 = "IQ", + Iso3 = "IRQ", + Name = "Iraq", + NumericCode = "368" + }, + new + { + Id = new Guid("294978f0-2702-d35d-cfc4-e676148aea2e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Ireland", + Iso2 = "IE", + Iso3 = "IRL", + Name = "Ireland", + NumericCode = "372" + }, + new + { + Id = new Guid("a1b83be0-6a9b-c8a9-2cce-531705a29664"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Isle of Man", + Iso2 = "IM", + Iso3 = "IMN", + Name = "Isle of Man", + NumericCode = "833" + }, + new + { + Id = new Guid("7ffa909b-8a6a-3028-9589-fcc3dfa530a8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Israel", + Iso2 = "IL", + Iso3 = "ISR", + Name = "Israel", + NumericCode = "376" + }, + new + { + Id = new Guid("7bbf15f4-a907-c0b2-7029-144aafb3c59d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Italy", + Iso2 = "IT", + Iso3 = "ITA", + Name = "Italy", + NumericCode = "380" + }, + new + { + Id = new Guid("6699efd5-0939-7812-315e-21f37b279ee9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Jamaica", + Iso2 = "JM", + Iso3 = "JAM", + Name = "Jamaica", + NumericCode = "388" + }, + new + { + Id = new Guid("13c69e56-375d-8a7e-c326-be2be2fd4cd8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Japan", + Iso2 = "JP", + Iso3 = "JPN", + Name = "Japan", + NumericCode = "392" + }, + new + { + Id = new Guid("65d871be-4a1d-a632-9cdb-62e3ff04928d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bailiwick of Jersey", + Iso2 = "JE", + Iso3 = "JEY", + Name = "Jersey", + NumericCode = "832" + }, + new + { + Id = new Guid("9ae7ad80-9ce7-6657-75cf-28b4c0254238"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Hashemite Kingdom of Jordan", + Iso2 = "JO", + Iso3 = "JOR", + Name = "Jordan", + NumericCode = "400" + }, + new + { + Id = new Guid("b723594d-7800-0f37-db86-0f6b85bb6cf9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Kazakhstan", + Iso2 = "KZ", + Iso3 = "KAZ", + Name = "Kazakhstan", + NumericCode = "398" + }, + new + { + Id = new Guid("b32fe2b5-a06e-0d76-ffd2-f186c3e64b15"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Kenya", + Iso2 = "KE", + Iso3 = "KEN", + Name = "Kenya", + NumericCode = "404" + }, + new + { + Id = new Guid("914618fd-86f9-827a-91b8-826f0db9e02d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Kiribati", + Iso2 = "KI", + Iso3 = "KIR", + Name = "Kiribati", + NumericCode = "296" + }, + new + { + Id = new Guid("f70ae426-f130-5637-0383-a5b63a06c500"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic People's Republic of Korea", + Iso2 = "KP", + Iso3 = "PRK", + Name = "Korea", + NumericCode = "408" + }, + new + { + Id = new Guid("7bf934fa-bcf4-80b5-fd7d-ab4cca45c67b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Korea", + Iso2 = "KR", + Iso3 = "KOR", + Name = "Korea", + NumericCode = "410" + }, + new + { + Id = new Guid("b6f70436-9515-7ef8-af57-aad196503499"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Kuwait", + Iso2 = "KW", + Iso3 = "KWT", + Name = "Kuwait", + NumericCode = "414" + }, + new + { + Id = new Guid("0932ed88-c79f-591a-d684-9a77735f947e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kyrgyz Republic", + Iso2 = "KG", + Iso3 = "KGZ", + Name = "Kyrgyz Republic", + NumericCode = "417" + }, + new + { + Id = new Guid("c4754c00-cfa5-aa6f-a9c8-a200457de7a8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Lao People's Democratic Republic", + Iso2 = "LA", + Iso3 = "LAO", + Name = "Lao People's Democratic Republic", + NumericCode = "418" + }, + new + { + Id = new Guid("9205dbfc-60cd-91d9-b0b8-8a18a3755286"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Latvia", + Iso2 = "LV", + Iso3 = "LVA", + Name = "Latvia", + NumericCode = "428" + }, + new + { + Id = new Guid("1e5c0dcc-83e9-f275-c81d-3bc49f88e70c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Lebanese Republic", + Iso2 = "LB", + Iso3 = "LBN", + Name = "Lebanon", + NumericCode = "422" + }, + new + { + Id = new Guid("bf210ee6-6c75-cf08-052e-5c3e608aed15"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Lesotho", + Iso2 = "LS", + Iso3 = "LSO", + Name = "Lesotho", + NumericCode = "426" + }, + new + { + Id = new Guid("ee926d09-799c-7c6a-2419-a6ff814b2c03"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Liberia", + Iso2 = "LR", + Iso3 = "LBR", + Name = "Liberia", + NumericCode = "430" + }, + new + { + Id = new Guid("695c85b3-a6c6-c217-9be8-3baebc7719ce"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Libya", + Iso2 = "LY", + Iso3 = "LBY", + Name = "Libya", + NumericCode = "434" + }, + new + { + Id = new Guid("9d6e6446-185e-235e-8771-9eb2d19f22e7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Principality of Liechtenstein", + Iso2 = "LI", + Iso3 = "LIE", + Name = "Liechtenstein", + NumericCode = "438" + }, + new + { + Id = new Guid("52538361-bbdf-fafb-e434-5655fc7451e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Lithuania", + Iso2 = "LT", + Iso3 = "LTU", + Name = "Lithuania", + NumericCode = "440" + }, + new + { + Id = new Guid("70673250-4cc3-3ba1-a42c-6b62ea8ab1d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Grand Duchy of Luxembourg", + Iso2 = "LU", + Iso3 = "LUX", + Name = "Luxembourg", + NumericCode = "442" + }, + new + { + Id = new Guid("8d32a12d-3230-1431-8fbb-72c789184345"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Macao Special Administrative Region of China", + Iso2 = "MO", + Iso3 = "MAC", + Name = "Macao", + NumericCode = "446" + }, + new + { + Id = new Guid("976e496f-ca38-d113-1697-8af2d9a3b159"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Madagascar", + Iso2 = "MG", + Iso3 = "MDG", + Name = "Madagascar", + NumericCode = "450" + }, + new + { + Id = new Guid("fbf4479d-d70d-c76e-b053-699362443a17"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Malawi", + Iso2 = "MW", + Iso3 = "MWI", + Name = "Malawi", + NumericCode = "454" + }, + new + { + Id = new Guid("d292ea2d-fbb6-7c1e-cb7d-23d552673776"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Malaysia", + Iso2 = "MY", + Iso3 = "MYS", + Name = "Malaysia", + NumericCode = "458" + }, + new + { + Id = new Guid("1d2aa3ab-e1c3-8c76-9be6-7a3b3eca35da"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Maldives", + Iso2 = "MV", + Iso3 = "MDV", + Name = "Maldives", + NumericCode = "462" + }, + new + { + Id = new Guid("c03d71a5-b215-8672-ec0c-dd8fe5c20e05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Mali", + Iso2 = "ML", + Iso3 = "MLI", + Name = "Mali", + NumericCode = "466" + }, + new + { + Id = new Guid("f0219540-8b2c-bd29-4f76-b832de53a56f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Malta", + Iso2 = "MT", + Iso3 = "MLT", + Name = "Malta", + NumericCode = "470" + }, + new + { + Id = new Guid("943d2419-2ca6-95f8-9c3b-ed445aea0371"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Marshall Islands", + Iso2 = "MH", + Iso3 = "MHL", + Name = "Marshall Islands", + NumericCode = "584" + }, + new + { + Id = new Guid("fc78fa89-b372-dcf7-7f1c-1e1bb14ecbe7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Martinique", + Iso2 = "MQ", + Iso3 = "MTQ", + Name = "Martinique", + NumericCode = "474" + }, + new + { + Id = new Guid("74da982f-cf20-e1b4-517b-a040511af23c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Islamic Republic of Mauritania", + Iso2 = "MR", + Iso3 = "MRT", + Name = "Mauritania", + NumericCode = "478" + }, + new + { + Id = new Guid("1b634ca2-2b90-7e54-715a-74cee7e4d294"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Mauritius", + Iso2 = "MU", + Iso3 = "MUS", + Name = "Mauritius", + NumericCode = "480" + }, + new + { + Id = new Guid("08a999e4-e420-b864-2864-bef78c138448"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Mayotte", + Iso2 = "YT", + Iso3 = "MYT", + Name = "Mayotte", + NumericCode = "175" + }, + new + { + Id = new Guid("a9940e91-93ef-19f7-79c0-00d31c6a9f87"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United Mexican States", + Iso2 = "MX", + Iso3 = "MEX", + Name = "Mexico", + NumericCode = "484" + }, + new + { + Id = new Guid("a2da72dc-5866-ba2f-6283-6575af00ade5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federated States of Micronesia", + Iso2 = "FM", + Iso3 = "FSM", + Name = "Micronesia", + NumericCode = "583" + }, + new + { + Id = new Guid("daf6bc7a-92c4-ef47-3111-e13199b86b90"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Moldova", + Iso2 = "MD", + Iso3 = "MDA", + Name = "Moldova", + NumericCode = "498" + }, + new + { + Id = new Guid("5cab34ca-8c74-0766-c7ca-4a826b44c5bd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Principality of Monaco", + Iso2 = "MC", + Iso3 = "MCO", + Name = "Monaco", + NumericCode = "492" + }, + new + { + Id = new Guid("c522b3d3-74cc-846f-0394-737dff4d2b1a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Mongolia", + Iso2 = "MN", + Iso3 = "MNG", + Name = "Mongolia", + NumericCode = "496" + }, + new + { + Id = new Guid("86db2170-be87-fd1d-bf57-05ff61ae83a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Montenegro", + Iso2 = "ME", + Iso3 = "MNE", + Name = "Montenegro", + NumericCode = "499" + }, + new + { + Id = new Guid("50e5954d-7cb4-2201-b96c-f2a846ab3ae3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Montserrat", + Iso2 = "MS", + Iso3 = "MSR", + Name = "Montserrat", + NumericCode = "500" + }, + new + { + Id = new Guid("915805f0-9ff0-48ff-39b3-44a4af5e0482"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Morocco", + Iso2 = "MA", + Iso3 = "MAR", + Name = "Morocco", + NumericCode = "504" + }, + new + { + Id = new Guid("10b58d9b-42ef-edb8-54a3-712636fda55a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Mozambique", + Iso2 = "MZ", + Iso3 = "MOZ", + Name = "Mozambique", + NumericCode = "508" + }, + new + { + Id = new Guid("015a9f83-6e57-bc1e-8227-24a4e5248582"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Union of Myanmar", + Iso2 = "MM", + Iso3 = "MMR", + Name = "Myanmar", + NumericCode = "104" + }, + new + { + Id = new Guid("0c0fef20-0e8d-98ea-7724-12cea9b3b926"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Namibia", + Iso2 = "NA", + Iso3 = "NAM", + Name = "Namibia", + NumericCode = "516" + }, + new + { + Id = new Guid("e3bacefb-d79b-1569-a91c-43d7e4f6f230"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Nauru", + Iso2 = "NR", + Iso3 = "NRU", + Name = "Nauru", + NumericCode = "520" + }, + new + { + Id = new Guid("e81c5db3-401a-e047-001e-045f39bef8ef"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Nepal", + Iso2 = "NP", + Iso3 = "NPL", + Name = "Nepal", + NumericCode = "524" + }, + new + { + Id = new Guid("cfff3443-1378-9c7d-9d58-66146d7f29a6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of the Netherlands", + Iso2 = "NL", + Iso3 = "NLD", + Name = "Netherlands", + NumericCode = "528" + }, + new + { + Id = new Guid("4b0729b6-f698-5730-767c-88e2d36691bb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "New Caledonia", + Iso2 = "NC", + Iso3 = "NCL", + Name = "New Caledonia", + NumericCode = "540" + }, + new + { + Id = new Guid("360e3c61-aaac-fa2f-d731-fc0824c05107"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "New Zealand", + Iso2 = "NZ", + Iso3 = "NZL", + Name = "New Zealand", + NumericCode = "554" + }, + new + { + Id = new Guid("cd0e8275-3def-1de4-8858-61aab36851c4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Nicaragua", + Iso2 = "NI", + Iso3 = "NIC", + Name = "Nicaragua", + NumericCode = "558" + }, + new + { + Id = new Guid("97cd39d5-1aca-8f10-9f5e-3f611d7606d8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Niger", + Iso2 = "NE", + Iso3 = "NER", + Name = "Niger", + NumericCode = "562" + }, + new + { + Id = new Guid("2e1bd9d8-df06-d773-0eb9-98e274b63b43"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federal Republic of Nigeria", + Iso2 = "NG", + Iso3 = "NGA", + Name = "Nigeria", + NumericCode = "566" + }, + new + { + Id = new Guid("3eea06f4-c085-f619-6d52-b76a5f6fd2b6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Niue", + Iso2 = "NU", + Iso3 = "NIU", + Name = "Niue", + NumericCode = "570" + }, + new + { + Id = new Guid("47804b6a-e705-b925-f4fd-4adf6500180b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Norfolk Island", + Iso2 = "NF", + Iso3 = "NFK", + Name = "Norfolk Island", + NumericCode = "574" + }, + new + { + Id = new Guid("aa0f69b2-93aa-ec51-b43b-60145db79e38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of North Macedonia", + Iso2 = "MK", + Iso3 = "MKD", + Name = "North Macedonia", + NumericCode = "807" + }, + new + { + Id = new Guid("6ac64a20-5688-ccd0-4eca-88d8a2560079"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of the Northern Mariana Islands", + Iso2 = "MP", + Iso3 = "MNP", + Name = "Northern Mariana Islands", + NumericCode = "580" + }, + new + { + Id = new Guid("914d7923-3ac5-75e8-c8e2-47d72561e35d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Norway", + Iso2 = "NO", + Iso3 = "NOR", + Name = "Norway", + NumericCode = "578" + }, + new + { + Id = new Guid("6c366974-3672-3a2c-2345-0fda33942304"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Sultanate of Oman", + Iso2 = "OM", + Iso3 = "OMN", + Name = "Oman", + NumericCode = "512" + }, + new + { + Id = new Guid("cc7fabfc-4c2b-d9ff-bb45-003bfc2e468a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Islamic Republic of Pakistan", + Iso2 = "PK", + Iso3 = "PAK", + Name = "Pakistan", + NumericCode = "586" + }, + new + { + Id = new Guid("057884bc-3c2e-dea9-6522-b003c9297f7a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Palau", + Iso2 = "PW", + Iso3 = "PLW", + Name = "Palau", + NumericCode = "585" + }, + new + { + Id = new Guid("d6d31cdd-280a-56bc-24a4-a414028d2b67"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Palestine", + Iso2 = "PS", + Iso3 = "PSE", + Name = "Palestine", + NumericCode = "275" + }, + new + { + Id = new Guid("7bf4a786-3733-c670-e85f-03ee3caa6ef9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Panama", + Iso2 = "PA", + Iso3 = "PAN", + Name = "Panama", + NumericCode = "591" + }, + new + { + Id = new Guid("c926f091-fe96-35b3-56b5-d418d17e0159"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Independent State of Papua New Guinea", + Iso2 = "PG", + Iso3 = "PNG", + Name = "Papua New Guinea", + NumericCode = "598" + }, + new + { + Id = new Guid("db6ce903-ab43-3793-960c-659529bae6df"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Paraguay", + Iso2 = "PY", + Iso3 = "PRY", + Name = "Paraguay", + NumericCode = "600" + }, + new + { + Id = new Guid("75634729-8e4a-4cfd-739d-9f679bfca3ab"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Peru", + Iso2 = "PE", + Iso3 = "PER", + Name = "Peru", + NumericCode = "604" + }, + new + { + Id = new Guid("c93bccaf-1835-3c02-e2ee-c113ced19e43"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Philippines", + Iso2 = "PH", + Iso3 = "PHL", + Name = "Philippines", + NumericCode = "608" + }, + new + { + Id = new Guid("a5d0c9af-2022-2b43-9332-eb6a2ce4305d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Pitcairn Islands", + Iso2 = "PN", + Iso3 = "PCN", + Name = "Pitcairn Islands", + NumericCode = "612" + }, + new + { + Id = new Guid("de503629-2607-b948-e279-0509d8109d0f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Poland", + Iso2 = "PL", + Iso3 = "POL", + Name = "Poland", + NumericCode = "616" + }, + new + { + Id = new Guid("2a039b16-2adf-0fb8-3bdf-fbdf14358d9d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Portuguese Republic", + Iso2 = "PT", + Iso3 = "PRT", + Name = "Portugal", + NumericCode = "620" + }, + new + { + Id = new Guid("cd2c97c3-5473-0719-3803-fcacedfe2ea2"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of Puerto Rico", + Iso2 = "PR", + Iso3 = "PRI", + Name = "Puerto Rico", + NumericCode = "630" + }, + new + { + Id = new Guid("067c9448-9ad0-2c21-a1dc-fbdf5a63d18d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Qatar", + Iso2 = "QA", + Iso3 = "QAT", + Name = "Qatar", + NumericCode = "634" + }, + new + { + Id = new Guid("881b4bb8-b6da-c73e-55c0-c9f31c02aaef"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Réunion", + Iso2 = "RE", + Iso3 = "REU", + Name = "Réunion", + NumericCode = "638" + }, + new + { + Id = new Guid("51aa4900-30a6-91b7-2728-071542a064ff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Romania", + Iso2 = "RO", + Iso3 = "ROU", + Name = "Romania", + NumericCode = "642" + }, + new + { + Id = new Guid("58337ef3-3d24-43e9-a440-832306e7fc07"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Russian Federation", + Iso2 = "RU", + Iso3 = "RUS", + Name = "Russian Federation", + NumericCode = "643" + }, + new + { + Id = new Guid("f5b15ea6-133d-c2c9-7ef9-b0916ea96edb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Rwanda", + Iso2 = "RW", + Iso3 = "RWA", + Name = "Rwanda", + NumericCode = "646" + }, + new + { + Id = new Guid("77f6f69b-ec41-8818-9395-8d39bf09e653"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Barthélemy", + Iso2 = "BL", + Iso3 = "BLM", + Name = "Saint Barthélemy", + NumericCode = "652" + }, + new + { + Id = new Guid("6a76d068-49e1-da80-ddb4-9ef3d11191e6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Helena, Ascension and Tristan da Cunha", + Iso2 = "SH", + Iso3 = "SHN", + Name = "Saint Helena, Ascension and Tristan da Cunha", + NumericCode = "654" + }, + new + { + Id = new Guid("fa633273-9866-840d-9739-c6c957901e46"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federation of Saint Kitts and Nevis", + Iso2 = "KN", + Iso3 = "KNA", + Name = "Saint Kitts and Nevis", + NumericCode = "659" + }, + new + { + Id = new Guid("220e980a-7363-0150-c250-89e83b967fb4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Lucia", + Iso2 = "LC", + Iso3 = "LCA", + Name = "Saint Lucia", + NumericCode = "662" + }, + new + { + Id = new Guid("899c2a9f-f35d-5a49-a6cd-f92531bb2266"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Martin (French part)", + Iso2 = "MF", + Iso3 = "MAF", + Name = "Saint Martin", + NumericCode = "663" + }, + new + { + Id = new Guid("5476986b-11a4-8463-9bd7-0f7354ec7a20"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Pierre and Miquelon", + Iso2 = "PM", + Iso3 = "SPM", + Name = "Saint Pierre and Miquelon", + NumericCode = "666" + }, + new + { + Id = new Guid("2f49855b-ff93-c399-d72a-121f2bf28bc9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Vincent and the Grenadines", + Iso2 = "VC", + Iso3 = "VCT", + Name = "Saint Vincent and the Grenadines", + NumericCode = "670" + }, + new + { + Id = new Guid("a7c4c9db-8fe4-7d43-e830-1a70954970c3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Independent State of Samoa", + Iso2 = "WS", + Iso3 = "WSM", + Name = "Samoa", + NumericCode = "882" + }, + new + { + Id = new Guid("0a25f96f-5173-2fff-a2f8-c6872393edf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of San Marino", + Iso2 = "SM", + Iso3 = "SMR", + Name = "San Marino", + NumericCode = "674" + }, + new + { + Id = new Guid("766c1ebb-78c1-bada-37fb-c45d1bd4baff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic Republic of Sao Tome and Principe", + Iso2 = "ST", + Iso3 = "STP", + Name = "Sao Tome and Principe", + NumericCode = "678" + }, + new + { + Id = new Guid("a8f30b36-4a25-3fb9-c69e-84ce6640d785"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Saudi Arabia", + Iso2 = "SA", + Iso3 = "SAU", + Name = "Saudi Arabia", + NumericCode = "682" + }, + new + { + Id = new Guid("3175ac19-c801-0b87-8e66-7480a40dcf1e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Senegal", + Iso2 = "SN", + Iso3 = "SEN", + Name = "Senegal", + NumericCode = "686" + }, + new + { + Id = new Guid("971c7e66-c6e3-71f4-580a-5caf2852f9f4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Serbia", + Iso2 = "RS", + Iso3 = "SRB", + Name = "Serbia", + NumericCode = "688" + }, + new + { + Id = new Guid("2167da32-4f80-d31d-226c-0551970304eb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Seychelles", + Iso2 = "SC", + Iso3 = "SYC", + Name = "Seychelles", + NumericCode = "690" + }, + new + { + Id = new Guid("b0f4bdfa-17dd-9714-4fe8-3c3b1f010ffa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Sierra Leone", + Iso2 = "SL", + Iso3 = "SLE", + Name = "Sierra Leone", + NumericCode = "694" + }, + new + { + Id = new Guid("3ce3d958-7341-bd79-f294-f2e6907c186c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Singapore", + Iso2 = "SG", + Iso3 = "SGP", + Name = "Singapore", + NumericCode = "702" + }, + new + { + Id = new Guid("141e589a-7046-a265-d2f6-b2f85e6eeadd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Sint Maarten (Dutch part)", + Iso2 = "SX", + Iso3 = "SXM", + Name = "Sint Maarten (Dutch part)", + NumericCode = "534" + }, + new + { + Id = new Guid("3252e51a-5bc1-f065-7101-5b34ba493dc4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Slovakia (Slovak Republic)", + Iso2 = "SK", + Iso3 = "SVK", + Name = "Slovakia (Slovak Republic)", + NumericCode = "703" + }, + new + { + Id = new Guid("357c121b-e28d-1765-e699-cc4ec5ff86fc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Slovenia", + Iso2 = "SI", + Iso3 = "SVN", + Name = "Slovenia", + NumericCode = "705" + }, + new + { + Id = new Guid("7453c201-ecf1-d3dd-0409-e94d0733173b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Solomon Islands", + Iso2 = "SB", + Iso3 = "SLB", + Name = "Solomon Islands", + NumericCode = "090" + }, + new + { + Id = new Guid("802c05db-3866-545d-dc1a-a02c83ea6cf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federal Republic of Somalia", + Iso2 = "SO", + Iso3 = "SOM", + Name = "Somalia", + NumericCode = "706" + }, + new + { + Id = new Guid("ebf38b9a-6fbe-6e82-3977-2c4763bea072"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of South Africa", + Iso2 = "ZA", + Iso3 = "ZAF", + Name = "South Africa", + NumericCode = "710" + }, + new + { + Id = new Guid("6af4d03e-edd0-d98a-bc7e-abc7df87d3dd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "South Georgia and the South Sandwich Islands", + Iso2 = "GS", + Iso3 = "SGS", + Name = "South Georgia and the South Sandwich Islands", + NumericCode = "239" + }, + new + { + Id = new Guid("6aac6f0e-d13a-a629-4c2b-9d6eaf6680e4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of South Sudan", + Iso2 = "SS", + Iso3 = "SSD", + Name = "South Sudan", + NumericCode = "728" + }, + new + { + Id = new Guid("414a34ce-2781-8f96-2bd0-7ada86c8cf38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Spain", + Iso2 = "ES", + Iso3 = "ESP", + Name = "Spain", + NumericCode = "724" + }, + new + { + Id = new Guid("687320c8-e841-c911-6d30-b14eb998feb6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic Socialist Republic of Sri Lanka", + Iso2 = "LK", + Iso3 = "LKA", + Name = "Sri Lanka", + NumericCode = "144" + }, + new + { + Id = new Guid("f0965449-6b15-6c1a-f5cb-ebd2d575c02c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Sudan", + Iso2 = "SD", + Iso3 = "SDN", + Name = "Sudan", + NumericCode = "729" + }, + new + { + Id = new Guid("61ba1844-4d33-84b4-dbac-70718aa91d59"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Suriname", + Iso2 = "SR", + Iso3 = "SUR", + Name = "Suriname", + NumericCode = "740" + }, + new + { + Id = new Guid("d525de3a-aecc-07de-0426-68f32af2968e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Svalbard & Jan Mayen Islands", + Iso2 = "SJ", + Iso3 = "SJM", + Name = "Svalbard & Jan Mayen Islands", + NumericCode = "744" + }, + new + { + Id = new Guid("a32a9fc2-677f-43e0-97aa-9e83943d785c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Eswatini", + Iso2 = "SZ", + Iso3 = "SWZ", + Name = "Eswatini", + NumericCode = "748" + }, + new + { + Id = new Guid("0ab731f0-5326-44be-af3a-20aa33ad0f35"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Sweden", + Iso2 = "SE", + Iso3 = "SWE", + Name = "Sweden", + NumericCode = "752" + }, + new + { + Id = new Guid("37c89068-a8e9-87e8-d651-f86fac63673a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Swiss Confederation", + Iso2 = "CH", + Iso3 = "CHE", + Name = "Switzerland", + NumericCode = "756" + }, + new + { + Id = new Guid("c1a923f6-b9ec-78f7-cc1c-7025e3d69d7d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Syrian Arab Republic", + Iso2 = "SY", + Iso3 = "SYR", + Name = "Syrian Arab Republic", + NumericCode = "760" + }, + new + { + Id = new Guid("875060ca-73f6-af3b-d844-1b1416ce4583"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Taiwan, Province of China", + Iso2 = "TW", + Iso3 = "TWN", + Name = "Taiwan", + NumericCode = "158" + }, + new + { + Id = new Guid("2a848549-9777-cf48-a0f2-b32c6f942096"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Tajikistan", + Iso2 = "TJ", + Iso3 = "TJK", + Name = "Tajikistan", + NumericCode = "762" + }, + new + { + Id = new Guid("4736c1ad-54bd-c8e8-d9ee-492a88268de8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United Republic of Tanzania", + Iso2 = "TZ", + Iso3 = "TZA", + Name = "Tanzania", + NumericCode = "834" + }, + new + { + Id = new Guid("84d58b3d-d131-1506-0792-1b3228b6f71f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Thailand", + Iso2 = "TH", + Iso3 = "THA", + Name = "Thailand", + NumericCode = "764" + }, + new + { + Id = new Guid("fb9a713c-2de1-882a-64b7-0e8fef5d2f7e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic Republic of Timor-Leste", + Iso2 = "TL", + Iso3 = "TLS", + Name = "Timor-Leste", + NumericCode = "626" + }, + new + { + Id = new Guid("9dacf00b-7d0a-d744-cc60-e5fa66371e9d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Togolese Republic", + Iso2 = "TG", + Iso3 = "TGO", + Name = "Togo", + NumericCode = "768" + }, + new + { + Id = new Guid("11765ad0-30f2-bab8-b616-20f88b28b21e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Tokelau", + Iso2 = "TK", + Iso3 = "TKL", + Name = "Tokelau", + NumericCode = "772" + }, + new + { + Id = new Guid("9e7dbdc3-2c8b-e8ae-082b-e02695f8268e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Tonga", + Iso2 = "TO", + Iso3 = "TON", + Name = "Tonga", + NumericCode = "776" + }, + new + { + Id = new Guid("95467997-f989-f456-34b7-0b578302dcba"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Trinidad and Tobago", + Iso2 = "TT", + Iso3 = "TTO", + Name = "Trinidad and Tobago", + NumericCode = "780" + }, + new + { + Id = new Guid("06f8ad57-7133-9a5e-5a83-53052012b014"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Tunisian Republic", + Iso2 = "TN", + Iso3 = "TUN", + Name = "Tunisia", + NumericCode = "788" + }, + new + { + Id = new Guid("f39cca22-449e-9866-3a65-465a5510483e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Türkiye", + Iso2 = "TR", + Iso3 = "TUR", + Name = "Türkiye", + NumericCode = "792" + }, + new + { + Id = new Guid("550ca5df-3995-617c-c39d-437beb400a42"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Turkmenistan", + Iso2 = "TM", + Iso3 = "TKM", + Name = "Turkmenistan", + NumericCode = "795" + }, + new + { + Id = new Guid("0e0fefd5-9a05-fde5-bee9-ef56db7748a1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Turks and Caicos Islands", + Iso2 = "TC", + Iso3 = "TCA", + Name = "Turks and Caicos Islands", + NumericCode = "796" + }, + new + { + Id = new Guid("e0d562ca-f573-3c2f-eb83-f72d4d70d4fc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Tuvalu", + Iso2 = "TV", + Iso3 = "TUV", + Name = "Tuvalu", + NumericCode = "798" + }, + new + { + Id = new Guid("3e2cccbe-1615-c707-a97b-421a799b2559"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Uganda", + Iso2 = "UG", + Iso3 = "UGA", + Name = "Uganda", + NumericCode = "800" + }, + new + { + Id = new Guid("e087f51c-feba-19b6-5595-fcbdce170411"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Ukraine", + Iso2 = "UA", + Iso3 = "UKR", + Name = "Ukraine", + NumericCode = "804" + }, + new + { + Id = new Guid("29201cbb-ca65-1924-75a9-0c4d4db43001"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United Arab Emirates", + Iso2 = "AE", + Iso3 = "ARE", + Name = "United Arab Emirates", + NumericCode = "784" + }, + new + { + Id = new Guid("0b3b04b4-9782-79e3-bc55-9ab33b6ae9c7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United Kingdom of Great Britain & Northern Ireland", + Iso2 = "GB", + Iso3 = "GBR", + Name = "United Kingdom of Great Britain and Northern Ireland", + NumericCode = "826" + }, + new + { + Id = new Guid("cb2e209b-d4c6-6d5c-8901-d989a9188783"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United States of America", + Iso2 = "US", + Iso3 = "USA", + Name = "United States of America", + NumericCode = "840" + }, + new + { + Id = new Guid("0868cdd3-7f50-5a25-88d6-98c45f9157e3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United States Minor Outlying Islands", + Iso2 = "UM", + Iso3 = "UMI", + Name = "United States Minor Outlying Islands", + NumericCode = "581" + }, + new + { + Id = new Guid("e1947bdc-ff2c-d2c1-3c55-f1f9bf778578"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United States Virgin Islands", + Iso2 = "VI", + Iso3 = "VIR", + Name = "United States Virgin Islands", + NumericCode = "850" + }, + new + { + Id = new Guid("8e787470-aae6-575a-fe0b-d65fc78b648a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Eastern Republic of Uruguay", + Iso2 = "UY", + Iso3 = "URY", + Name = "Uruguay", + NumericCode = "858" + }, + new + { + Id = new Guid("357369e3-85a8-86f7-91c7-349772ae7744"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Uzbekistan", + Iso2 = "UZ", + Iso3 = "UZB", + Name = "Uzbekistan", + NumericCode = "860" + }, + new + { + Id = new Guid("c98174ef-8198-54ba-2ff1-b93f3c646db8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Vanuatu", + Iso2 = "VU", + Iso3 = "VUT", + Name = "Vanuatu", + NumericCode = "548" + }, + new + { + Id = new Guid("52d9992c-19bd-82b4-9188-11dabcac6171"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bolivarian Republic of Venezuela", + Iso2 = "VE", + Iso3 = "VEN", + Name = "Venezuela", + NumericCode = "862" + }, + new + { + Id = new Guid("d7236157-d5a7-6b7a-3bc1-69802313fa30"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Socialist Republic of Vietnam", + Iso2 = "VN", + Iso3 = "VNM", + Name = "Vietnam", + NumericCode = "704" + }, + new + { + Id = new Guid("e186a953-7ab3-c009-501c-a754267b770b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Wallis and Futuna", + Iso2 = "WF", + Iso3 = "WLF", + Name = "Wallis and Futuna", + NumericCode = "876" + }, + new + { + Id = new Guid("2f4cc994-53f1-1763-8220-5d89e063804f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Western Sahara", + Iso2 = "EH", + Iso3 = "ESH", + Name = "Western Sahara", + NumericCode = "732" + }, + new + { + Id = new Guid("8c4441fd-8cd4-ff1e-928e-e46f9ca12552"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Yemen", + Iso2 = "YE", + Iso3 = "YEM", + Name = "Yemen", + NumericCode = "887" + }, + new + { + Id = new Guid("ab0b7e83-bf02-16e6-e5ae-46c4bd4c093b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Zambia", + Iso2 = "ZM", + Iso3 = "ZMB", + Name = "Zambia", + NumericCode = "894" + }, + new + { + Id = new Guid("6984f722-6963-d067-d4d4-9fd3ef2edbf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Zimbabwe", + Iso2 = "ZW", + Iso3 = "ZWE", + Name = "Zimbabwe", + NumericCode = "716" + }); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CitizenReportingEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("CountryId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("EnglishTitle") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringNgoForCitizenReportingId") + .HasColumnType("uuid"); + + b.Property("PollingStationsVersion") + .HasColumnType("uuid"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("CountryId"); + + b.HasIndex("MonitoringNgoForCitizenReportingId"); + + b.ToTable("ElectionRounds"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ExportedDataAggregate.ExportedData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Base64EncodedData") + .HasColumnType("text"); + + b.Property("CompletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("ExportStatus") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExportedDataType") + .IsRequired() + .HasColumnType("text"); + + b.Property("FileName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("StartedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("Id"); + + b.ToTable("ExportedData", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FeedbackAggregate.Feedback", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property>("Metadata") + .IsRequired() + .HasColumnType("hstore"); + + b.Property("ObserverId") + .HasColumnType("uuid"); + + b.Property("TimeSubmitted") + .HasColumnType("timestamp with time zone"); + + b.Property("UserFeedback") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("ObserverId"); + + b.ToTable("UserFeedback"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormAggregate.Form", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DefaultLanguage") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Languages") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("LanguagesTranslationStatus") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringNgoId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("NumberOfQuestions") + .HasColumnType("integer"); + + b.Property("Questions") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("MonitoringNgoId"); + + b.ToTable("Forms"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormSubmissionAggregate.FormSubmission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Answers") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FollowUpStatus") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("NotApplicable"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("NumberOfFlaggedAnswers") + .HasColumnType("integer"); + + b.Property("NumberOfQuestionsAnswered") + .HasColumnType("integer"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("FormId"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.HasIndex("ElectionRoundId", "PollingStationId", "MonitoringObserverId", "FormId") + .IsUnique(); + + b.ToTable("FormSubmissions", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormTemplateAggregate.FormTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DefaultLanguage") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("FormTemplateType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Languages") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("NumberOfQuestions") + .HasColumnType("integer"); + + b.Property("Questions") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("FormTemplates"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ImportValidationErrorsAggregate.ImportValidationErrors", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Data") + .IsRequired() + .HasColumnType("text"); + + b.Property("ImportType") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("OriginalFileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("Id"); + + b.ToTable("ImportValidationErrors"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.LanguageAggregate.Language", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Iso1") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("character varying(2)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NativeName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("Id"); + + b.HasIndex("Iso1") + .IsUnique(); + + b.ToTable("Language"); + + b.HasData( + new + { + Id = new Guid("9c11bb58-5135-453a-1d24-dc20ef0e9031"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AA", + Name = "Afar", + NativeName = "Afaraf" + }, + new + { + Id = new Guid("bd4f1638-6017-733d-f696-b8b4d72664d7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AB", + Name = "Abkhaz", + NativeName = "аҧсуа бызшәа" + }, + new + { + Id = new Guid("29201cbb-ca65-1924-75a9-0c4d4db43001"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AE", + Name = "Avestan", + NativeName = "avesta" + }, + new + { + Id = new Guid("edd4319b-86f3-24cb-248c-71da624c02f7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AF", + Name = "Afrikaans", + NativeName = "Afrikaans" + }, + new + { + Id = new Guid("ef584e3c-03f2-42b0-7139-69d15d21e5a8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AK", + Name = "Akan", + NativeName = "Akan" + }, + new + { + Id = new Guid("688af4c8-9d64-ae1c-147f-b8afd54801e3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AM", + Name = "Amharic", + NativeName = "አማርኛ" + }, + new + { + Id = new Guid("d4d5c45a-d3c2-891e-6d7d-75569c3386ac"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AN", + Name = "Aragonese", + NativeName = "aragonés" + }, + new + { + Id = new Guid("a7afb7b1-b26d-4571-1a1f-3fff738ff21e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AR", + Name = "Arabic", + NativeName = "اَلْعَرَبِيَّةُ" + }, + new + { + Id = new Guid("538114de-7db0-9242-35e6-324fa7eff44d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AS", + Name = "Assamese", + NativeName = "অসমীয়া" + }, + new + { + Id = new Guid("e43a2010-14fc-63a9-f9d3-0ab2a1d0e52f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AV", + Name = "Avaric", + NativeName = "авар мацӀ" + }, + new + { + Id = new Guid("78c6e8af-fcb4-c783-987c-7e1aca3aed64"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AY", + Name = "Aymara", + NativeName = "aymar aru" + }, + new + { + Id = new Guid("008c3138-73d8-dbbc-f1dd-521e4c68bcf1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AZ", + Name = "Azerbaijani", + NativeName = "azərbaycan dili" + }, + new + { + Id = new Guid("a7716d29-6ef6-b775-51c5-97094536329d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BA", + Name = "Bashkir", + NativeName = "башҡорт теле" + }, + new + { + Id = new Guid("0797a7d5-bbc0-2e52-0de8-14a42fc80baa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BE", + Name = "Belarusian", + NativeName = "беларуская мова" + }, + new + { + Id = new Guid("46576b73-c05b-7498-5b07-9bbf59b7645d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BG", + Name = "Bulgarian", + NativeName = "български език" + }, + new + { + Id = new Guid("75e4464b-a784-63b8-1ecc-69ee1f09f43f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BI", + Name = "Bislama", + NativeName = "Bislama" + }, + new + { + Id = new Guid("ca2a5560-d4c4-3c87-3090-6f5436310b55"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BM", + Name = "Bambara", + NativeName = "bamanankan" + }, + new + { + Id = new Guid("ed6278e0-436c-9fd9-0b9e-44fd424cbd1b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BN", + Name = "Bengali", + NativeName = "বাংলা" + }, + new + { + Id = new Guid("f33ced84-eb43-fb39-ef79-b266e4d4cd94"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BO", + Name = "Tibetan", + NativeName = "བོད་ཡིག" + }, + new + { + Id = new Guid("5283afbb-2744-e930-2c16-c5ea6b0ff7cc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BR", + Name = "Breton", + NativeName = "brezhoneg" + }, + new + { + Id = new Guid("46e88019-c521-57b2-d1c0-c0e2478d3b05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BS", + Name = "Bosnian", + NativeName = "bosanski jezik" + }, + new + { + Id = new Guid("5c0e654b-8547-5d02-ee7b-d65e3c5c5273"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CA", + Name = "Catalan", + NativeName = "Català" + }, + new + { + Id = new Guid("cd5689d6-7a06-73c7-650e-f6f94387fd88"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CE", + Name = "Chechen", + NativeName = "нохчийн мотт" + }, + new + { + Id = new Guid("37c89068-a8e9-87e8-d651-f86fac63673a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CH", + Name = "Chamorro", + NativeName = "Chamoru" + }, + new + { + Id = new Guid("c64288fc-d941-0615-47f9-28e6c294ce26"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CO", + Name = "Corsican", + NativeName = "corsu" + }, + new + { + Id = new Guid("d13935c1-8956-1399-7c4e-0354795cd37b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CR", + Name = "Cree", + NativeName = "ᓀᐦᐃᔭᐍᐏᐣ" + }, + new + { + Id = new Guid("4def223a-9524-596d-cc29-ab7830c590de"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CS", + Name = "Czech", + NativeName = "čeština" + }, + new + { + Id = new Guid("57765d87-2424-2c86-ad9c-1af58ef3127a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CU", + Name = "Old Church Slavonic", + NativeName = "ѩзыкъ словѣньскъ" + }, + new + { + Id = new Guid("17ed5f0f-e091-94ff-0512-ad291bde94d7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CV", + Name = "Chuvash", + NativeName = "чӑваш чӗлхи" + }, + new + { + Id = new Guid("df20d0d7-9fbe-e725-d966-4fdf9f5c9dfb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CY", + Name = "Welsh", + NativeName = "Cymraeg" + }, + new + { + Id = new Guid("b356a541-1383-3c0a-9afd-6aebae3753cb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "DA", + Name = "Danish", + NativeName = "dansk" + }, + new + { + Id = new Guid("46ef1468-86f6-0c99-f4e9-46f966167b05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "DE", + Name = "German", + NativeName = "Deutsch" + }, + new + { + Id = new Guid("d8d4f63d-fa65-63dd-a788-de2eec3d24ec"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "DV", + Name = "Divehi", + NativeName = "ދިވެހި" + }, + new + { + Id = new Guid("fee6f04f-c4c1-e3e4-645d-bb6bb703aeb7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "DZ", + Name = "Dzongkha", + NativeName = "རྫོང་ཁ" + }, + new + { + Id = new Guid("2dc643bd-cc6c-eb0c-7314-44123576f0ee"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EE", + Name = "Ewe", + NativeName = "Eʋegbe" + }, + new + { + Id = new Guid("b9da7f73-60cd-404c-18fb-1bc5bbfffb38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EL", + Name = "Greek", + NativeName = "Ελληνικά" + }, + new + { + Id = new Guid("094b3769-68b1-6211-ba2d-6bba92d6a167"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EN", + Name = "English", + NativeName = "English" + }, + new + { + Id = new Guid("1da84244-fa39-125e-06dc-3c0cb2342ce9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EO", + Name = "Esperanto", + NativeName = "Esperanto" + }, + new + { + Id = new Guid("414a34ce-2781-8f96-2bd0-7ada86c8cf38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ES", + Name = "Spanish", + NativeName = "Español" + }, + new + { + Id = new Guid("e75515a6-63cf-3612-a3a2-befa0d7048a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ET", + Name = "Estonian", + NativeName = "eesti" + }, + new + { + Id = new Guid("b2a87091-32fb-ba34-a721-bf8b3de5935d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EU", + Name = "Basque", + NativeName = "euskara" + }, + new + { + Id = new Guid("e9da8997-dee8-0c2d-79d3-05fafc45092e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FA", + Name = "Persian", + NativeName = "فارسی" + }, + new + { + Id = new Guid("51a86a09-0d0b-31c1-90f1-f237db8e29ad"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FF", + Name = "Fula", + NativeName = "Fulfulde" + }, + new + { + Id = new Guid("5a5d9168-081b-1e02-1fbb-cdfa910e526c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FI", + Name = "Finnish", + NativeName = "suomi" + }, + new + { + Id = new Guid("0e2a1681-d852-67ae-7387-0d04be9e7fd3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FJ", + Name = "Fijian", + NativeName = "vosa Vakaviti" + }, + new + { + Id = new Guid("0d4fe6e6-ea1e-d1ce-5134-6c0c1a696a00"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FO", + Name = "Faroese", + NativeName = "føroyskt" + }, + new + { + Id = new Guid("b2261c50-1a57-7f1f-d72d-f8c21593874f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FR", + Name = "French", + NativeName = "Français" + }, + new + { + Id = new Guid("fb429393-f994-0a16-37f9-edc0510fced5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FY", + Name = "Western Frisian", + NativeName = "Frysk" + }, + new + { + Id = new Guid("4826bc0f-235e-572f-2b1a-21f1c9e05f83"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GA", + Name = "Irish", + NativeName = "Gaeilge" + }, + new + { + Id = new Guid("ff5b4d88-c179-ff0d-6285-cf46ba475d7d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GD", + Name = "Scottish Gaelic", + NativeName = "Gàidhlig" + }, + new + { + Id = new Guid("2f00fe86-a06b-dc95-0ea7-4520d1dec784"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GL", + Name = "Galician", + NativeName = "galego" + }, + new + { + Id = new Guid("3ffe68ca-7350-175b-4e95-0c34f54dc1f4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GN", + Name = "Guaraní", + NativeName = "Avañe'ẽ" + }, + new + { + Id = new Guid("096a8586-9702-6fec-5f6a-6eb3b7b7837f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GU", + Name = "Gujarati", + NativeName = "ગુજરાતી" + }, + new + { + Id = new Guid("849b5e66-dc68-a1ed-6ed3-e315fbd0a0e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GV", + Name = "Manx", + NativeName = "Gaelg" + }, + new + { + Id = new Guid("2e9cb133-68a7-2f3b-49d1-0921cf42dfae"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HA", + Name = "Hausa", + NativeName = "هَوُسَ" + }, + new + { + Id = new Guid("d685aa26-aee7-716b-9433-1b3411209f4b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HE", + Name = "Hebrew", + NativeName = "עברית" + }, + new + { + Id = new Guid("54686fcd-3f35-f468-7c9c-93217c5084bc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HI", + Name = "Hindi", + NativeName = "हिन्दी" + }, + new + { + Id = new Guid("87813ec7-4830-e4dc-5ab1-bd599057ede0"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HO", + Name = "Hiri Motu", + NativeName = "Hiri Motu" + }, + new + { + Id = new Guid("1f8be615-5746-277e-d82b-47596b5bb922"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HR", + Name = "Croatian", + NativeName = "Hrvatski" + }, + new + { + Id = new Guid("2bebebe4-edaa-9160-5a0c-4d99048bd8d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HT", + Name = "Haitian", + NativeName = "Kreyòl ayisyen" + }, + new + { + Id = new Guid("dcf19e1d-74a6-7b8b-a5ed-76b94a8ac2a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HU", + Name = "Hungarian", + NativeName = "magyar" + }, + new + { + Id = new Guid("d832c50a-112e-4591-9432-4ada24bc85b2"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HY", + Name = "Armenian", + NativeName = "Հայերեն" + }, + new + { + Id = new Guid("d5bffdfb-6a8e-6d9f-2e59-4ada912acdba"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HZ", + Name = "Herero", + NativeName = "Otjiherero" + }, + new + { + Id = new Guid("7f065da7-4ba4-81ca-5126-dbf606a73907"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IA", + Name = "Interlingua", + NativeName = "Interlingua" + }, + new + { + Id = new Guid("1d974338-decf-08e5-3e62-89e1bbdbb003"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ID", + Name = "Indonesian", + NativeName = "Bahasa Indonesia" + }, + new + { + Id = new Guid("294978f0-2702-d35d-cfc4-e676148aea2e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IE", + Name = "Interlingue", + NativeName = "Interlingue" + }, + new + { + Id = new Guid("caddae27-283a-82b2-9365-76a3d6c49eee"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IG", + Name = "Igbo", + NativeName = "Asụsụ Igbo" + }, + new + { + Id = new Guid("f21f562e-5c35-4806-4efc-416619b5b7f7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "II", + Name = "Nuosu", + NativeName = "ꆈꌠ꒿ Nuosuhxop" + }, + new + { + Id = new Guid("23785991-fef4-e625-4d3b-b6ac364d0fa0"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IK", + Name = "Inupiaq", + NativeName = "Iñupiaq" + }, + new + { + Id = new Guid("b8b09512-ea4c-4a61-9331-304f55324ef7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IO", + Name = "Ido", + NativeName = "Ido" + }, + new + { + Id = new Guid("4ee6400d-5534-7c67-1521-870d6b732366"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IS", + Name = "Icelandic", + NativeName = "Íslenska" + }, + new + { + Id = new Guid("7bbf15f4-a907-c0b2-7029-144aafb3c59d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IT", + Name = "Italian", + NativeName = "Italiano" + }, + new + { + Id = new Guid("899392d7-d54f-a1c6-407a-1bada9b85fdd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IU", + Name = "Inuktitut", + NativeName = "ᐃᓄᒃᑎᑐᑦ" + }, + new + { + Id = new Guid("6857242c-f772-38b5-b5a2-c8e8b9db551f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "JA", + Name = "Japanese", + NativeName = "日本語" + }, + new + { + Id = new Guid("e7532b00-3b1b-ff2c-b7c0-26bd7e91af55"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "JV", + Name = "Javanese", + NativeName = "basa Jawa" + }, + new + { + Id = new Guid("9204928b-c569-ef6a-446e-4853aee439b0"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KA", + Name = "Georgian", + NativeName = "ქართული" + }, + new + { + Id = new Guid("0932ed88-c79f-591a-d684-9a77735f947e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KG", + Name = "Kongo", + NativeName = "Kikongo" + }, + new + { + Id = new Guid("914618fd-86f9-827a-91b8-826f0db9e02d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KI", + Name = "Kikuyu", + NativeName = "Gĩkũyũ" + }, + new + { + Id = new Guid("80ecea2c-8969-1929-0d4a-39ed2324abc6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KJ", + Name = "Kwanyama", + NativeName = "Kuanyama" + }, + new + { + Id = new Guid("b6b2351f-4f1e-c92f-0e9a-a915f4cc5fa6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KK", + Name = "Kazakh", + NativeName = "қазақ тілі" + }, + new + { + Id = new Guid("081a5fdb-445a-015a-1e36-f2e5014265ae"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KL", + Name = "Kalaallisut", + NativeName = "kalaallisut" + }, + new + { + Id = new Guid("5e7a08f2-7d59-bcdb-7ddd-876b87181420"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KM", + Name = "Khmer", + NativeName = "ខេមរភាសា" + }, + new + { + Id = new Guid("fa633273-9866-840d-9739-c6c957901e46"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KN", + Name = "Kannada", + NativeName = "ಕನ್ನಡ" + }, + new + { + Id = new Guid("74f19a84-b1c5-fa2d-8818-2220b80a3056"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KO", + Name = "Korean", + NativeName = "한국어" + }, + new + { + Id = new Guid("7bf934fa-bcf4-80b5-fd7d-ab4cca45c67b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KR", + Name = "Kanuri", + NativeName = "Kanuri" + }, + new + { + Id = new Guid("eace47f6-5499-f4f0-8f97-ed165b681d84"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KS", + Name = "Kashmiri", + NativeName = "कश्मीरी" + }, + new + { + Id = new Guid("7451108d-ad49-940a-d479-4d868b62a7c6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KU", + Name = "Kurdish", + NativeName = "Kurdî" + }, + new + { + Id = new Guid("78b7020d-8b82-3fae-2049-30e490ae1faf"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KV", + Name = "Komi", + NativeName = "коми кыв" + }, + new + { + Id = new Guid("b6f70436-9515-7ef8-af57-aad196503499"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KW", + Name = "Cornish", + NativeName = "Kernewek" + }, + new + { + Id = new Guid("3c5828e0-16a8-79ba-4e5c-9b45065df113"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KY", + Name = "Kyrgyz", + NativeName = "Кыргызча" + }, + new + { + Id = new Guid("c4754c00-cfa5-aa6f-a9c8-a200457de7a8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LA", + Name = "Latin", + NativeName = "latine" + }, + new + { + Id = new Guid("1e5c0dcc-83e9-f275-c81d-3bc49f88e70c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LB", + Name = "Luxembourgish", + NativeName = "Lëtzebuergesch" + }, + new + { + Id = new Guid("80b770b8-4797-3d62-ef66-1ded7b0da0e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LG", + Name = "Ganda", + NativeName = "Luganda" + }, + new + { + Id = new Guid("9d6e6446-185e-235e-8771-9eb2d19f22e7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LI", + Name = "Limburgish", + NativeName = "Limburgs" + }, + new + { + Id = new Guid("ca44a869-d3b6-052d-1e1a-ad4e3682a2ed"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LN", + Name = "Lingala", + NativeName = "Lingála" + }, + new + { + Id = new Guid("e9ad0bec-7dee-bd01-9528-1fc74d1d78dd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LO", + Name = "Lao", + NativeName = "ພາສາລາວ" + }, + new + { + Id = new Guid("52538361-bbdf-fafb-e434-5655fc7451e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LT", + Name = "Lithuanian", + NativeName = "lietuvių kalba" + }, + new + { + Id = new Guid("70673250-4cc3-3ba1-a42c-6b62ea8ab1d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LU", + Name = "Luba-Katanga", + NativeName = "Kiluba" + }, + new + { + Id = new Guid("9205dbfc-60cd-91d9-b0b8-8a18a3755286"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LV", + Name = "Latvian", + NativeName = "latviešu valoda" + }, + new + { + Id = new Guid("976e496f-ca38-d113-1697-8af2d9a3b159"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MG", + Name = "Malagasy", + NativeName = "fiteny malagasy" + }, + new + { + Id = new Guid("943d2419-2ca6-95f8-9c3b-ed445aea0371"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MH", + Name = "Marshallese", + NativeName = "Kajin M̧ajeļ" + }, + new + { + Id = new Guid("54726f17-03b8-8af3-0359-c42d8fe8459d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MI", + Name = "Māori", + NativeName = "te reo Māori" + }, + new + { + Id = new Guid("aa0f69b2-93aa-ec51-b43b-60145db79e38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MK", + Name = "Macedonian", + NativeName = "македонски јазик" + }, + new + { + Id = new Guid("c03d71a5-b215-8672-ec0c-dd8fe5c20e05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ML", + Name = "Malayalam", + NativeName = "മലയാളം" + }, + new + { + Id = new Guid("c522b3d3-74cc-846f-0394-737dff4d2b1a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MN", + Name = "Mongolian", + NativeName = "Монгол хэл" + }, + new + { + Id = new Guid("74da982f-cf20-e1b4-517b-a040511af23c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MR", + Name = "Marathi", + NativeName = "मराठी" + }, + new + { + Id = new Guid("50e5954d-7cb4-2201-b96c-f2a846ab3ae3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MS", + Name = "Malay", + NativeName = "Bahasa Melayu" + }, + new + { + Id = new Guid("f0219540-8b2c-bd29-4f76-b832de53a56f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MT", + Name = "Maltese", + NativeName = "Malti" + }, + new + { + Id = new Guid("d292ea2d-fbb6-7c1e-cb7d-23d552673776"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MY", + Name = "Burmese", + NativeName = "ဗမာစာ" + }, + new + { + Id = new Guid("0c0fef20-0e8d-98ea-7724-12cea9b3b926"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NA", + Name = "Nauru", + NativeName = "Dorerin Naoero" + }, + new + { + Id = new Guid("4a3aa5a4-473f-45cd-f054-fa0465c476a4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NB", + Name = "Norwegian Bokmål", + NativeName = "Norsk bokmål" + }, + new + { + Id = new Guid("b4292ad3-3ca8-eea5-f3e0-d1983db8f61e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ND", + Name = "Northern Ndebele", + NativeName = "isiNdebele" + }, + new + { + Id = new Guid("97cd39d5-1aca-8f10-9f5e-3f611d7606d8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NE", + Name = "Nepali", + NativeName = "नेपाली" + }, + new + { + Id = new Guid("2e1bd9d8-df06-d773-0eb9-98e274b63b43"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NG", + Name = "Ndonga", + NativeName = "Owambo" + }, + new + { + Id = new Guid("cfff3443-1378-9c7d-9d58-66146d7f29a6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NL", + Name = "Dutch", + NativeName = "Nederlands" + }, + new + { + Id = new Guid("df41c815-40f8-197a-7a8b-e456d43283d9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NN", + Name = "Norwegian Nynorsk", + NativeName = "Norsk nynorsk" + }, + new + { + Id = new Guid("914d7923-3ac5-75e8-c8e2-47d72561e35d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NO", + Name = "Norwegian", + NativeName = "Norsk" + }, + new + { + Id = new Guid("e3bacefb-d79b-1569-a91c-43d7e4f6f230"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NR", + Name = "Southern Ndebele", + NativeName = "isiNdebele" + }, + new + { + Id = new Guid("67729f87-ef47-dd3f-65f7-b0f6df0d6384"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NV", + Name = "Navajo", + NativeName = "Diné bizaad" + }, + new + { + Id = new Guid("720b4e12-b001-8d38-7c07-f43194b9645d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NY", + Name = "Chichewa", + NativeName = "chiCheŵa" + }, + new + { + Id = new Guid("2b6d383a-9ab6-fcdf-bcfe-a4538faca407"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OC", + Name = "Occitan", + NativeName = "occitan" + }, + new + { + Id = new Guid("9ec46cb5-6c2b-0e22-07c5-eb2fe1b8d2ff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OJ", + Name = "Ojibwe", + NativeName = "ᐊᓂᔑᓈᐯᒧᐎᓐ" + }, + new + { + Id = new Guid("6c366974-3672-3a2c-2345-0fda33942304"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OM", + Name = "Oromo", + NativeName = "Afaan Oromoo" + }, + new + { + Id = new Guid("285b9e82-38af-33ab-79fd-0b4f3fd4f2f1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OR", + Name = "Oriya", + NativeName = "ଓଡ଼ିଆ" + }, + new + { + Id = new Guid("2d013d34-b258-8fe9-ef52-dd34e82a4672"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OS", + Name = "Ossetian", + NativeName = "ирон æвзаг" + }, + new + { + Id = new Guid("7bf4a786-3733-c670-e85f-03ee3caa6ef9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PA", + Name = "Panjabi", + NativeName = "ਪੰਜਾਬੀ" + }, + new + { + Id = new Guid("d8ef067c-1087-4ff5-8e1f-2291df7ac958"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PI", + Name = "Pāli", + NativeName = "पाऴि" + }, + new + { + Id = new Guid("de503629-2607-b948-e279-0509d8109d0f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PL", + Name = "Polish", + NativeName = "Polski" + }, + new + { + Id = new Guid("d6d31cdd-280a-56bc-24a4-a414028d2b67"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PS", + Name = "Pashto", + NativeName = "پښتو" + }, + new + { + Id = new Guid("2a039b16-2adf-0fb8-3bdf-fbdf14358d9d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PT", + Name = "Portuguese", + NativeName = "Português" + }, + new + { + Id = new Guid("93fb8ace-4156-12d5-218e-64b7d35129b1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "QU", + Name = "Quechua", + NativeName = "Runa Simi" + }, + new + { + Id = new Guid("136610e1-8115-9cf1-d671-7950c6483495"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RM", + Name = "Romansh", + NativeName = "rumantsch grischun" + }, + new + { + Id = new Guid("7a0725cf-311a-4f59-cff8-ad8b43dd226e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RN", + Name = "Kirundi", + NativeName = "Ikirundi" + }, + new + { + Id = new Guid("51aa4900-30a6-91b7-2728-071542a064ff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RO", + Name = "Romanian", + NativeName = "Română" + }, + new + { + Id = new Guid("58337ef3-3d24-43e9-a440-832306e7fc07"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RU", + Name = "Russian", + NativeName = "Русский" + }, + new + { + Id = new Guid("f5b15ea6-133d-c2c9-7ef9-b0916ea96edb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RW", + Name = "Kinyarwanda", + NativeName = "Ikinyarwanda" + }, + new + { + Id = new Guid("a8f30b36-4a25-3fb9-c69e-84ce6640d785"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SA", + Name = "Sanskrit", + NativeName = "संस्कृतम्" + }, + new + { + Id = new Guid("2167da32-4f80-d31d-226c-0551970304eb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SC", + Name = "Sardinian", + NativeName = "sardu" + }, + new + { + Id = new Guid("f0965449-6b15-6c1a-f5cb-ebd2d575c02c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SD", + Name = "Sindhi", + NativeName = "सिन्धी" + }, + new + { + Id = new Guid("0ab731f0-5326-44be-af3a-20aa33ad0f35"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SE", + Name = "Northern Sami", + NativeName = "Davvisámegiella" + }, + new + { + Id = new Guid("3ce3d958-7341-bd79-f294-f2e6907c186c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SG", + Name = "Sango", + NativeName = "yângâ tî sängö" + }, + new + { + Id = new Guid("357c121b-e28d-1765-e699-cc4ec5ff86fc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SI", + Name = "Sinhala", + NativeName = "සිංහල" + }, + new + { + Id = new Guid("3252e51a-5bc1-f065-7101-5b34ba493dc4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SK", + Name = "Slovak", + NativeName = "slovenčina" + }, + new + { + Id = new Guid("b0f4bdfa-17dd-9714-4fe8-3c3b1f010ffa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SL", + Name = "Slovenian", + NativeName = "slovenščina" + }, + new + { + Id = new Guid("0a25f96f-5173-2fff-a2f8-c6872393edf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SM", + Name = "Samoan", + NativeName = "gagana fa'a Samoa" + }, + new + { + Id = new Guid("3175ac19-c801-0b87-8e66-7480a40dcf1e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SN", + Name = "Shona", + NativeName = "chiShona" + }, + new + { + Id = new Guid("802c05db-3866-545d-dc1a-a02c83ea6cf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SO", + Name = "Somali", + NativeName = "Soomaaliga" + }, + new + { + Id = new Guid("fb1cce84-4a6c-1834-0ff2-6df002e3d56f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SQ", + Name = "Albanian", + NativeName = "Shqip" + }, + new + { + Id = new Guid("61ba1844-4d33-84b4-dbac-70718aa91d59"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SR", + Name = "Serbian", + NativeName = "српски језик" + }, + new + { + Id = new Guid("6aac6f0e-d13a-a629-4c2b-9d6eaf6680e4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SS", + Name = "Swati", + NativeName = "SiSwati" + }, + new + { + Id = new Guid("766c1ebb-78c1-bada-37fb-c45d1bd4baff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ST", + Name = "Southern Sotho", + NativeName = "Sesotho" + }, + new + { + Id = new Guid("ee1ace14-e945-4767-85ec-3d74be8b516b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SU", + Name = "Sundanese", + NativeName = "Basa Sunda" + }, + new + { + Id = new Guid("4d8bcda4-5598-16cd-b379-97eb7a5e1c29"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SV", + Name = "Swedish", + NativeName = "Svenska" + }, + new + { + Id = new Guid("5f002f07-f2c3-9fa4-2e29-225d116c10a3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SW", + Name = "Swahili", + NativeName = "Kiswahili" + }, + new + { + Id = new Guid("8bc44f03-84a5-2afc-8b0b-40c727e4ce36"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TA", + Name = "Tamil", + NativeName = "தமிழ்" + }, + new + { + Id = new Guid("3bf5a74a-6d12-e971-16bc-c75e487f2615"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TE", + Name = "Telugu", + NativeName = "తెలుగు" + }, + new + { + Id = new Guid("9dacf00b-7d0a-d744-cc60-e5fa66371e9d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TG", + Name = "Tajik", + NativeName = "тоҷикӣ" + }, + new + { + Id = new Guid("84d58b3d-d131-1506-0792-1b3228b6f71f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TH", + Name = "Thai", + NativeName = "ไทย" + }, + new + { + Id = new Guid("596e8283-10ce-d81d-2e6f-400fa259d717"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TI", + Name = "Tigrinya", + NativeName = "ትግርኛ" + }, + new + { + Id = new Guid("11765ad0-30f2-bab8-b616-20f88b28b21e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TK", + Name = "Turkmen", + NativeName = "Türkmençe" + }, + new + { + Id = new Guid("fb9a713c-2de1-882a-64b7-0e8fef5d2f7e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TL", + Name = "Tagalog", + NativeName = "Wikang Tagalog" + }, + new + { + Id = new Guid("06f8ad57-7133-9a5e-5a83-53052012b014"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TN", + Name = "Tswana", + NativeName = "Setswana" + }, + new + { + Id = new Guid("9e7dbdc3-2c8b-e8ae-082b-e02695f8268e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TO", + Name = "Tonga", + NativeName = "faka Tonga" + }, + new + { + Id = new Guid("f39cca22-449e-9866-3a65-465a5510483e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TR", + Name = "Turkish", + NativeName = "Türkçe" + }, + new + { + Id = new Guid("6200b376-9eae-d01b-de52-8674aaf5b013"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TS", + Name = "Tsonga", + NativeName = "Xitsonga" + }, + new + { + Id = new Guid("95467997-f989-f456-34b7-0b578302dcba"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TT", + Name = "Tatar", + NativeName = "татар теле" + }, + new + { + Id = new Guid("875060ca-73f6-af3b-d844-1b1416ce4583"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TW", + Name = "Twi", + NativeName = "Twi" + }, + new + { + Id = new Guid("2299a74f-3ebc-f022-da1a-44ae59335b3b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TY", + Name = "Tahitian", + NativeName = "Reo Tahiti" + }, + new + { + Id = new Guid("3e2cccbe-1615-c707-a97b-421a799b2559"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "UG", + Name = "Uyghur", + NativeName = "ئۇيغۇرچە‎" + }, + new + { + Id = new Guid("de29d5e7-2ecf-a4ff-5e40-5e83edd0d9b4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "UK", + Name = "Ukrainian", + NativeName = "Українська" + }, + new + { + Id = new Guid("f1f09549-a9bb-da4a-9b98-8655a01235aa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "UR", + Name = "Urdu", + NativeName = "اردو" + }, + new + { + Id = new Guid("357369e3-85a8-86f7-91c7-349772ae7744"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "UZ", + Name = "Uzbek", + NativeName = "Ўзбек" + }, + new + { + Id = new Guid("52d9992c-19bd-82b4-9188-11dabcac6171"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "VE", + Name = "Venda", + NativeName = "Tshivenḓa" + }, + new + { + Id = new Guid("e1947bdc-ff2c-d2c1-3c55-f1f9bf778578"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "VI", + Name = "Vietnamese", + NativeName = "Tiếng Việt" + }, + new + { + Id = new Guid("c2254fd9-159e-4064-0fbf-a7969cba06ec"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "VO", + Name = "Volapük", + NativeName = "Volapük" + }, + new + { + Id = new Guid("629b68d8-1d71-d3ce-f13e-45048ffff017"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "WA", + Name = "Walloon", + NativeName = "walon" + }, + new + { + Id = new Guid("ca6bfadf-4e87-0692-a6b3-20ea6a51555d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "WO", + Name = "Wolof", + NativeName = "Wollof" + }, + new + { + Id = new Guid("0b9b4368-7ceb-e519-153d-2c58c983852b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "XH", + Name = "Xhosa", + NativeName = "isiXhosa" + }, + new + { + Id = new Guid("13016d0c-fbf0-9503-12f2-e0f8d27394ae"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "YI", + Name = "Yiddish", + NativeName = "ייִדיש" + }, + new + { + Id = new Guid("d55a9eb2-48fc-2719-47bf-99e902c28e80"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "YO", + Name = "Yoruba", + NativeName = "Yorùbá" + }, + new + { + Id = new Guid("ebf38b9a-6fbe-6e82-3977-2c4763bea072"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ZA", + Name = "Zhuang", + NativeName = "Saɯ cueŋƅ" + }, + new + { + Id = new Guid("0ce6f5e0-0789-fa0e-b4b5-23a5b1f5e257"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ZH", + Name = "Chinese", + NativeName = "中文" + }, + new + { + Id = new Guid("2c7b808d-7786-2deb-5318-56f7c238520e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ZU", + Name = "Zulu", + NativeName = "isiZulu" + }); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.LocationAggregate.Location", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayOrder") + .HasColumnType("integer"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Level1") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level2") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level3") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level4") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level5") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Tags") + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.ToTable("Locations"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormsVersion") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("NgoId") + .HasColumnType("uuid"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("NgoId"); + + b.ToTable("MonitoringNgos"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringNgoId") + .HasColumnType("uuid"); + + b.Property("ObserverId") + .HasColumnType("uuid"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("Tags") + .IsRequired() + .HasColumnType("text[]"); + + b.HasKey("Id"); + + b.HasIndex("MonitoringNgoId"); + + b.HasIndex("ObserverId"); + + b.HasIndex("ElectionRoundId", "Id") + .IsUnique(); + + b.ToTable("MonitoringObservers"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NgoAdminAggregate.NgoAdmin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ApplicationUserId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("NgoId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId"); + + b.HasIndex("NgoId"); + + b.ToTable("NgoAdmins", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NgoAggregate.Ngo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Ngos"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NoteAggregate.Note", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.Property("QuestionId") + .HasColumnType("uuid"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(10000) + .HasColumnType("character varying(10000)"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.ToTable("Notes", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationAggregate.MonitoringObserverNotification", b => + { + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("NotificationId") + .HasColumnType("uuid"); + + b.Property("IsRead") + .HasColumnType("boolean"); + + b.HasKey("MonitoringObserverId", "NotificationId"); + + b.HasIndex("NotificationId"); + + b.ToTable("MonitoringObserverNotification"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationAggregate.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Body") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("SenderId") + .HasColumnType("uuid"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("SenderId"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationStubAggregate.NotificationStub", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("HasBeenProcessed") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("SerializedData") + .IsRequired() + .HasColumnType("text"); + + b.Property("StubType") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("NotificationStubs"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationTokenAggregate.NotificationToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ObserverId") + .HasColumnType("uuid"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.HasKey("Id"); + + b.HasIndex("ObserverId"); + + b.ToTable("NotificationTokens"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ApplicationUserId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId"); + + b.ToTable("Observers", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverGuideAggregate.ObserverGuide", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("FileName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FilePath") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("GuideType") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MimeType") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MonitoringNgoId") + .HasColumnType("uuid"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UploadedFileName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("WebsiteUrl") + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.HasKey("Id"); + + b.HasIndex("MonitoringNgoId"); + + b.ToTable("ObserversGuides"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Address") + .IsRequired() + .HasMaxLength(2024) + .HasColumnType("character varying(2024)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayOrder") + .HasColumnType("integer"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Level1") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level2") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level3") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level4") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level5") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Number") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Tags") + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.ToTable("PollingStations"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationInfoAggregate.PollingStationInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Answers") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("ArrivalTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DepartureTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FollowUpStatus") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("NotApplicable"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MinutesMonitoring") + .HasColumnType("double precision"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("NumberOfFlaggedAnswers") + .HasColumnType("integer"); + + b.Property("NumberOfQuestionsAnswered") + .HasColumnType("integer"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.Property("PollingStationInformationFormId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.HasIndex("PollingStationInformationFormId"); + + b.HasIndex("ElectionRoundId", "PollingStationId", "MonitoringObserverId", "PollingStationInformationFormId") + .IsUnique(); + + b.ToTable("PollingStationInformation", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate.PollingStationInformationForm", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DefaultLanguage") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Languages") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("LanguagesTranslationStatus") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("NumberOfQuestions") + .HasColumnType("integer"); + + b.Property("Questions") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId") + .IsUnique(); + + b.ToTable("PollingStationInformationForms"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.QuickReportAggregate.QuickReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(10000) + .HasColumnType("character varying(10000)"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FollowUpStatus") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("NotApplicable"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("PollingStationDetails") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.Property("QuickReportLocationType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("Id"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.ToTable("QuickReports"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.QuickReportAttachmentAggregate.QuickReportAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasColumnType("text"); + + b.Property("FilePath") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsCompleted") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MimeType") + .IsRequired() + .HasColumnType("text"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("QuickReportId") + .HasColumnType("uuid"); + + b.Property("UploadedFileName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("MonitoringObserverId"); + + b.ToTable("QuickReportAttachments"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", b => + { + b.OwnsOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.UserPreferences", "Preferences", b1 => + { + b1.Property("ApplicationUserId") + .HasColumnType("uuid"); + + b1.Property("LanguageCode") + .IsRequired() + .HasColumnType("text"); + + b1.HasKey("ApplicationUserId"); + + b1.ToTable("AspNetUsers"); + + b1.ToJson("Preferences"); + + b1.WithOwner() + .HasForeignKey("ApplicationUserId"); + }); + + b.Navigation("Preferences") + .IsRequired(); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.AttachmentAggregate.Attachment", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.LocationAggregate.Location", "Location") + .WithMany() + .HasForeignKey("LocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + + b.Navigation("Location"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAttachmentAggregate.CitizenReportAttachment", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", "CitizenReport") + .WithMany("Attachments") + .HasForeignKey("CitizenReportId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CitizenReport"); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportNoteAggregate.CitizenReportNote", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", "CitizenReport") + .WithMany("Notes") + .HasForeignKey("CitizenReportId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CitizenReport"); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.CountryAggregate.Country", "Country") + .WithMany() + .HasForeignKey("CountryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", "MonitoringNgoForCitizenReporting") + .WithMany() + .HasForeignKey("MonitoringNgoForCitizenReportingId"); + + b.Navigation("Country"); + + b.Navigation("MonitoringNgoForCitizenReporting"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ExportedDataAggregate.ExportedData", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FeedbackAggregate.Feedback", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", "Observer") + .WithMany() + .HasForeignKey("ObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Observer"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormAggregate.Form", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", "MonitoringNgo") + .WithMany() + .HasForeignKey("MonitoringNgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringNgo"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormSubmissionAggregate.FormSubmission", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.LocationAggregate.Location", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany("MonitoringNgos") + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.NgoAggregate.Ngo", "Ngo") + .WithMany() + .HasForeignKey("NgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Ngo"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", "MonitoringNgo") + .WithMany("MonitoringObservers") + .HasForeignKey("MonitoringNgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", "Observer") + .WithMany("MonitoringObservers") + .HasForeignKey("ObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringNgo"); + + b.Navigation("Observer"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NgoAdminAggregate.NgoAdmin", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", "ApplicationUser") + .WithMany() + .HasForeignKey("ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.NgoAggregate.Ngo", "Ngo") + .WithMany("Admins") + .HasForeignKey("NgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApplicationUser"); + + b.Navigation("Ngo"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NoteAggregate.Note", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationAggregate.MonitoringObserverNotification", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.NotificationAggregate.Notification", "Notification") + .WithMany() + .HasForeignKey("NotificationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MonitoringObserver"); + + b.Navigation("Notification"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationAggregate.Notification", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.NgoAdminAggregate.NgoAdmin", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationTokenAggregate.NotificationToken", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", null) + .WithMany() + .HasForeignKey("ObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", "ApplicationUser") + .WithMany() + .HasForeignKey("ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApplicationUser"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverGuideAggregate.ObserverGuide", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", "MonitoringNgo") + .WithMany() + .HasForeignKey("MonitoringNgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MonitoringNgo"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationInfoAggregate.PollingStationInformation", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate.PollingStationInformationForm", "PollingStationInformationForm") + .WithMany() + .HasForeignKey("PollingStationInformationFormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + + b.Navigation("PollingStationInformationForm"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate.PollingStationInformationForm", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithOne() + .HasForeignKey("Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate.PollingStationInformationForm", "ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.QuickReportAggregate.QuickReport", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId"); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.QuickReportAttachmentAggregate.QuickReportAttachment", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringObserver"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", b => + { + b.Navigation("Attachments"); + + b.Navigation("Notes"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", b => + { + b.Navigation("MonitoringNgos"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", b => + { + b.Navigation("MonitoringObservers"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NgoAggregate.Ngo", b => + { + b.Navigation("Admins"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", b => + { + b.Navigation("MonitoringObservers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/api/src/Vote.Monitor.Domain/Migrations/20240913125040_CitizenReportsLocationModel.cs b/api/src/Vote.Monitor.Domain/Migrations/20240913125040_CitizenReportsLocationModel.cs new file mode 100644 index 000000000..2e94b0f23 --- /dev/null +++ b/api/src/Vote.Monitor.Domain/Migrations/20240913125040_CitizenReportsLocationModel.cs @@ -0,0 +1,89 @@ +using System; +using System.Text.Json; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Vote.Monitor.Domain.Migrations +{ + /// + public partial class CitizenReportsLocationModel : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "LocationId", + table: "CitizenReports", + type: "uuid", + nullable: false, + defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); + + migrationBuilder.CreateTable( + name: "Locations", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + ElectionRoundId = table.Column(type: "uuid", nullable: false), + Level1 = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), + Level2 = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + Level3 = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + Level4 = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + Level5 = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + DisplayOrder = table.Column(type: "integer", nullable: false), + Tags = table.Column(type: "jsonb", nullable: true), + CreatedOn = table.Column(type: "timestamp with time zone", nullable: false), + CreatedBy = table.Column(type: "uuid", nullable: false), + LastModifiedOn = table.Column(type: "timestamp with time zone", nullable: true), + LastModifiedBy = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Locations", x => x.Id); + table.ForeignKey( + name: "FK_Locations_ElectionRounds_ElectionRoundId", + column: x => x.ElectionRoundId, + principalTable: "ElectionRounds", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_CitizenReports_LocationId", + table: "CitizenReports", + column: "LocationId"); + + migrationBuilder.CreateIndex( + name: "IX_Locations_ElectionRoundId", + table: "Locations", + column: "ElectionRoundId"); + + migrationBuilder.AddForeignKey( + name: "FK_CitizenReports_Locations_LocationId", + table: "CitizenReports", + column: "LocationId", + principalTable: "Locations", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_CitizenReports_Locations_LocationId", + table: "CitizenReports"); + + migrationBuilder.DropTable( + name: "Locations"); + + migrationBuilder.DropIndex( + name: "IX_CitizenReports_LocationId", + table: "CitizenReports"); + + migrationBuilder.DropColumn( + name: "LocationId", + table: "CitizenReports"); + } + } +} diff --git a/api/src/Vote.Monitor.Domain/Migrations/20240917090918_AddLocationVersionColumn.Designer.cs b/api/src/Vote.Monitor.Domain/Migrations/20240917090918_AddLocationVersionColumn.Designer.cs new file mode 100644 index 000000000..a0156b596 --- /dev/null +++ b/api/src/Vote.Monitor.Domain/Migrations/20240917090918_AddLocationVersionColumn.Designer.cs @@ -0,0 +1,6350 @@ +// +using System; +using System.Collections.Generic; +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Vote.Monitor.Domain; + +#nullable disable + +namespace Vote.Monitor.Domain.Migrations +{ + [DbContext(typeof(VoteMonitorContext))] + [Migration("20240917090918_AddLocationVersionColumn")] + partial class AddLocationVersionColumn + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "hstore"); + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "uuid-ossp"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + + b.HasData( + new + { + Id = new Guid("265e94b0-50fe-4546-b21c-83cb7e94aeff"), + Name = "PlatformAdmin", + NormalizedName = "PLATFORMADMIN" + }, + new + { + Id = new Guid("3239f803-dda8-408b-93ad-0ed973a04e45"), + Name = "NgoAdmin", + NormalizedName = "NGOADMIN" + }, + new + { + Id = new Guid("d1cbef39-62e0-4120-a42b-b01b029dc6ad"), + Name = "Observer", + NormalizedName = "OBSERVER" + }); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("InvitationToken") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("RefreshToken") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("RefreshTokenExpiryTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Role") + .IsRequired() + .HasColumnType("text"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.AttachmentAggregate.Attachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("IsCompleted") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.Property("QuestionId") + .HasColumnType("uuid"); + + b.Property("UploadedFileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.ToTable("Attachments", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.Auditing.Trail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AffectedColumns") + .HasColumnType("text"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("NewValues") + .HasColumnType("text"); + + b.Property("OldValues") + .HasColumnType("text"); + + b.Property("PrimaryKey") + .HasColumnType("text"); + + b.Property("TableName") + .HasColumnType("text"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("Type") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("AuditTrails"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Answers") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FollowUpStatus") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("NotApplicable"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("LocationId") + .HasColumnType("uuid"); + + b.Property("NumberOfFlaggedAnswers") + .HasColumnType("integer"); + + b.Property("NumberOfQuestionsAnswered") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.HasIndex("LocationId"); + + b.ToTable("CitizenReports"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAttachmentAggregate.CitizenReportAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CitizenReportId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("IsCompleted") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("QuestionId") + .HasColumnType("uuid"); + + b.Property("UploadedFileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("CitizenReportId"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.ToTable("CitizenReportAttachments"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportNoteAggregate.CitizenReportNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CitizenReportId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("QuestionId") + .HasColumnType("uuid"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(10000) + .HasColumnType("character varying(10000)"); + + b.HasKey("Id"); + + b.HasIndex("CitizenReportId"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.ToTable("CitizenReportNotes"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CountryAggregate.Country", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Iso2") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("character varying(2)"); + + b.Property("Iso3") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("character varying(3)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NumericCode") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("character varying(3)"); + + b.HasKey("Id"); + + b.HasIndex("Iso2") + .IsUnique(); + + b.HasIndex("Iso3") + .IsUnique(); + + b.HasIndex("NumericCode") + .IsUnique(); + + b.ToTable("Countries"); + + b.HasData( + new + { + Id = new Guid("edd4319b-86f3-24cb-248c-71da624c02f7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Islamic Republic of Afghanistan", + Iso2 = "AF", + Iso3 = "AFG", + Name = "Afghanistan", + NumericCode = "004" + }, + new + { + Id = new Guid("a96fe9bb-4ef4-fca0-f38b-0ec729822f37"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Åland Islands", + Iso2 = "AX", + Iso3 = "ALA", + Name = "Åland Islands", + NumericCode = "248" + }, + new + { + Id = new Guid("5aa0aeb7-4dc8-6a29-fc2f-35daec1541dd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Albania", + Iso2 = "AL", + Iso3 = "ALB", + Name = "Albania", + NumericCode = "008" + }, + new + { + Id = new Guid("fee6f04f-c4c1-e3e4-645d-bb6bb703aeb7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "People's Democratic Republic of Algeria", + Iso2 = "DZ", + Iso3 = "DZA", + Name = "Algeria", + NumericCode = "012" + }, + new + { + Id = new Guid("538114de-7db0-9242-35e6-324fa7eff44d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "American Samoa", + Iso2 = "AS", + Iso3 = "ASM", + Name = "American Samoa", + NumericCode = "016" + }, + new + { + Id = new Guid("bd4bbfc7-d8bc-9d8d-7f7c-7b299c94e9e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Principality of Andorra", + Iso2 = "AD", + Iso3 = "AND", + Name = "Andorra", + NumericCode = "020" + }, + new + { + Id = new Guid("478786f7-1842-8c1e-921c-12e7ed5329c5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Angola", + Iso2 = "AO", + Iso3 = "AGO", + Name = "Angola", + NumericCode = "024" + }, + new + { + Id = new Guid("2b68fb11-a0e0-3d23-5fb8-99721ecfc182"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Anguilla", + Iso2 = "AI", + Iso3 = "AIA", + Name = "Anguilla", + NumericCode = "660" + }, + new + { + Id = new Guid("a0098040-b7a0-59a1-e64b-0a9778b7f74c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Antarctica (the territory South of 60 deg S)", + Iso2 = "AQ", + Iso3 = "ATA", + Name = "Antarctica", + NumericCode = "010" + }, + new + { + Id = new Guid("f3eef99a-661e-2c68-7a4c-3053e2f28007"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Antigua and Barbuda", + Iso2 = "AG", + Iso3 = "ATG", + Name = "Antigua and Barbuda", + NumericCode = "028" + }, + new + { + Id = new Guid("a7afb7b1-b26d-4571-1a1f-3fff738ff21e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Argentine Republic", + Iso2 = "AR", + Iso3 = "ARG", + Name = "Argentina", + NumericCode = "032" + }, + new + { + Id = new Guid("688af4c8-9d64-ae1c-147f-b8afd54801e3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Armenia", + Iso2 = "AM", + Iso3 = "ARM", + Name = "Armenia", + NumericCode = "051" + }, + new + { + Id = new Guid("e6c7651f-182e-cf9c-1ef9-6293b95b500c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Aruba", + Iso2 = "AW", + Iso3 = "ABW", + Name = "Aruba", + NumericCode = "533" + }, + new + { + Id = new Guid("15639386-e4fc-120c-6916-c0c980e24be1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of Australia", + Iso2 = "AU", + Iso3 = "AUS", + Name = "Australia", + NumericCode = "036" + }, + new + { + Id = new Guid("704254eb-6959-8ddc-a5df-ac8f9658dc68"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Austria", + Iso2 = "AT", + Iso3 = "AUT", + Name = "Austria", + NumericCode = "040" + }, + new + { + Id = new Guid("008c3138-73d8-dbbc-f1dd-521e4c68bcf1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Azerbaijan", + Iso2 = "AZ", + Iso3 = "AZE", + Name = "Azerbaijan", + NumericCode = "031" + }, + new + { + Id = new Guid("46e88019-c521-57b2-d1c0-c0e2478d3b05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of the Bahamas", + Iso2 = "BS", + Iso3 = "BHS", + Name = "Bahamas", + NumericCode = "044" + }, + new + { + Id = new Guid("44caa0f4-1e78-d2fb-96be-d01b3224bdc1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Bahrain", + Iso2 = "BH", + Iso3 = "BHR", + Name = "Bahrain", + NumericCode = "048" + }, + new + { + Id = new Guid("809c3424-8654-b82c-cbd4-d857d096943e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "People's Republic of Bangladesh", + Iso2 = "BD", + Iso3 = "BGD", + Name = "Bangladesh", + NumericCode = "050" + }, + new + { + Id = new Guid("316c68fc-9144-f6e1-8bf1-899fc54b2327"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Barbados", + Iso2 = "BB", + Iso3 = "BRB", + Name = "Barbados", + NumericCode = "052" + }, + new + { + Id = new Guid("d97b5460-11ab-45c5-9a6f-ffa441ed70d6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Belarus", + Iso2 = "BY", + Iso3 = "BLR", + Name = "Belarus", + NumericCode = "112" + }, + new + { + Id = new Guid("0797a7d5-bbc0-2e52-0de8-14a42fc80baa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Belgium", + Iso2 = "BE", + Iso3 = "BEL", + Name = "Belgium", + NumericCode = "056" + }, + new + { + Id = new Guid("c89e02a0-9506-90df-5545-b98a2453cd63"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Belize", + Iso2 = "BZ", + Iso3 = "BLZ", + Name = "Belize", + NumericCode = "084" + }, + new + { + Id = new Guid("96a22cee-9af7-8f03-b483-b3e774a36d3b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Benin", + Iso2 = "BJ", + Iso3 = "BEN", + Name = "Benin", + NumericCode = "204" + }, + new + { + Id = new Guid("ca2a5560-d4c4-3c87-3090-6f5436310b55"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bermuda", + Iso2 = "BM", + Iso3 = "BMU", + Name = "Bermuda", + NumericCode = "060" + }, + new + { + Id = new Guid("8ed6a34e-8135-27fa-f86a-caa247b29768"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Bhutan", + Iso2 = "BT", + Iso3 = "BTN", + Name = "Bhutan", + NumericCode = "064" + }, + new + { + Id = new Guid("f33ced84-eb43-fb39-ef79-b266e4d4cd94"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Plurinational State of Bolivia", + Iso2 = "BO", + Iso3 = "BOL", + Name = "Bolivia", + NumericCode = "068" + }, + new + { + Id = new Guid("d8101f9d-8313-4054-c5f3-42c7a1c72862"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bonaire, Sint Eustatius and Saba", + Iso2 = "BQ", + Iso3 = "BES", + Name = "Bonaire, Sint Eustatius and Saba", + NumericCode = "535" + }, + new + { + Id = new Guid("a7716d29-6ef6-b775-51c5-97094536329d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bosnia and Herzegovina", + Iso2 = "BA", + Iso3 = "BIH", + Name = "Bosnia and Herzegovina", + NumericCode = "070" + }, + new + { + Id = new Guid("14f190c6-97c9-3e12-2eba-db17c59d6a04"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Botswana", + Iso2 = "BW", + Iso3 = "BWA", + Name = "Botswana", + NumericCode = "072" + }, + new + { + Id = new Guid("32da0208-9048-1339-a8ee-6955cfff4c12"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bouvet Island (Bouvetøya)", + Iso2 = "BV", + Iso3 = "BVT", + Name = "Bouvet Island (Bouvetøya)", + NumericCode = "074" + }, + new + { + Id = new Guid("5283afbb-2744-e930-2c16-c5ea6b0ff7cc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federative Republic of Brazil", + Iso2 = "BR", + Iso3 = "BRA", + Name = "Brazil", + NumericCode = "076" + }, + new + { + Id = new Guid("b8b09512-ea4c-4a61-9331-304f55324ef7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "British Indian Ocean Territory (Chagos Archipelago)", + Iso2 = "IO", + Iso3 = "IOT", + Name = "British Indian Ocean Territory (Chagos Archipelago)", + NumericCode = "086" + }, + new + { + Id = new Guid("39be5e86-aea5-f64f-fd7e-1017fe24e543"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "British Virgin Islands", + Iso2 = "VG", + Iso3 = "VGB", + Name = "British Virgin Islands", + NumericCode = "092" + }, + new + { + Id = new Guid("ed6278e0-436c-9fd9-0b9e-44fd424cbd1b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Brunei Darussalam", + Iso2 = "BN", + Iso3 = "BRN", + Name = "Brunei Darussalam", + NumericCode = "096" + }, + new + { + Id = new Guid("46576b73-c05b-7498-5b07-9bbf59b7645d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Bulgaria", + Iso2 = "BG", + Iso3 = "BGR", + Name = "Bulgaria", + NumericCode = "100" + }, + new + { + Id = new Guid("42697d56-52cf-b411-321e-c51929f02f90"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Burkina Faso", + Iso2 = "BF", + Iso3 = "BFA", + Name = "Burkina Faso", + NumericCode = "854" + }, + new + { + Id = new Guid("75e4464b-a784-63b8-1ecc-69ee1f09f43f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Burundi", + Iso2 = "BI", + Iso3 = "BDI", + Name = "Burundi", + NumericCode = "108" + }, + new + { + Id = new Guid("c9702851-1f67-f2a6-89d4-37b3fbb12044"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Cambodia", + Iso2 = "KH", + Iso3 = "KHM", + Name = "Cambodia", + NumericCode = "116" + }, + new + { + Id = new Guid("c0b7e39e-223a-ebb0-b899-5404573bbdb7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cameroon", + Iso2 = "CM", + Iso3 = "CMR", + Name = "Cameroon", + NumericCode = "120" + }, + new + { + Id = new Guid("5c0e654b-8547-5d02-ee7b-d65e3c5c5273"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Canada", + Iso2 = "CA", + Iso3 = "CAN", + Name = "Canada", + NumericCode = "124" + }, + new + { + Id = new Guid("17ed5f0f-e091-94ff-0512-ad291bde94d7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cabo Verde", + Iso2 = "CV", + Iso3 = "CPV", + Name = "Cabo Verde", + NumericCode = "132" + }, + new + { + Id = new Guid("3c5828e0-16a8-79ba-4e5c-9b45065df113"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Cayman Islands", + Iso2 = "KY", + Iso3 = "CYM", + Name = "Cayman Islands", + NumericCode = "136" + }, + new + { + Id = new Guid("b4e0625c-7597-c185-b8ae-cfb35a731f2f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Central African Republic", + Iso2 = "CF", + Iso3 = "CAF", + Name = "Central African Republic", + NumericCode = "140" + }, + new + { + Id = new Guid("2a1ca5b6-fba0-cfa8-9928-d7a2382bc4d7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Chad", + Iso2 = "TD", + Iso3 = "TCD", + Name = "Chad", + NumericCode = "148" + }, + new + { + Id = new Guid("ad4f938a-bf7b-684b-2c9e-e824d3fa3863"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Chile", + Iso2 = "CL", + Iso3 = "CHL", + Name = "Chile", + NumericCode = "152" + }, + new + { + Id = new Guid("8250c49f-9438-7c2e-f403-54d962db0c18"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "People's Republic of China", + Iso2 = "CN", + Iso3 = "CHN", + Name = "China", + NumericCode = "156" + }, + new + { + Id = new Guid("0f1ba59e-ade5-23e5-6fce-e2fd3282e114"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Christmas Island", + Iso2 = "CX", + Iso3 = "CXR", + Name = "Christmas Island", + NumericCode = "162" + }, + new + { + Id = new Guid("a16263a5-810c-bf6a-206d-72cb914e2d5c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Cocos (Keeling) Islands", + Iso2 = "CC", + Iso3 = "CCK", + Name = "Cocos (Keeling) Islands", + NumericCode = "166" + }, + new + { + Id = new Guid("c64288fc-d941-0615-47f9-28e6c294ce26"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Colombia", + Iso2 = "CO", + Iso3 = "COL", + Name = "Colombia", + NumericCode = "170" + }, + new + { + Id = new Guid("5e7a08f2-7d59-bcdb-7ddd-876b87181420"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Union of the Comoros", + Iso2 = "KM", + Iso3 = "COM", + Name = "Comoros", + NumericCode = "174" + }, + new + { + Id = new Guid("1258ec90-c47e-ff72-b7e3-f90c3ee320f8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic Republic of the Congo", + Iso2 = "CD", + Iso3 = "COD", + Name = "Congo", + NumericCode = "180" + }, + new + { + Id = new Guid("1934954c-66c2-6226-c5b6-491065a3e4c0"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Congo", + Iso2 = "CG", + Iso3 = "COG", + Name = "Congo", + NumericCode = "178" + }, + new + { + Id = new Guid("af79558d-51fb-b08d-185b-afeb983ab99b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Cook Islands", + Iso2 = "CK", + Iso3 = "COK", + Name = "Cook Islands", + NumericCode = "184" + }, + new + { + Id = new Guid("d13935c1-8956-1399-7c4e-0354795cd37b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Costa Rica", + Iso2 = "CR", + Iso3 = "CRI", + Name = "Costa Rica", + NumericCode = "188" + }, + new + { + Id = new Guid("5be18efe-6db8-a727-7f2a-62bd71bc6593"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cote d'Ivoire", + Iso2 = "CI", + Iso3 = "CIV", + Name = "Cote d'Ivoire", + NumericCode = "384" + }, + new + { + Id = new Guid("1f8be615-5746-277e-d82b-47596b5bb922"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Croatia", + Iso2 = "HR", + Iso3 = "HRV", + Name = "Croatia", + NumericCode = "191" + }, + new + { + Id = new Guid("57765d87-2424-2c86-ad9c-1af58ef3127a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cuba", + Iso2 = "CU", + Iso3 = "CUB", + Name = "Cuba", + NumericCode = "192" + }, + new + { + Id = new Guid("3345e205-3e72-43ed-de1b-ac6e050543e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Curaçao", + Iso2 = "CW", + Iso3 = "CUW", + Name = "Curaçao", + NumericCode = "531" + }, + new + { + Id = new Guid("df20d0d7-9fbe-e725-d966-4fdf9f5c9dfb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Cyprus", + Iso2 = "CY", + Iso3 = "CYP", + Name = "Cyprus", + NumericCode = "196" + }, + new + { + Id = new Guid("9d4ec95b-974a-f5bb-bb4b-ba6747440631"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Czech Republic", + Iso2 = "CZ", + Iso3 = "CZE", + Name = "Czechia", + NumericCode = "203" + }, + new + { + Id = new Guid("8a4fcb23-f3e6-fb5b-8cda-975872f600d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Denmark", + Iso2 = "DK", + Iso3 = "DNK", + Name = "Denmark", + NumericCode = "208" + }, + new + { + Id = new Guid("37a79267-d38a-aaef-577a-aa68a96880ae"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Djibouti", + Iso2 = "DJ", + Iso3 = "DJI", + Name = "Djibouti", + NumericCode = "262" + }, + new + { + Id = new Guid("19ea3a6a-1a76-23c8-8e4e-1d298f15207f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of Dominica", + Iso2 = "DM", + Iso3 = "DMA", + Name = "Dominica", + NumericCode = "212" + }, + new + { + Id = new Guid("b2c4d2d7-7ada-7864-426f-10a28d9f9eba"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Dominican Republic", + Iso2 = "DO", + Iso3 = "DOM", + Name = "Dominican Republic", + NumericCode = "214" + }, + new + { + Id = new Guid("49c82f1b-968d-b5e7-8559-e39567d46787"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Ecuador", + Iso2 = "EC", + Iso3 = "ECU", + Name = "Ecuador", + NumericCode = "218" + }, + new + { + Id = new Guid("ee5dfc29-80f1-86ae-cde7-02484a18907a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Arab Republic of Egypt", + Iso2 = "EG", + Iso3 = "EGY", + Name = "Egypt", + NumericCode = "818" + }, + new + { + Id = new Guid("4d8bcda4-5598-16cd-b379-97eb7a5e1c29"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of El Salvador", + Iso2 = "SV", + Iso3 = "SLV", + Name = "El Salvador", + NumericCode = "222" + }, + new + { + Id = new Guid("824392e8-a6cc-0cd4-af13-3067dad3258e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Equatorial Guinea", + Iso2 = "GQ", + Iso3 = "GNQ", + Name = "Equatorial Guinea", + NumericCode = "226" + }, + new + { + Id = new Guid("8b5a477a-070a-a84f-bd3b-f54dc2a172de"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Eritrea", + Iso2 = "ER", + Iso3 = "ERI", + Name = "Eritrea", + NumericCode = "232" + }, + new + { + Id = new Guid("2dc643bd-cc6c-eb0c-7314-44123576f0ee"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Estonia", + Iso2 = "EE", + Iso3 = "EST", + Name = "Estonia", + NumericCode = "233" + }, + new + { + Id = new Guid("e75515a6-63cf-3612-a3a2-befa0d7048a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federal Democratic Republic of Ethiopia", + Iso2 = "ET", + Iso3 = "ETH", + Name = "Ethiopia", + NumericCode = "231" + }, + new + { + Id = new Guid("0d4fe6e6-ea1e-d1ce-5134-6c0c1a696a00"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Faroe Islands", + Iso2 = "FO", + Iso3 = "FRO", + Name = "Faroe Islands", + NumericCode = "234" + }, + new + { + Id = new Guid("b86375dc-edbb-922c-9ed4-2f724094a5a2"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Falkland Islands (Malvinas)", + Iso2 = "FK", + Iso3 = "FLK", + Name = "Falkland Islands (Malvinas)", + NumericCode = "238" + }, + new + { + Id = new Guid("0e2a1681-d852-67ae-7387-0d04be9e7fd3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Fiji", + Iso2 = "FJ", + Iso3 = "FJI", + Name = "Fiji", + NumericCode = "242" + }, + new + { + Id = new Guid("5a5d9168-081b-1e02-1fbb-cdfa910e526c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Finland", + Iso2 = "FI", + Iso3 = "FIN", + Name = "Finland", + NumericCode = "246" + }, + new + { + Id = new Guid("b2261c50-1a57-7f1f-d72d-f8c21593874f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "French Republic", + Iso2 = "FR", + Iso3 = "FRA", + Name = "France", + NumericCode = "250" + }, + new + { + Id = new Guid("ac6cde6e-f645-d04e-8afc-0391ecf38a70"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "French Guiana", + Iso2 = "GF", + Iso3 = "GUF", + Name = "French Guiana", + NumericCode = "254" + }, + new + { + Id = new Guid("11dbce82-a154-7aee-7b5e-d5981f220572"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "French Polynesia", + Iso2 = "PF", + Iso3 = "PYF", + Name = "French Polynesia", + NumericCode = "258" + }, + new + { + Id = new Guid("903bee63-bcf0-0264-6eaf-a8cde95c5f41"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "French Southern Territories", + Iso2 = "TF", + Iso3 = "ATF", + Name = "French Southern Territories", + NumericCode = "260" + }, + new + { + Id = new Guid("4826bc0f-235e-572f-2b1a-21f1c9e05f83"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Gabonese Republic", + Iso2 = "GA", + Iso3 = "GAB", + Name = "Gabon", + NumericCode = "266" + }, + new + { + Id = new Guid("a40b91b3-cc13-2470-65f0-a0fdc946f2a2"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Gambia", + Iso2 = "GM", + Iso3 = "GMB", + Name = "Gambia", + NumericCode = "270" + }, + new + { + Id = new Guid("980176e8-7d9d-9729-b3e9-ebc455fb8fc4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Georgia", + Iso2 = "GE", + Iso3 = "GEO", + Name = "Georgia", + NumericCode = "268" + }, + new + { + Id = new Guid("46ef1468-86f6-0c99-f4e9-46f966167b05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federal Republic of Germany", + Iso2 = "DE", + Iso3 = "DEU", + Name = "Germany", + NumericCode = "276" + }, + new + { + Id = new Guid("6d0c77a7-a4aa-c2bd-2db6-0e2ad2d61f8a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Ghana", + Iso2 = "GH", + Iso3 = "GHA", + Name = "Ghana", + NumericCode = "288" + }, + new + { + Id = new Guid("8e0de349-f9ab-2bca-3910-efd48bf1170a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Gibraltar", + Iso2 = "GI", + Iso3 = "GIB", + Name = "Gibraltar", + NumericCode = "292" + }, + new + { + Id = new Guid("4fc1a9dc-cc74-f6ce-5743-c5cee8d709ef"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Hellenic Republic of Greece", + Iso2 = "GR", + Iso3 = "GRC", + Name = "Greece", + NumericCode = "300" + }, + new + { + Id = new Guid("2f00fe86-a06b-dc95-0ea7-4520d1dec784"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Greenland", + Iso2 = "GL", + Iso3 = "GRL", + Name = "Greenland", + NumericCode = "304" + }, + new + { + Id = new Guid("ff5b4d88-c179-ff0d-6285-cf46ba475d7d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Grenada", + Iso2 = "GD", + Iso3 = "GRD", + Name = "Grenada", + NumericCode = "308" + }, + new + { + Id = new Guid("3bcd2aad-fb69-09f4-1ad7-2c7f5fa23f9f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Guadeloupe", + Iso2 = "GP", + Iso3 = "GLP", + Name = "Guadeloupe", + NumericCode = "312" + }, + new + { + Id = new Guid("096a8586-9702-6fec-5f6a-6eb3b7b7837f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Guam", + Iso2 = "GU", + Iso3 = "GUM", + Name = "Guam", + NumericCode = "316" + }, + new + { + Id = new Guid("d24b46ba-8e9d-2a09-7995-e35e8ae54f6b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Guatemala", + Iso2 = "GT", + Iso3 = "GTM", + Name = "Guatemala", + NumericCode = "320" + }, + new + { + Id = new Guid("5b0ee3be-596d-bdc1-f101-00ef33170655"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bailiwick of Guernsey", + Iso2 = "GG", + Iso3 = "GGY", + Name = "Guernsey", + NumericCode = "831" + }, + new + { + Id = new Guid("3ffe68ca-7350-175b-4e95-0c34f54dc1f4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Guinea", + Iso2 = "GN", + Iso3 = "GIN", + Name = "Guinea", + NumericCode = "324" + }, + new + { + Id = new Guid("a9a5f440-a9bd-487d-e7f4-914df0d52fa6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Guinea-Bissau", + Iso2 = "GW", + Iso3 = "GNB", + Name = "Guinea-Bissau", + NumericCode = "624" + }, + new + { + Id = new Guid("a9949ac7-8d2d-32b5-3f4f-e2a3ef291a67"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Co-operative Republic of Guyana", + Iso2 = "GY", + Iso3 = "GUY", + Name = "Guyana", + NumericCode = "328" + }, + new + { + Id = new Guid("2bebebe4-edaa-9160-5a0c-4d99048bd8d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Haiti", + Iso2 = "HT", + Iso3 = "HTI", + Name = "Haiti", + NumericCode = "332" + }, + new + { + Id = new Guid("592b4658-a210-ab0a-5660-3dcc673dc581"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Heard Island and McDonald Islands", + Iso2 = "HM", + Iso3 = "HMD", + Name = "Heard Island and McDonald Islands", + NumericCode = "334" + }, + new + { + Id = new Guid("d0e11a85-6623-69f5-bd95-3779dfeec297"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Holy See (Vatican City State)", + Iso2 = "VA", + Iso3 = "VAT", + Name = "Holy See (Vatican City State)", + NumericCode = "336" + }, + new + { + Id = new Guid("0aebadaa-91b2-8794-c153-4f903a2a1004"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Honduras", + Iso2 = "HN", + Iso3 = "HND", + Name = "Honduras", + NumericCode = "340" + }, + new + { + Id = new Guid("500bb0de-61f5-dc9b-0488-1c507456ea4d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Hong Kong Special Administrative Region of China", + Iso2 = "HK", + Iso3 = "HKG", + Name = "Hong Kong", + NumericCode = "344" + }, + new + { + Id = new Guid("dcf19e1d-74a6-7b8b-a5ed-76b94a8ac2a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Hungary", + Iso2 = "HU", + Iso3 = "HUN", + Name = "Hungary", + NumericCode = "348" + }, + new + { + Id = new Guid("4ee6400d-5534-7c67-1521-870d6b732366"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Iceland", + Iso2 = "IS", + Iso3 = "ISL", + Name = "Iceland", + NumericCode = "352" + }, + new + { + Id = new Guid("72d8d1fe-d5f6-f440-1185-82ec69427027"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of India", + Iso2 = "IN", + Iso3 = "IND", + Name = "India", + NumericCode = "356" + }, + new + { + Id = new Guid("1d974338-decf-08e5-3e62-89e1bbdbb003"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Indonesia", + Iso2 = "ID", + Iso3 = "IDN", + Name = "Indonesia", + NumericCode = "360" + }, + new + { + Id = new Guid("b3460bab-2a35-57bc-17e2-4e117748bbb1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Islamic Republic of Iran", + Iso2 = "IR", + Iso3 = "IRN", + Name = "Iran", + NumericCode = "364" + }, + new + { + Id = new Guid("6c8be2e6-8c2e-cd80-68a6-d18c80d0eedc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Iraq", + Iso2 = "IQ", + Iso3 = "IRQ", + Name = "Iraq", + NumericCode = "368" + }, + new + { + Id = new Guid("294978f0-2702-d35d-cfc4-e676148aea2e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Ireland", + Iso2 = "IE", + Iso3 = "IRL", + Name = "Ireland", + NumericCode = "372" + }, + new + { + Id = new Guid("a1b83be0-6a9b-c8a9-2cce-531705a29664"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Isle of Man", + Iso2 = "IM", + Iso3 = "IMN", + Name = "Isle of Man", + NumericCode = "833" + }, + new + { + Id = new Guid("7ffa909b-8a6a-3028-9589-fcc3dfa530a8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Israel", + Iso2 = "IL", + Iso3 = "ISR", + Name = "Israel", + NumericCode = "376" + }, + new + { + Id = new Guid("7bbf15f4-a907-c0b2-7029-144aafb3c59d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Italy", + Iso2 = "IT", + Iso3 = "ITA", + Name = "Italy", + NumericCode = "380" + }, + new + { + Id = new Guid("6699efd5-0939-7812-315e-21f37b279ee9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Jamaica", + Iso2 = "JM", + Iso3 = "JAM", + Name = "Jamaica", + NumericCode = "388" + }, + new + { + Id = new Guid("13c69e56-375d-8a7e-c326-be2be2fd4cd8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Japan", + Iso2 = "JP", + Iso3 = "JPN", + Name = "Japan", + NumericCode = "392" + }, + new + { + Id = new Guid("65d871be-4a1d-a632-9cdb-62e3ff04928d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bailiwick of Jersey", + Iso2 = "JE", + Iso3 = "JEY", + Name = "Jersey", + NumericCode = "832" + }, + new + { + Id = new Guid("9ae7ad80-9ce7-6657-75cf-28b4c0254238"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Hashemite Kingdom of Jordan", + Iso2 = "JO", + Iso3 = "JOR", + Name = "Jordan", + NumericCode = "400" + }, + new + { + Id = new Guid("b723594d-7800-0f37-db86-0f6b85bb6cf9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Kazakhstan", + Iso2 = "KZ", + Iso3 = "KAZ", + Name = "Kazakhstan", + NumericCode = "398" + }, + new + { + Id = new Guid("b32fe2b5-a06e-0d76-ffd2-f186c3e64b15"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Kenya", + Iso2 = "KE", + Iso3 = "KEN", + Name = "Kenya", + NumericCode = "404" + }, + new + { + Id = new Guid("914618fd-86f9-827a-91b8-826f0db9e02d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Kiribati", + Iso2 = "KI", + Iso3 = "KIR", + Name = "Kiribati", + NumericCode = "296" + }, + new + { + Id = new Guid("f70ae426-f130-5637-0383-a5b63a06c500"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic People's Republic of Korea", + Iso2 = "KP", + Iso3 = "PRK", + Name = "Korea", + NumericCode = "408" + }, + new + { + Id = new Guid("7bf934fa-bcf4-80b5-fd7d-ab4cca45c67b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Korea", + Iso2 = "KR", + Iso3 = "KOR", + Name = "Korea", + NumericCode = "410" + }, + new + { + Id = new Guid("b6f70436-9515-7ef8-af57-aad196503499"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Kuwait", + Iso2 = "KW", + Iso3 = "KWT", + Name = "Kuwait", + NumericCode = "414" + }, + new + { + Id = new Guid("0932ed88-c79f-591a-d684-9a77735f947e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kyrgyz Republic", + Iso2 = "KG", + Iso3 = "KGZ", + Name = "Kyrgyz Republic", + NumericCode = "417" + }, + new + { + Id = new Guid("c4754c00-cfa5-aa6f-a9c8-a200457de7a8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Lao People's Democratic Republic", + Iso2 = "LA", + Iso3 = "LAO", + Name = "Lao People's Democratic Republic", + NumericCode = "418" + }, + new + { + Id = new Guid("9205dbfc-60cd-91d9-b0b8-8a18a3755286"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Latvia", + Iso2 = "LV", + Iso3 = "LVA", + Name = "Latvia", + NumericCode = "428" + }, + new + { + Id = new Guid("1e5c0dcc-83e9-f275-c81d-3bc49f88e70c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Lebanese Republic", + Iso2 = "LB", + Iso3 = "LBN", + Name = "Lebanon", + NumericCode = "422" + }, + new + { + Id = new Guid("bf210ee6-6c75-cf08-052e-5c3e608aed15"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Lesotho", + Iso2 = "LS", + Iso3 = "LSO", + Name = "Lesotho", + NumericCode = "426" + }, + new + { + Id = new Guid("ee926d09-799c-7c6a-2419-a6ff814b2c03"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Liberia", + Iso2 = "LR", + Iso3 = "LBR", + Name = "Liberia", + NumericCode = "430" + }, + new + { + Id = new Guid("695c85b3-a6c6-c217-9be8-3baebc7719ce"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Libya", + Iso2 = "LY", + Iso3 = "LBY", + Name = "Libya", + NumericCode = "434" + }, + new + { + Id = new Guid("9d6e6446-185e-235e-8771-9eb2d19f22e7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Principality of Liechtenstein", + Iso2 = "LI", + Iso3 = "LIE", + Name = "Liechtenstein", + NumericCode = "438" + }, + new + { + Id = new Guid("52538361-bbdf-fafb-e434-5655fc7451e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Lithuania", + Iso2 = "LT", + Iso3 = "LTU", + Name = "Lithuania", + NumericCode = "440" + }, + new + { + Id = new Guid("70673250-4cc3-3ba1-a42c-6b62ea8ab1d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Grand Duchy of Luxembourg", + Iso2 = "LU", + Iso3 = "LUX", + Name = "Luxembourg", + NumericCode = "442" + }, + new + { + Id = new Guid("8d32a12d-3230-1431-8fbb-72c789184345"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Macao Special Administrative Region of China", + Iso2 = "MO", + Iso3 = "MAC", + Name = "Macao", + NumericCode = "446" + }, + new + { + Id = new Guid("976e496f-ca38-d113-1697-8af2d9a3b159"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Madagascar", + Iso2 = "MG", + Iso3 = "MDG", + Name = "Madagascar", + NumericCode = "450" + }, + new + { + Id = new Guid("fbf4479d-d70d-c76e-b053-699362443a17"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Malawi", + Iso2 = "MW", + Iso3 = "MWI", + Name = "Malawi", + NumericCode = "454" + }, + new + { + Id = new Guid("d292ea2d-fbb6-7c1e-cb7d-23d552673776"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Malaysia", + Iso2 = "MY", + Iso3 = "MYS", + Name = "Malaysia", + NumericCode = "458" + }, + new + { + Id = new Guid("1d2aa3ab-e1c3-8c76-9be6-7a3b3eca35da"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Maldives", + Iso2 = "MV", + Iso3 = "MDV", + Name = "Maldives", + NumericCode = "462" + }, + new + { + Id = new Guid("c03d71a5-b215-8672-ec0c-dd8fe5c20e05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Mali", + Iso2 = "ML", + Iso3 = "MLI", + Name = "Mali", + NumericCode = "466" + }, + new + { + Id = new Guid("f0219540-8b2c-bd29-4f76-b832de53a56f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Malta", + Iso2 = "MT", + Iso3 = "MLT", + Name = "Malta", + NumericCode = "470" + }, + new + { + Id = new Guid("943d2419-2ca6-95f8-9c3b-ed445aea0371"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Marshall Islands", + Iso2 = "MH", + Iso3 = "MHL", + Name = "Marshall Islands", + NumericCode = "584" + }, + new + { + Id = new Guid("fc78fa89-b372-dcf7-7f1c-1e1bb14ecbe7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Martinique", + Iso2 = "MQ", + Iso3 = "MTQ", + Name = "Martinique", + NumericCode = "474" + }, + new + { + Id = new Guid("74da982f-cf20-e1b4-517b-a040511af23c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Islamic Republic of Mauritania", + Iso2 = "MR", + Iso3 = "MRT", + Name = "Mauritania", + NumericCode = "478" + }, + new + { + Id = new Guid("1b634ca2-2b90-7e54-715a-74cee7e4d294"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Mauritius", + Iso2 = "MU", + Iso3 = "MUS", + Name = "Mauritius", + NumericCode = "480" + }, + new + { + Id = new Guid("08a999e4-e420-b864-2864-bef78c138448"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Mayotte", + Iso2 = "YT", + Iso3 = "MYT", + Name = "Mayotte", + NumericCode = "175" + }, + new + { + Id = new Guid("a9940e91-93ef-19f7-79c0-00d31c6a9f87"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United Mexican States", + Iso2 = "MX", + Iso3 = "MEX", + Name = "Mexico", + NumericCode = "484" + }, + new + { + Id = new Guid("a2da72dc-5866-ba2f-6283-6575af00ade5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federated States of Micronesia", + Iso2 = "FM", + Iso3 = "FSM", + Name = "Micronesia", + NumericCode = "583" + }, + new + { + Id = new Guid("daf6bc7a-92c4-ef47-3111-e13199b86b90"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Moldova", + Iso2 = "MD", + Iso3 = "MDA", + Name = "Moldova", + NumericCode = "498" + }, + new + { + Id = new Guid("5cab34ca-8c74-0766-c7ca-4a826b44c5bd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Principality of Monaco", + Iso2 = "MC", + Iso3 = "MCO", + Name = "Monaco", + NumericCode = "492" + }, + new + { + Id = new Guid("c522b3d3-74cc-846f-0394-737dff4d2b1a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Mongolia", + Iso2 = "MN", + Iso3 = "MNG", + Name = "Mongolia", + NumericCode = "496" + }, + new + { + Id = new Guid("86db2170-be87-fd1d-bf57-05ff61ae83a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Montenegro", + Iso2 = "ME", + Iso3 = "MNE", + Name = "Montenegro", + NumericCode = "499" + }, + new + { + Id = new Guid("50e5954d-7cb4-2201-b96c-f2a846ab3ae3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Montserrat", + Iso2 = "MS", + Iso3 = "MSR", + Name = "Montserrat", + NumericCode = "500" + }, + new + { + Id = new Guid("915805f0-9ff0-48ff-39b3-44a4af5e0482"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Morocco", + Iso2 = "MA", + Iso3 = "MAR", + Name = "Morocco", + NumericCode = "504" + }, + new + { + Id = new Guid("10b58d9b-42ef-edb8-54a3-712636fda55a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Mozambique", + Iso2 = "MZ", + Iso3 = "MOZ", + Name = "Mozambique", + NumericCode = "508" + }, + new + { + Id = new Guid("015a9f83-6e57-bc1e-8227-24a4e5248582"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Union of Myanmar", + Iso2 = "MM", + Iso3 = "MMR", + Name = "Myanmar", + NumericCode = "104" + }, + new + { + Id = new Guid("0c0fef20-0e8d-98ea-7724-12cea9b3b926"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Namibia", + Iso2 = "NA", + Iso3 = "NAM", + Name = "Namibia", + NumericCode = "516" + }, + new + { + Id = new Guid("e3bacefb-d79b-1569-a91c-43d7e4f6f230"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Nauru", + Iso2 = "NR", + Iso3 = "NRU", + Name = "Nauru", + NumericCode = "520" + }, + new + { + Id = new Guid("e81c5db3-401a-e047-001e-045f39bef8ef"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Nepal", + Iso2 = "NP", + Iso3 = "NPL", + Name = "Nepal", + NumericCode = "524" + }, + new + { + Id = new Guid("cfff3443-1378-9c7d-9d58-66146d7f29a6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of the Netherlands", + Iso2 = "NL", + Iso3 = "NLD", + Name = "Netherlands", + NumericCode = "528" + }, + new + { + Id = new Guid("4b0729b6-f698-5730-767c-88e2d36691bb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "New Caledonia", + Iso2 = "NC", + Iso3 = "NCL", + Name = "New Caledonia", + NumericCode = "540" + }, + new + { + Id = new Guid("360e3c61-aaac-fa2f-d731-fc0824c05107"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "New Zealand", + Iso2 = "NZ", + Iso3 = "NZL", + Name = "New Zealand", + NumericCode = "554" + }, + new + { + Id = new Guid("cd0e8275-3def-1de4-8858-61aab36851c4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Nicaragua", + Iso2 = "NI", + Iso3 = "NIC", + Name = "Nicaragua", + NumericCode = "558" + }, + new + { + Id = new Guid("97cd39d5-1aca-8f10-9f5e-3f611d7606d8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Niger", + Iso2 = "NE", + Iso3 = "NER", + Name = "Niger", + NumericCode = "562" + }, + new + { + Id = new Guid("2e1bd9d8-df06-d773-0eb9-98e274b63b43"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federal Republic of Nigeria", + Iso2 = "NG", + Iso3 = "NGA", + Name = "Nigeria", + NumericCode = "566" + }, + new + { + Id = new Guid("3eea06f4-c085-f619-6d52-b76a5f6fd2b6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Niue", + Iso2 = "NU", + Iso3 = "NIU", + Name = "Niue", + NumericCode = "570" + }, + new + { + Id = new Guid("47804b6a-e705-b925-f4fd-4adf6500180b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Norfolk Island", + Iso2 = "NF", + Iso3 = "NFK", + Name = "Norfolk Island", + NumericCode = "574" + }, + new + { + Id = new Guid("aa0f69b2-93aa-ec51-b43b-60145db79e38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of North Macedonia", + Iso2 = "MK", + Iso3 = "MKD", + Name = "North Macedonia", + NumericCode = "807" + }, + new + { + Id = new Guid("6ac64a20-5688-ccd0-4eca-88d8a2560079"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of the Northern Mariana Islands", + Iso2 = "MP", + Iso3 = "MNP", + Name = "Northern Mariana Islands", + NumericCode = "580" + }, + new + { + Id = new Guid("914d7923-3ac5-75e8-c8e2-47d72561e35d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Norway", + Iso2 = "NO", + Iso3 = "NOR", + Name = "Norway", + NumericCode = "578" + }, + new + { + Id = new Guid("6c366974-3672-3a2c-2345-0fda33942304"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Sultanate of Oman", + Iso2 = "OM", + Iso3 = "OMN", + Name = "Oman", + NumericCode = "512" + }, + new + { + Id = new Guid("cc7fabfc-4c2b-d9ff-bb45-003bfc2e468a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Islamic Republic of Pakistan", + Iso2 = "PK", + Iso3 = "PAK", + Name = "Pakistan", + NumericCode = "586" + }, + new + { + Id = new Guid("057884bc-3c2e-dea9-6522-b003c9297f7a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Palau", + Iso2 = "PW", + Iso3 = "PLW", + Name = "Palau", + NumericCode = "585" + }, + new + { + Id = new Guid("d6d31cdd-280a-56bc-24a4-a414028d2b67"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Palestine", + Iso2 = "PS", + Iso3 = "PSE", + Name = "Palestine", + NumericCode = "275" + }, + new + { + Id = new Guid("7bf4a786-3733-c670-e85f-03ee3caa6ef9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Panama", + Iso2 = "PA", + Iso3 = "PAN", + Name = "Panama", + NumericCode = "591" + }, + new + { + Id = new Guid("c926f091-fe96-35b3-56b5-d418d17e0159"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Independent State of Papua New Guinea", + Iso2 = "PG", + Iso3 = "PNG", + Name = "Papua New Guinea", + NumericCode = "598" + }, + new + { + Id = new Guid("db6ce903-ab43-3793-960c-659529bae6df"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Paraguay", + Iso2 = "PY", + Iso3 = "PRY", + Name = "Paraguay", + NumericCode = "600" + }, + new + { + Id = new Guid("75634729-8e4a-4cfd-739d-9f679bfca3ab"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Peru", + Iso2 = "PE", + Iso3 = "PER", + Name = "Peru", + NumericCode = "604" + }, + new + { + Id = new Guid("c93bccaf-1835-3c02-e2ee-c113ced19e43"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of the Philippines", + Iso2 = "PH", + Iso3 = "PHL", + Name = "Philippines", + NumericCode = "608" + }, + new + { + Id = new Guid("a5d0c9af-2022-2b43-9332-eb6a2ce4305d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Pitcairn Islands", + Iso2 = "PN", + Iso3 = "PCN", + Name = "Pitcairn Islands", + NumericCode = "612" + }, + new + { + Id = new Guid("de503629-2607-b948-e279-0509d8109d0f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Poland", + Iso2 = "PL", + Iso3 = "POL", + Name = "Poland", + NumericCode = "616" + }, + new + { + Id = new Guid("2a039b16-2adf-0fb8-3bdf-fbdf14358d9d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Portuguese Republic", + Iso2 = "PT", + Iso3 = "PRT", + Name = "Portugal", + NumericCode = "620" + }, + new + { + Id = new Guid("cd2c97c3-5473-0719-3803-fcacedfe2ea2"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Commonwealth of Puerto Rico", + Iso2 = "PR", + Iso3 = "PRI", + Name = "Puerto Rico", + NumericCode = "630" + }, + new + { + Id = new Guid("067c9448-9ad0-2c21-a1dc-fbdf5a63d18d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "State of Qatar", + Iso2 = "QA", + Iso3 = "QAT", + Name = "Qatar", + NumericCode = "634" + }, + new + { + Id = new Guid("881b4bb8-b6da-c73e-55c0-c9f31c02aaef"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Réunion", + Iso2 = "RE", + Iso3 = "REU", + Name = "Réunion", + NumericCode = "638" + }, + new + { + Id = new Guid("51aa4900-30a6-91b7-2728-071542a064ff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Romania", + Iso2 = "RO", + Iso3 = "ROU", + Name = "Romania", + NumericCode = "642" + }, + new + { + Id = new Guid("58337ef3-3d24-43e9-a440-832306e7fc07"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Russian Federation", + Iso2 = "RU", + Iso3 = "RUS", + Name = "Russian Federation", + NumericCode = "643" + }, + new + { + Id = new Guid("f5b15ea6-133d-c2c9-7ef9-b0916ea96edb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Rwanda", + Iso2 = "RW", + Iso3 = "RWA", + Name = "Rwanda", + NumericCode = "646" + }, + new + { + Id = new Guid("77f6f69b-ec41-8818-9395-8d39bf09e653"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Barthélemy", + Iso2 = "BL", + Iso3 = "BLM", + Name = "Saint Barthélemy", + NumericCode = "652" + }, + new + { + Id = new Guid("6a76d068-49e1-da80-ddb4-9ef3d11191e6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Helena, Ascension and Tristan da Cunha", + Iso2 = "SH", + Iso3 = "SHN", + Name = "Saint Helena, Ascension and Tristan da Cunha", + NumericCode = "654" + }, + new + { + Id = new Guid("fa633273-9866-840d-9739-c6c957901e46"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federation of Saint Kitts and Nevis", + Iso2 = "KN", + Iso3 = "KNA", + Name = "Saint Kitts and Nevis", + NumericCode = "659" + }, + new + { + Id = new Guid("220e980a-7363-0150-c250-89e83b967fb4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Lucia", + Iso2 = "LC", + Iso3 = "LCA", + Name = "Saint Lucia", + NumericCode = "662" + }, + new + { + Id = new Guid("899c2a9f-f35d-5a49-a6cd-f92531bb2266"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Martin (French part)", + Iso2 = "MF", + Iso3 = "MAF", + Name = "Saint Martin", + NumericCode = "663" + }, + new + { + Id = new Guid("5476986b-11a4-8463-9bd7-0f7354ec7a20"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Pierre and Miquelon", + Iso2 = "PM", + Iso3 = "SPM", + Name = "Saint Pierre and Miquelon", + NumericCode = "666" + }, + new + { + Id = new Guid("2f49855b-ff93-c399-d72a-121f2bf28bc9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Saint Vincent and the Grenadines", + Iso2 = "VC", + Iso3 = "VCT", + Name = "Saint Vincent and the Grenadines", + NumericCode = "670" + }, + new + { + Id = new Guid("a7c4c9db-8fe4-7d43-e830-1a70954970c3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Independent State of Samoa", + Iso2 = "WS", + Iso3 = "WSM", + Name = "Samoa", + NumericCode = "882" + }, + new + { + Id = new Guid("0a25f96f-5173-2fff-a2f8-c6872393edf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of San Marino", + Iso2 = "SM", + Iso3 = "SMR", + Name = "San Marino", + NumericCode = "674" + }, + new + { + Id = new Guid("766c1ebb-78c1-bada-37fb-c45d1bd4baff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic Republic of Sao Tome and Principe", + Iso2 = "ST", + Iso3 = "STP", + Name = "Sao Tome and Principe", + NumericCode = "678" + }, + new + { + Id = new Guid("a8f30b36-4a25-3fb9-c69e-84ce6640d785"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Saudi Arabia", + Iso2 = "SA", + Iso3 = "SAU", + Name = "Saudi Arabia", + NumericCode = "682" + }, + new + { + Id = new Guid("3175ac19-c801-0b87-8e66-7480a40dcf1e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Senegal", + Iso2 = "SN", + Iso3 = "SEN", + Name = "Senegal", + NumericCode = "686" + }, + new + { + Id = new Guid("971c7e66-c6e3-71f4-580a-5caf2852f9f4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Serbia", + Iso2 = "RS", + Iso3 = "SRB", + Name = "Serbia", + NumericCode = "688" + }, + new + { + Id = new Guid("2167da32-4f80-d31d-226c-0551970304eb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Seychelles", + Iso2 = "SC", + Iso3 = "SYC", + Name = "Seychelles", + NumericCode = "690" + }, + new + { + Id = new Guid("b0f4bdfa-17dd-9714-4fe8-3c3b1f010ffa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Sierra Leone", + Iso2 = "SL", + Iso3 = "SLE", + Name = "Sierra Leone", + NumericCode = "694" + }, + new + { + Id = new Guid("3ce3d958-7341-bd79-f294-f2e6907c186c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Singapore", + Iso2 = "SG", + Iso3 = "SGP", + Name = "Singapore", + NumericCode = "702" + }, + new + { + Id = new Guid("141e589a-7046-a265-d2f6-b2f85e6eeadd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Sint Maarten (Dutch part)", + Iso2 = "SX", + Iso3 = "SXM", + Name = "Sint Maarten (Dutch part)", + NumericCode = "534" + }, + new + { + Id = new Guid("3252e51a-5bc1-f065-7101-5b34ba493dc4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Slovakia (Slovak Republic)", + Iso2 = "SK", + Iso3 = "SVK", + Name = "Slovakia (Slovak Republic)", + NumericCode = "703" + }, + new + { + Id = new Guid("357c121b-e28d-1765-e699-cc4ec5ff86fc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Slovenia", + Iso2 = "SI", + Iso3 = "SVN", + Name = "Slovenia", + NumericCode = "705" + }, + new + { + Id = new Guid("7453c201-ecf1-d3dd-0409-e94d0733173b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Solomon Islands", + Iso2 = "SB", + Iso3 = "SLB", + Name = "Solomon Islands", + NumericCode = "090" + }, + new + { + Id = new Guid("802c05db-3866-545d-dc1a-a02c83ea6cf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Federal Republic of Somalia", + Iso2 = "SO", + Iso3 = "SOM", + Name = "Somalia", + NumericCode = "706" + }, + new + { + Id = new Guid("ebf38b9a-6fbe-6e82-3977-2c4763bea072"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of South Africa", + Iso2 = "ZA", + Iso3 = "ZAF", + Name = "South Africa", + NumericCode = "710" + }, + new + { + Id = new Guid("6af4d03e-edd0-d98a-bc7e-abc7df87d3dd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "South Georgia and the South Sandwich Islands", + Iso2 = "GS", + Iso3 = "SGS", + Name = "South Georgia and the South Sandwich Islands", + NumericCode = "239" + }, + new + { + Id = new Guid("6aac6f0e-d13a-a629-4c2b-9d6eaf6680e4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of South Sudan", + Iso2 = "SS", + Iso3 = "SSD", + Name = "South Sudan", + NumericCode = "728" + }, + new + { + Id = new Guid("414a34ce-2781-8f96-2bd0-7ada86c8cf38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Spain", + Iso2 = "ES", + Iso3 = "ESP", + Name = "Spain", + NumericCode = "724" + }, + new + { + Id = new Guid("687320c8-e841-c911-6d30-b14eb998feb6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic Socialist Republic of Sri Lanka", + Iso2 = "LK", + Iso3 = "LKA", + Name = "Sri Lanka", + NumericCode = "144" + }, + new + { + Id = new Guid("f0965449-6b15-6c1a-f5cb-ebd2d575c02c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Sudan", + Iso2 = "SD", + Iso3 = "SDN", + Name = "Sudan", + NumericCode = "729" + }, + new + { + Id = new Guid("61ba1844-4d33-84b4-dbac-70718aa91d59"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Suriname", + Iso2 = "SR", + Iso3 = "SUR", + Name = "Suriname", + NumericCode = "740" + }, + new + { + Id = new Guid("d525de3a-aecc-07de-0426-68f32af2968e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Svalbard & Jan Mayen Islands", + Iso2 = "SJ", + Iso3 = "SJM", + Name = "Svalbard & Jan Mayen Islands", + NumericCode = "744" + }, + new + { + Id = new Guid("a32a9fc2-677f-43e0-97aa-9e83943d785c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Eswatini", + Iso2 = "SZ", + Iso3 = "SWZ", + Name = "Eswatini", + NumericCode = "748" + }, + new + { + Id = new Guid("0ab731f0-5326-44be-af3a-20aa33ad0f35"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Sweden", + Iso2 = "SE", + Iso3 = "SWE", + Name = "Sweden", + NumericCode = "752" + }, + new + { + Id = new Guid("37c89068-a8e9-87e8-d651-f86fac63673a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Swiss Confederation", + Iso2 = "CH", + Iso3 = "CHE", + Name = "Switzerland", + NumericCode = "756" + }, + new + { + Id = new Guid("c1a923f6-b9ec-78f7-cc1c-7025e3d69d7d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Syrian Arab Republic", + Iso2 = "SY", + Iso3 = "SYR", + Name = "Syrian Arab Republic", + NumericCode = "760" + }, + new + { + Id = new Guid("875060ca-73f6-af3b-d844-1b1416ce4583"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Taiwan, Province of China", + Iso2 = "TW", + Iso3 = "TWN", + Name = "Taiwan", + NumericCode = "158" + }, + new + { + Id = new Guid("2a848549-9777-cf48-a0f2-b32c6f942096"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Tajikistan", + Iso2 = "TJ", + Iso3 = "TJK", + Name = "Tajikistan", + NumericCode = "762" + }, + new + { + Id = new Guid("4736c1ad-54bd-c8e8-d9ee-492a88268de8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United Republic of Tanzania", + Iso2 = "TZ", + Iso3 = "TZA", + Name = "Tanzania", + NumericCode = "834" + }, + new + { + Id = new Guid("84d58b3d-d131-1506-0792-1b3228b6f71f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Thailand", + Iso2 = "TH", + Iso3 = "THA", + Name = "Thailand", + NumericCode = "764" + }, + new + { + Id = new Guid("fb9a713c-2de1-882a-64b7-0e8fef5d2f7e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Democratic Republic of Timor-Leste", + Iso2 = "TL", + Iso3 = "TLS", + Name = "Timor-Leste", + NumericCode = "626" + }, + new + { + Id = new Guid("9dacf00b-7d0a-d744-cc60-e5fa66371e9d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Togolese Republic", + Iso2 = "TG", + Iso3 = "TGO", + Name = "Togo", + NumericCode = "768" + }, + new + { + Id = new Guid("11765ad0-30f2-bab8-b616-20f88b28b21e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Tokelau", + Iso2 = "TK", + Iso3 = "TKL", + Name = "Tokelau", + NumericCode = "772" + }, + new + { + Id = new Guid("9e7dbdc3-2c8b-e8ae-082b-e02695f8268e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Kingdom of Tonga", + Iso2 = "TO", + Iso3 = "TON", + Name = "Tonga", + NumericCode = "776" + }, + new + { + Id = new Guid("95467997-f989-f456-34b7-0b578302dcba"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Trinidad and Tobago", + Iso2 = "TT", + Iso3 = "TTO", + Name = "Trinidad and Tobago", + NumericCode = "780" + }, + new + { + Id = new Guid("06f8ad57-7133-9a5e-5a83-53052012b014"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Tunisian Republic", + Iso2 = "TN", + Iso3 = "TUN", + Name = "Tunisia", + NumericCode = "788" + }, + new + { + Id = new Guid("f39cca22-449e-9866-3a65-465a5510483e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Türkiye", + Iso2 = "TR", + Iso3 = "TUR", + Name = "Türkiye", + NumericCode = "792" + }, + new + { + Id = new Guid("550ca5df-3995-617c-c39d-437beb400a42"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Turkmenistan", + Iso2 = "TM", + Iso3 = "TKM", + Name = "Turkmenistan", + NumericCode = "795" + }, + new + { + Id = new Guid("0e0fefd5-9a05-fde5-bee9-ef56db7748a1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Turks and Caicos Islands", + Iso2 = "TC", + Iso3 = "TCA", + Name = "Turks and Caicos Islands", + NumericCode = "796" + }, + new + { + Id = new Guid("e0d562ca-f573-3c2f-eb83-f72d4d70d4fc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Tuvalu", + Iso2 = "TV", + Iso3 = "TUV", + Name = "Tuvalu", + NumericCode = "798" + }, + new + { + Id = new Guid("3e2cccbe-1615-c707-a97b-421a799b2559"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Uganda", + Iso2 = "UG", + Iso3 = "UGA", + Name = "Uganda", + NumericCode = "800" + }, + new + { + Id = new Guid("e087f51c-feba-19b6-5595-fcbdce170411"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Ukraine", + Iso2 = "UA", + Iso3 = "UKR", + Name = "Ukraine", + NumericCode = "804" + }, + new + { + Id = new Guid("29201cbb-ca65-1924-75a9-0c4d4db43001"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United Arab Emirates", + Iso2 = "AE", + Iso3 = "ARE", + Name = "United Arab Emirates", + NumericCode = "784" + }, + new + { + Id = new Guid("0b3b04b4-9782-79e3-bc55-9ab33b6ae9c7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United Kingdom of Great Britain & Northern Ireland", + Iso2 = "GB", + Iso3 = "GBR", + Name = "United Kingdom of Great Britain and Northern Ireland", + NumericCode = "826" + }, + new + { + Id = new Guid("cb2e209b-d4c6-6d5c-8901-d989a9188783"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United States of America", + Iso2 = "US", + Iso3 = "USA", + Name = "United States of America", + NumericCode = "840" + }, + new + { + Id = new Guid("0868cdd3-7f50-5a25-88d6-98c45f9157e3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United States Minor Outlying Islands", + Iso2 = "UM", + Iso3 = "UMI", + Name = "United States Minor Outlying Islands", + NumericCode = "581" + }, + new + { + Id = new Guid("e1947bdc-ff2c-d2c1-3c55-f1f9bf778578"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "United States Virgin Islands", + Iso2 = "VI", + Iso3 = "VIR", + Name = "United States Virgin Islands", + NumericCode = "850" + }, + new + { + Id = new Guid("8e787470-aae6-575a-fe0b-d65fc78b648a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Eastern Republic of Uruguay", + Iso2 = "UY", + Iso3 = "URY", + Name = "Uruguay", + NumericCode = "858" + }, + new + { + Id = new Guid("357369e3-85a8-86f7-91c7-349772ae7744"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Uzbekistan", + Iso2 = "UZ", + Iso3 = "UZB", + Name = "Uzbekistan", + NumericCode = "860" + }, + new + { + Id = new Guid("c98174ef-8198-54ba-2ff1-b93f3c646db8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Vanuatu", + Iso2 = "VU", + Iso3 = "VUT", + Name = "Vanuatu", + NumericCode = "548" + }, + new + { + Id = new Guid("52d9992c-19bd-82b4-9188-11dabcac6171"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Bolivarian Republic of Venezuela", + Iso2 = "VE", + Iso3 = "VEN", + Name = "Venezuela", + NumericCode = "862" + }, + new + { + Id = new Guid("d7236157-d5a7-6b7a-3bc1-69802313fa30"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Socialist Republic of Vietnam", + Iso2 = "VN", + Iso3 = "VNM", + Name = "Vietnam", + NumericCode = "704" + }, + new + { + Id = new Guid("e186a953-7ab3-c009-501c-a754267b770b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Wallis and Futuna", + Iso2 = "WF", + Iso3 = "WLF", + Name = "Wallis and Futuna", + NumericCode = "876" + }, + new + { + Id = new Guid("2f4cc994-53f1-1763-8220-5d89e063804f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Western Sahara", + Iso2 = "EH", + Iso3 = "ESH", + Name = "Western Sahara", + NumericCode = "732" + }, + new + { + Id = new Guid("8c4441fd-8cd4-ff1e-928e-e46f9ca12552"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Yemen", + Iso2 = "YE", + Iso3 = "YEM", + Name = "Yemen", + NumericCode = "887" + }, + new + { + Id = new Guid("ab0b7e83-bf02-16e6-e5ae-46c4bd4c093b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Zambia", + Iso2 = "ZM", + Iso3 = "ZMB", + Name = "Zambia", + NumericCode = "894" + }, + new + { + Id = new Guid("6984f722-6963-d067-d4d4-9fd3ef2edbf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + FullName = "Republic of Zimbabwe", + Iso2 = "ZW", + Iso3 = "ZWE", + Name = "Zimbabwe", + NumericCode = "716" + }); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CitizenReportingEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("CountryId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("EnglishTitle") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("LocationsVersion") + .HasColumnType("uuid"); + + b.Property("MonitoringNgoForCitizenReportingId") + .HasColumnType("uuid"); + + b.Property("PollingStationsVersion") + .HasColumnType("uuid"); + + b.Property("StartDate") + .HasColumnType("date"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("CountryId"); + + b.HasIndex("MonitoringNgoForCitizenReportingId"); + + b.ToTable("ElectionRounds"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ExportedDataAggregate.ExportedData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Base64EncodedData") + .HasColumnType("text"); + + b.Property("CompletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("ExportStatus") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExportedDataType") + .IsRequired() + .HasColumnType("text"); + + b.Property("FileName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("StartedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("Id"); + + b.ToTable("ExportedData", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FeedbackAggregate.Feedback", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property>("Metadata") + .IsRequired() + .HasColumnType("hstore"); + + b.Property("ObserverId") + .HasColumnType("uuid"); + + b.Property("TimeSubmitted") + .HasColumnType("timestamp with time zone"); + + b.Property("UserFeedback") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("ObserverId"); + + b.ToTable("UserFeedback"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormAggregate.Form", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DefaultLanguage") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Languages") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("LanguagesTranslationStatus") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringNgoId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("NumberOfQuestions") + .HasColumnType("integer"); + + b.Property("Questions") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("MonitoringNgoId"); + + b.ToTable("Forms"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormSubmissionAggregate.FormSubmission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Answers") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FollowUpStatus") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("NotApplicable"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("NumberOfFlaggedAnswers") + .HasColumnType("integer"); + + b.Property("NumberOfQuestionsAnswered") + .HasColumnType("integer"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("FormId"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.HasIndex("ElectionRoundId", "PollingStationId", "MonitoringObserverId", "FormId") + .IsUnique(); + + b.ToTable("FormSubmissions", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormTemplateAggregate.FormTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DefaultLanguage") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("FormTemplateType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Languages") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("NumberOfQuestions") + .HasColumnType("integer"); + + b.Property("Questions") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("FormTemplates"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ImportValidationErrorsAggregate.ImportValidationErrors", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Data") + .IsRequired() + .HasColumnType("text"); + + b.Property("ImportType") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("OriginalFileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("Id"); + + b.ToTable("ImportValidationErrors"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.LanguageAggregate.Language", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Iso1") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("character varying(2)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NativeName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("Id"); + + b.HasIndex("Iso1") + .IsUnique(); + + b.ToTable("Language"); + + b.HasData( + new + { + Id = new Guid("9c11bb58-5135-453a-1d24-dc20ef0e9031"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AA", + Name = "Afar", + NativeName = "Afaraf" + }, + new + { + Id = new Guid("bd4f1638-6017-733d-f696-b8b4d72664d7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AB", + Name = "Abkhaz", + NativeName = "аҧсуа бызшәа" + }, + new + { + Id = new Guid("29201cbb-ca65-1924-75a9-0c4d4db43001"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AE", + Name = "Avestan", + NativeName = "avesta" + }, + new + { + Id = new Guid("edd4319b-86f3-24cb-248c-71da624c02f7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AF", + Name = "Afrikaans", + NativeName = "Afrikaans" + }, + new + { + Id = new Guid("ef584e3c-03f2-42b0-7139-69d15d21e5a8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AK", + Name = "Akan", + NativeName = "Akan" + }, + new + { + Id = new Guid("688af4c8-9d64-ae1c-147f-b8afd54801e3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AM", + Name = "Amharic", + NativeName = "አማርኛ" + }, + new + { + Id = new Guid("d4d5c45a-d3c2-891e-6d7d-75569c3386ac"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AN", + Name = "Aragonese", + NativeName = "aragonés" + }, + new + { + Id = new Guid("a7afb7b1-b26d-4571-1a1f-3fff738ff21e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AR", + Name = "Arabic", + NativeName = "اَلْعَرَبِيَّةُ" + }, + new + { + Id = new Guid("538114de-7db0-9242-35e6-324fa7eff44d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AS", + Name = "Assamese", + NativeName = "অসমীয়া" + }, + new + { + Id = new Guid("e43a2010-14fc-63a9-f9d3-0ab2a1d0e52f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AV", + Name = "Avaric", + NativeName = "авар мацӀ" + }, + new + { + Id = new Guid("78c6e8af-fcb4-c783-987c-7e1aca3aed64"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AY", + Name = "Aymara", + NativeName = "aymar aru" + }, + new + { + Id = new Guid("008c3138-73d8-dbbc-f1dd-521e4c68bcf1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "AZ", + Name = "Azerbaijani", + NativeName = "azərbaycan dili" + }, + new + { + Id = new Guid("a7716d29-6ef6-b775-51c5-97094536329d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BA", + Name = "Bashkir", + NativeName = "башҡорт теле" + }, + new + { + Id = new Guid("0797a7d5-bbc0-2e52-0de8-14a42fc80baa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BE", + Name = "Belarusian", + NativeName = "беларуская мова" + }, + new + { + Id = new Guid("46576b73-c05b-7498-5b07-9bbf59b7645d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BG", + Name = "Bulgarian", + NativeName = "български език" + }, + new + { + Id = new Guid("75e4464b-a784-63b8-1ecc-69ee1f09f43f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BI", + Name = "Bislama", + NativeName = "Bislama" + }, + new + { + Id = new Guid("ca2a5560-d4c4-3c87-3090-6f5436310b55"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BM", + Name = "Bambara", + NativeName = "bamanankan" + }, + new + { + Id = new Guid("ed6278e0-436c-9fd9-0b9e-44fd424cbd1b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BN", + Name = "Bengali", + NativeName = "বাংলা" + }, + new + { + Id = new Guid("f33ced84-eb43-fb39-ef79-b266e4d4cd94"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BO", + Name = "Tibetan", + NativeName = "བོད་ཡིག" + }, + new + { + Id = new Guid("5283afbb-2744-e930-2c16-c5ea6b0ff7cc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BR", + Name = "Breton", + NativeName = "brezhoneg" + }, + new + { + Id = new Guid("46e88019-c521-57b2-d1c0-c0e2478d3b05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "BS", + Name = "Bosnian", + NativeName = "bosanski jezik" + }, + new + { + Id = new Guid("5c0e654b-8547-5d02-ee7b-d65e3c5c5273"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CA", + Name = "Catalan", + NativeName = "Català" + }, + new + { + Id = new Guid("cd5689d6-7a06-73c7-650e-f6f94387fd88"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CE", + Name = "Chechen", + NativeName = "нохчийн мотт" + }, + new + { + Id = new Guid("37c89068-a8e9-87e8-d651-f86fac63673a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CH", + Name = "Chamorro", + NativeName = "Chamoru" + }, + new + { + Id = new Guid("c64288fc-d941-0615-47f9-28e6c294ce26"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CO", + Name = "Corsican", + NativeName = "corsu" + }, + new + { + Id = new Guid("d13935c1-8956-1399-7c4e-0354795cd37b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CR", + Name = "Cree", + NativeName = "ᓀᐦᐃᔭᐍᐏᐣ" + }, + new + { + Id = new Guid("4def223a-9524-596d-cc29-ab7830c590de"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CS", + Name = "Czech", + NativeName = "čeština" + }, + new + { + Id = new Guid("57765d87-2424-2c86-ad9c-1af58ef3127a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CU", + Name = "Old Church Slavonic", + NativeName = "ѩзыкъ словѣньскъ" + }, + new + { + Id = new Guid("17ed5f0f-e091-94ff-0512-ad291bde94d7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CV", + Name = "Chuvash", + NativeName = "чӑваш чӗлхи" + }, + new + { + Id = new Guid("df20d0d7-9fbe-e725-d966-4fdf9f5c9dfb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "CY", + Name = "Welsh", + NativeName = "Cymraeg" + }, + new + { + Id = new Guid("b356a541-1383-3c0a-9afd-6aebae3753cb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "DA", + Name = "Danish", + NativeName = "dansk" + }, + new + { + Id = new Guid("46ef1468-86f6-0c99-f4e9-46f966167b05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "DE", + Name = "German", + NativeName = "Deutsch" + }, + new + { + Id = new Guid("d8d4f63d-fa65-63dd-a788-de2eec3d24ec"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "DV", + Name = "Divehi", + NativeName = "ދިވެހި" + }, + new + { + Id = new Guid("fee6f04f-c4c1-e3e4-645d-bb6bb703aeb7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "DZ", + Name = "Dzongkha", + NativeName = "རྫོང་ཁ" + }, + new + { + Id = new Guid("2dc643bd-cc6c-eb0c-7314-44123576f0ee"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EE", + Name = "Ewe", + NativeName = "Eʋegbe" + }, + new + { + Id = new Guid("b9da7f73-60cd-404c-18fb-1bc5bbfffb38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EL", + Name = "Greek", + NativeName = "Ελληνικά" + }, + new + { + Id = new Guid("094b3769-68b1-6211-ba2d-6bba92d6a167"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EN", + Name = "English", + NativeName = "English" + }, + new + { + Id = new Guid("1da84244-fa39-125e-06dc-3c0cb2342ce9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EO", + Name = "Esperanto", + NativeName = "Esperanto" + }, + new + { + Id = new Guid("414a34ce-2781-8f96-2bd0-7ada86c8cf38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ES", + Name = "Spanish", + NativeName = "Español" + }, + new + { + Id = new Guid("e75515a6-63cf-3612-a3a2-befa0d7048a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ET", + Name = "Estonian", + NativeName = "eesti" + }, + new + { + Id = new Guid("b2a87091-32fb-ba34-a721-bf8b3de5935d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "EU", + Name = "Basque", + NativeName = "euskara" + }, + new + { + Id = new Guid("e9da8997-dee8-0c2d-79d3-05fafc45092e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FA", + Name = "Persian", + NativeName = "فارسی" + }, + new + { + Id = new Guid("51a86a09-0d0b-31c1-90f1-f237db8e29ad"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FF", + Name = "Fula", + NativeName = "Fulfulde" + }, + new + { + Id = new Guid("5a5d9168-081b-1e02-1fbb-cdfa910e526c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FI", + Name = "Finnish", + NativeName = "suomi" + }, + new + { + Id = new Guid("0e2a1681-d852-67ae-7387-0d04be9e7fd3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FJ", + Name = "Fijian", + NativeName = "vosa Vakaviti" + }, + new + { + Id = new Guid("0d4fe6e6-ea1e-d1ce-5134-6c0c1a696a00"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FO", + Name = "Faroese", + NativeName = "føroyskt" + }, + new + { + Id = new Guid("b2261c50-1a57-7f1f-d72d-f8c21593874f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FR", + Name = "French", + NativeName = "Français" + }, + new + { + Id = new Guid("fb429393-f994-0a16-37f9-edc0510fced5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "FY", + Name = "Western Frisian", + NativeName = "Frysk" + }, + new + { + Id = new Guid("4826bc0f-235e-572f-2b1a-21f1c9e05f83"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GA", + Name = "Irish", + NativeName = "Gaeilge" + }, + new + { + Id = new Guid("ff5b4d88-c179-ff0d-6285-cf46ba475d7d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GD", + Name = "Scottish Gaelic", + NativeName = "Gàidhlig" + }, + new + { + Id = new Guid("2f00fe86-a06b-dc95-0ea7-4520d1dec784"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GL", + Name = "Galician", + NativeName = "galego" + }, + new + { + Id = new Guid("3ffe68ca-7350-175b-4e95-0c34f54dc1f4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GN", + Name = "Guaraní", + NativeName = "Avañe'ẽ" + }, + new + { + Id = new Guid("096a8586-9702-6fec-5f6a-6eb3b7b7837f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GU", + Name = "Gujarati", + NativeName = "ગુજરાતી" + }, + new + { + Id = new Guid("849b5e66-dc68-a1ed-6ed3-e315fbd0a0e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "GV", + Name = "Manx", + NativeName = "Gaelg" + }, + new + { + Id = new Guid("2e9cb133-68a7-2f3b-49d1-0921cf42dfae"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HA", + Name = "Hausa", + NativeName = "هَوُسَ" + }, + new + { + Id = new Guid("d685aa26-aee7-716b-9433-1b3411209f4b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HE", + Name = "Hebrew", + NativeName = "עברית" + }, + new + { + Id = new Guid("54686fcd-3f35-f468-7c9c-93217c5084bc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HI", + Name = "Hindi", + NativeName = "हिन्दी" + }, + new + { + Id = new Guid("87813ec7-4830-e4dc-5ab1-bd599057ede0"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HO", + Name = "Hiri Motu", + NativeName = "Hiri Motu" + }, + new + { + Id = new Guid("1f8be615-5746-277e-d82b-47596b5bb922"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HR", + Name = "Croatian", + NativeName = "Hrvatski" + }, + new + { + Id = new Guid("2bebebe4-edaa-9160-5a0c-4d99048bd8d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HT", + Name = "Haitian", + NativeName = "Kreyòl ayisyen" + }, + new + { + Id = new Guid("dcf19e1d-74a6-7b8b-a5ed-76b94a8ac2a7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HU", + Name = "Hungarian", + NativeName = "magyar" + }, + new + { + Id = new Guid("d832c50a-112e-4591-9432-4ada24bc85b2"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HY", + Name = "Armenian", + NativeName = "Հայերեն" + }, + new + { + Id = new Guid("d5bffdfb-6a8e-6d9f-2e59-4ada912acdba"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "HZ", + Name = "Herero", + NativeName = "Otjiherero" + }, + new + { + Id = new Guid("7f065da7-4ba4-81ca-5126-dbf606a73907"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IA", + Name = "Interlingua", + NativeName = "Interlingua" + }, + new + { + Id = new Guid("1d974338-decf-08e5-3e62-89e1bbdbb003"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ID", + Name = "Indonesian", + NativeName = "Bahasa Indonesia" + }, + new + { + Id = new Guid("294978f0-2702-d35d-cfc4-e676148aea2e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IE", + Name = "Interlingue", + NativeName = "Interlingue" + }, + new + { + Id = new Guid("caddae27-283a-82b2-9365-76a3d6c49eee"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IG", + Name = "Igbo", + NativeName = "Asụsụ Igbo" + }, + new + { + Id = new Guid("f21f562e-5c35-4806-4efc-416619b5b7f7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "II", + Name = "Nuosu", + NativeName = "ꆈꌠ꒿ Nuosuhxop" + }, + new + { + Id = new Guid("23785991-fef4-e625-4d3b-b6ac364d0fa0"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IK", + Name = "Inupiaq", + NativeName = "Iñupiaq" + }, + new + { + Id = new Guid("b8b09512-ea4c-4a61-9331-304f55324ef7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IO", + Name = "Ido", + NativeName = "Ido" + }, + new + { + Id = new Guid("4ee6400d-5534-7c67-1521-870d6b732366"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IS", + Name = "Icelandic", + NativeName = "Íslenska" + }, + new + { + Id = new Guid("7bbf15f4-a907-c0b2-7029-144aafb3c59d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IT", + Name = "Italian", + NativeName = "Italiano" + }, + new + { + Id = new Guid("899392d7-d54f-a1c6-407a-1bada9b85fdd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "IU", + Name = "Inuktitut", + NativeName = "ᐃᓄᒃᑎᑐᑦ" + }, + new + { + Id = new Guid("6857242c-f772-38b5-b5a2-c8e8b9db551f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "JA", + Name = "Japanese", + NativeName = "日本語" + }, + new + { + Id = new Guid("e7532b00-3b1b-ff2c-b7c0-26bd7e91af55"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "JV", + Name = "Javanese", + NativeName = "basa Jawa" + }, + new + { + Id = new Guid("9204928b-c569-ef6a-446e-4853aee439b0"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KA", + Name = "Georgian", + NativeName = "ქართული" + }, + new + { + Id = new Guid("0932ed88-c79f-591a-d684-9a77735f947e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KG", + Name = "Kongo", + NativeName = "Kikongo" + }, + new + { + Id = new Guid("914618fd-86f9-827a-91b8-826f0db9e02d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KI", + Name = "Kikuyu", + NativeName = "Gĩkũyũ" + }, + new + { + Id = new Guid("80ecea2c-8969-1929-0d4a-39ed2324abc6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KJ", + Name = "Kwanyama", + NativeName = "Kuanyama" + }, + new + { + Id = new Guid("b6b2351f-4f1e-c92f-0e9a-a915f4cc5fa6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KK", + Name = "Kazakh", + NativeName = "қазақ тілі" + }, + new + { + Id = new Guid("081a5fdb-445a-015a-1e36-f2e5014265ae"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KL", + Name = "Kalaallisut", + NativeName = "kalaallisut" + }, + new + { + Id = new Guid("5e7a08f2-7d59-bcdb-7ddd-876b87181420"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KM", + Name = "Khmer", + NativeName = "ខេមរភាសា" + }, + new + { + Id = new Guid("fa633273-9866-840d-9739-c6c957901e46"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KN", + Name = "Kannada", + NativeName = "ಕನ್ನಡ" + }, + new + { + Id = new Guid("74f19a84-b1c5-fa2d-8818-2220b80a3056"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KO", + Name = "Korean", + NativeName = "한국어" + }, + new + { + Id = new Guid("7bf934fa-bcf4-80b5-fd7d-ab4cca45c67b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KR", + Name = "Kanuri", + NativeName = "Kanuri" + }, + new + { + Id = new Guid("eace47f6-5499-f4f0-8f97-ed165b681d84"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KS", + Name = "Kashmiri", + NativeName = "कश्मीरी" + }, + new + { + Id = new Guid("7451108d-ad49-940a-d479-4d868b62a7c6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KU", + Name = "Kurdish", + NativeName = "Kurdî" + }, + new + { + Id = new Guid("78b7020d-8b82-3fae-2049-30e490ae1faf"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KV", + Name = "Komi", + NativeName = "коми кыв" + }, + new + { + Id = new Guid("b6f70436-9515-7ef8-af57-aad196503499"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KW", + Name = "Cornish", + NativeName = "Kernewek" + }, + new + { + Id = new Guid("3c5828e0-16a8-79ba-4e5c-9b45065df113"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "KY", + Name = "Kyrgyz", + NativeName = "Кыргызча" + }, + new + { + Id = new Guid("c4754c00-cfa5-aa6f-a9c8-a200457de7a8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LA", + Name = "Latin", + NativeName = "latine" + }, + new + { + Id = new Guid("1e5c0dcc-83e9-f275-c81d-3bc49f88e70c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LB", + Name = "Luxembourgish", + NativeName = "Lëtzebuergesch" + }, + new + { + Id = new Guid("80b770b8-4797-3d62-ef66-1ded7b0da0e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LG", + Name = "Ganda", + NativeName = "Luganda" + }, + new + { + Id = new Guid("9d6e6446-185e-235e-8771-9eb2d19f22e7"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LI", + Name = "Limburgish", + NativeName = "Limburgs" + }, + new + { + Id = new Guid("ca44a869-d3b6-052d-1e1a-ad4e3682a2ed"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LN", + Name = "Lingala", + NativeName = "Lingála" + }, + new + { + Id = new Guid("e9ad0bec-7dee-bd01-9528-1fc74d1d78dd"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LO", + Name = "Lao", + NativeName = "ພາສາລາວ" + }, + new + { + Id = new Guid("52538361-bbdf-fafb-e434-5655fc7451e5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LT", + Name = "Lithuanian", + NativeName = "lietuvių kalba" + }, + new + { + Id = new Guid("70673250-4cc3-3ba1-a42c-6b62ea8ab1d5"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LU", + Name = "Luba-Katanga", + NativeName = "Kiluba" + }, + new + { + Id = new Guid("9205dbfc-60cd-91d9-b0b8-8a18a3755286"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "LV", + Name = "Latvian", + NativeName = "latviešu valoda" + }, + new + { + Id = new Guid("976e496f-ca38-d113-1697-8af2d9a3b159"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MG", + Name = "Malagasy", + NativeName = "fiteny malagasy" + }, + new + { + Id = new Guid("943d2419-2ca6-95f8-9c3b-ed445aea0371"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MH", + Name = "Marshallese", + NativeName = "Kajin M̧ajeļ" + }, + new + { + Id = new Guid("54726f17-03b8-8af3-0359-c42d8fe8459d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MI", + Name = "Māori", + NativeName = "te reo Māori" + }, + new + { + Id = new Guid("aa0f69b2-93aa-ec51-b43b-60145db79e38"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MK", + Name = "Macedonian", + NativeName = "македонски јазик" + }, + new + { + Id = new Guid("c03d71a5-b215-8672-ec0c-dd8fe5c20e05"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ML", + Name = "Malayalam", + NativeName = "മലയാളം" + }, + new + { + Id = new Guid("c522b3d3-74cc-846f-0394-737dff4d2b1a"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MN", + Name = "Mongolian", + NativeName = "Монгол хэл" + }, + new + { + Id = new Guid("74da982f-cf20-e1b4-517b-a040511af23c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MR", + Name = "Marathi", + NativeName = "मराठी" + }, + new + { + Id = new Guid("50e5954d-7cb4-2201-b96c-f2a846ab3ae3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MS", + Name = "Malay", + NativeName = "Bahasa Melayu" + }, + new + { + Id = new Guid("f0219540-8b2c-bd29-4f76-b832de53a56f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MT", + Name = "Maltese", + NativeName = "Malti" + }, + new + { + Id = new Guid("d292ea2d-fbb6-7c1e-cb7d-23d552673776"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "MY", + Name = "Burmese", + NativeName = "ဗမာစာ" + }, + new + { + Id = new Guid("0c0fef20-0e8d-98ea-7724-12cea9b3b926"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NA", + Name = "Nauru", + NativeName = "Dorerin Naoero" + }, + new + { + Id = new Guid("4a3aa5a4-473f-45cd-f054-fa0465c476a4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NB", + Name = "Norwegian Bokmål", + NativeName = "Norsk bokmål" + }, + new + { + Id = new Guid("b4292ad3-3ca8-eea5-f3e0-d1983db8f61e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ND", + Name = "Northern Ndebele", + NativeName = "isiNdebele" + }, + new + { + Id = new Guid("97cd39d5-1aca-8f10-9f5e-3f611d7606d8"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NE", + Name = "Nepali", + NativeName = "नेपाली" + }, + new + { + Id = new Guid("2e1bd9d8-df06-d773-0eb9-98e274b63b43"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NG", + Name = "Ndonga", + NativeName = "Owambo" + }, + new + { + Id = new Guid("cfff3443-1378-9c7d-9d58-66146d7f29a6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NL", + Name = "Dutch", + NativeName = "Nederlands" + }, + new + { + Id = new Guid("df41c815-40f8-197a-7a8b-e456d43283d9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NN", + Name = "Norwegian Nynorsk", + NativeName = "Norsk nynorsk" + }, + new + { + Id = new Guid("914d7923-3ac5-75e8-c8e2-47d72561e35d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NO", + Name = "Norwegian", + NativeName = "Norsk" + }, + new + { + Id = new Guid("e3bacefb-d79b-1569-a91c-43d7e4f6f230"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NR", + Name = "Southern Ndebele", + NativeName = "isiNdebele" + }, + new + { + Id = new Guid("67729f87-ef47-dd3f-65f7-b0f6df0d6384"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NV", + Name = "Navajo", + NativeName = "Diné bizaad" + }, + new + { + Id = new Guid("720b4e12-b001-8d38-7c07-f43194b9645d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "NY", + Name = "Chichewa", + NativeName = "chiCheŵa" + }, + new + { + Id = new Guid("2b6d383a-9ab6-fcdf-bcfe-a4538faca407"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OC", + Name = "Occitan", + NativeName = "occitan" + }, + new + { + Id = new Guid("9ec46cb5-6c2b-0e22-07c5-eb2fe1b8d2ff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OJ", + Name = "Ojibwe", + NativeName = "ᐊᓂᔑᓈᐯᒧᐎᓐ" + }, + new + { + Id = new Guid("6c366974-3672-3a2c-2345-0fda33942304"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OM", + Name = "Oromo", + NativeName = "Afaan Oromoo" + }, + new + { + Id = new Guid("285b9e82-38af-33ab-79fd-0b4f3fd4f2f1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OR", + Name = "Oriya", + NativeName = "ଓଡ଼ିଆ" + }, + new + { + Id = new Guid("2d013d34-b258-8fe9-ef52-dd34e82a4672"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "OS", + Name = "Ossetian", + NativeName = "ирон æвзаг" + }, + new + { + Id = new Guid("7bf4a786-3733-c670-e85f-03ee3caa6ef9"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PA", + Name = "Panjabi", + NativeName = "ਪੰਜਾਬੀ" + }, + new + { + Id = new Guid("d8ef067c-1087-4ff5-8e1f-2291df7ac958"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PI", + Name = "Pāli", + NativeName = "पाऴि" + }, + new + { + Id = new Guid("de503629-2607-b948-e279-0509d8109d0f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PL", + Name = "Polish", + NativeName = "Polski" + }, + new + { + Id = new Guid("d6d31cdd-280a-56bc-24a4-a414028d2b67"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PS", + Name = "Pashto", + NativeName = "پښتو" + }, + new + { + Id = new Guid("2a039b16-2adf-0fb8-3bdf-fbdf14358d9d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "PT", + Name = "Portuguese", + NativeName = "Português" + }, + new + { + Id = new Guid("93fb8ace-4156-12d5-218e-64b7d35129b1"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "QU", + Name = "Quechua", + NativeName = "Runa Simi" + }, + new + { + Id = new Guid("136610e1-8115-9cf1-d671-7950c6483495"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RM", + Name = "Romansh", + NativeName = "rumantsch grischun" + }, + new + { + Id = new Guid("7a0725cf-311a-4f59-cff8-ad8b43dd226e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RN", + Name = "Kirundi", + NativeName = "Ikirundi" + }, + new + { + Id = new Guid("51aa4900-30a6-91b7-2728-071542a064ff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RO", + Name = "Romanian", + NativeName = "Română" + }, + new + { + Id = new Guid("58337ef3-3d24-43e9-a440-832306e7fc07"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RU", + Name = "Russian", + NativeName = "Русский" + }, + new + { + Id = new Guid("f5b15ea6-133d-c2c9-7ef9-b0916ea96edb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "RW", + Name = "Kinyarwanda", + NativeName = "Ikinyarwanda" + }, + new + { + Id = new Guid("a8f30b36-4a25-3fb9-c69e-84ce6640d785"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SA", + Name = "Sanskrit", + NativeName = "संस्कृतम्" + }, + new + { + Id = new Guid("2167da32-4f80-d31d-226c-0551970304eb"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SC", + Name = "Sardinian", + NativeName = "sardu" + }, + new + { + Id = new Guid("f0965449-6b15-6c1a-f5cb-ebd2d575c02c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SD", + Name = "Sindhi", + NativeName = "सिन्धी" + }, + new + { + Id = new Guid("0ab731f0-5326-44be-af3a-20aa33ad0f35"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SE", + Name = "Northern Sami", + NativeName = "Davvisámegiella" + }, + new + { + Id = new Guid("3ce3d958-7341-bd79-f294-f2e6907c186c"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SG", + Name = "Sango", + NativeName = "yângâ tî sängö" + }, + new + { + Id = new Guid("357c121b-e28d-1765-e699-cc4ec5ff86fc"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SI", + Name = "Sinhala", + NativeName = "සිංහල" + }, + new + { + Id = new Guid("3252e51a-5bc1-f065-7101-5b34ba493dc4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SK", + Name = "Slovak", + NativeName = "slovenčina" + }, + new + { + Id = new Guid("b0f4bdfa-17dd-9714-4fe8-3c3b1f010ffa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SL", + Name = "Slovenian", + NativeName = "slovenščina" + }, + new + { + Id = new Guid("0a25f96f-5173-2fff-a2f8-c6872393edf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SM", + Name = "Samoan", + NativeName = "gagana fa'a Samoa" + }, + new + { + Id = new Guid("3175ac19-c801-0b87-8e66-7480a40dcf1e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SN", + Name = "Shona", + NativeName = "chiShona" + }, + new + { + Id = new Guid("802c05db-3866-545d-dc1a-a02c83ea6cf6"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SO", + Name = "Somali", + NativeName = "Soomaaliga" + }, + new + { + Id = new Guid("fb1cce84-4a6c-1834-0ff2-6df002e3d56f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SQ", + Name = "Albanian", + NativeName = "Shqip" + }, + new + { + Id = new Guid("61ba1844-4d33-84b4-dbac-70718aa91d59"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SR", + Name = "Serbian", + NativeName = "српски језик" + }, + new + { + Id = new Guid("6aac6f0e-d13a-a629-4c2b-9d6eaf6680e4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SS", + Name = "Swati", + NativeName = "SiSwati" + }, + new + { + Id = new Guid("766c1ebb-78c1-bada-37fb-c45d1bd4baff"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ST", + Name = "Southern Sotho", + NativeName = "Sesotho" + }, + new + { + Id = new Guid("ee1ace14-e945-4767-85ec-3d74be8b516b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SU", + Name = "Sundanese", + NativeName = "Basa Sunda" + }, + new + { + Id = new Guid("4d8bcda4-5598-16cd-b379-97eb7a5e1c29"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SV", + Name = "Swedish", + NativeName = "Svenska" + }, + new + { + Id = new Guid("5f002f07-f2c3-9fa4-2e29-225d116c10a3"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "SW", + Name = "Swahili", + NativeName = "Kiswahili" + }, + new + { + Id = new Guid("8bc44f03-84a5-2afc-8b0b-40c727e4ce36"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TA", + Name = "Tamil", + NativeName = "தமிழ்" + }, + new + { + Id = new Guid("3bf5a74a-6d12-e971-16bc-c75e487f2615"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TE", + Name = "Telugu", + NativeName = "తెలుగు" + }, + new + { + Id = new Guid("9dacf00b-7d0a-d744-cc60-e5fa66371e9d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TG", + Name = "Tajik", + NativeName = "тоҷикӣ" + }, + new + { + Id = new Guid("84d58b3d-d131-1506-0792-1b3228b6f71f"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TH", + Name = "Thai", + NativeName = "ไทย" + }, + new + { + Id = new Guid("596e8283-10ce-d81d-2e6f-400fa259d717"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TI", + Name = "Tigrinya", + NativeName = "ትግርኛ" + }, + new + { + Id = new Guid("11765ad0-30f2-bab8-b616-20f88b28b21e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TK", + Name = "Turkmen", + NativeName = "Türkmençe" + }, + new + { + Id = new Guid("fb9a713c-2de1-882a-64b7-0e8fef5d2f7e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TL", + Name = "Tagalog", + NativeName = "Wikang Tagalog" + }, + new + { + Id = new Guid("06f8ad57-7133-9a5e-5a83-53052012b014"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TN", + Name = "Tswana", + NativeName = "Setswana" + }, + new + { + Id = new Guid("9e7dbdc3-2c8b-e8ae-082b-e02695f8268e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TO", + Name = "Tonga", + NativeName = "faka Tonga" + }, + new + { + Id = new Guid("f39cca22-449e-9866-3a65-465a5510483e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TR", + Name = "Turkish", + NativeName = "Türkçe" + }, + new + { + Id = new Guid("6200b376-9eae-d01b-de52-8674aaf5b013"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TS", + Name = "Tsonga", + NativeName = "Xitsonga" + }, + new + { + Id = new Guid("95467997-f989-f456-34b7-0b578302dcba"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TT", + Name = "Tatar", + NativeName = "татар теле" + }, + new + { + Id = new Guid("875060ca-73f6-af3b-d844-1b1416ce4583"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TW", + Name = "Twi", + NativeName = "Twi" + }, + new + { + Id = new Guid("2299a74f-3ebc-f022-da1a-44ae59335b3b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "TY", + Name = "Tahitian", + NativeName = "Reo Tahiti" + }, + new + { + Id = new Guid("3e2cccbe-1615-c707-a97b-421a799b2559"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "UG", + Name = "Uyghur", + NativeName = "ئۇيغۇرچە‎" + }, + new + { + Id = new Guid("de29d5e7-2ecf-a4ff-5e40-5e83edd0d9b4"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "UK", + Name = "Ukrainian", + NativeName = "Українська" + }, + new + { + Id = new Guid("f1f09549-a9bb-da4a-9b98-8655a01235aa"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "UR", + Name = "Urdu", + NativeName = "اردو" + }, + new + { + Id = new Guid("357369e3-85a8-86f7-91c7-349772ae7744"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "UZ", + Name = "Uzbek", + NativeName = "Ўзбек" + }, + new + { + Id = new Guid("52d9992c-19bd-82b4-9188-11dabcac6171"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "VE", + Name = "Venda", + NativeName = "Tshivenḓa" + }, + new + { + Id = new Guid("e1947bdc-ff2c-d2c1-3c55-f1f9bf778578"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "VI", + Name = "Vietnamese", + NativeName = "Tiếng Việt" + }, + new + { + Id = new Guid("c2254fd9-159e-4064-0fbf-a7969cba06ec"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "VO", + Name = "Volapük", + NativeName = "Volapük" + }, + new + { + Id = new Guid("629b68d8-1d71-d3ce-f13e-45048ffff017"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "WA", + Name = "Walloon", + NativeName = "walon" + }, + new + { + Id = new Guid("ca6bfadf-4e87-0692-a6b3-20ea6a51555d"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "WO", + Name = "Wolof", + NativeName = "Wollof" + }, + new + { + Id = new Guid("0b9b4368-7ceb-e519-153d-2c58c983852b"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "XH", + Name = "Xhosa", + NativeName = "isiXhosa" + }, + new + { + Id = new Guid("13016d0c-fbf0-9503-12f2-e0f8d27394ae"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "YI", + Name = "Yiddish", + NativeName = "ייִדיש" + }, + new + { + Id = new Guid("d55a9eb2-48fc-2719-47bf-99e902c28e80"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "YO", + Name = "Yoruba", + NativeName = "Yorùbá" + }, + new + { + Id = new Guid("ebf38b9a-6fbe-6e82-3977-2c4763bea072"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ZA", + Name = "Zhuang", + NativeName = "Saɯ cueŋƅ" + }, + new + { + Id = new Guid("0ce6f5e0-0789-fa0e-b4b5-23a5b1f5e257"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ZH", + Name = "Chinese", + NativeName = "中文" + }, + new + { + Id = new Guid("2c7b808d-7786-2deb-5318-56f7c238520e"), + CreatedOn = new DateTime(2024, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), + Iso1 = "ZU", + Name = "Zulu", + NativeName = "isiZulu" + }); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.LocationAggregate.Location", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayOrder") + .HasColumnType("integer"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Level1") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level2") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level3") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level4") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level5") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Tags") + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.ToTable("Locations"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormsVersion") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("NgoId") + .HasColumnType("uuid"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("NgoId"); + + b.ToTable("MonitoringNgos"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringNgoId") + .HasColumnType("uuid"); + + b.Property("ObserverId") + .HasColumnType("uuid"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("Tags") + .IsRequired() + .HasColumnType("text[]"); + + b.HasKey("Id"); + + b.HasIndex("MonitoringNgoId"); + + b.HasIndex("ObserverId"); + + b.HasIndex("ElectionRoundId", "Id") + .IsUnique(); + + b.ToTable("MonitoringObservers"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NgoAdminAggregate.NgoAdmin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ApplicationUserId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("NgoId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId"); + + b.HasIndex("NgoId"); + + b.ToTable("NgoAdmins", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NgoAggregate.Ngo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Ngos"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NoteAggregate.Note", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.Property("QuestionId") + .HasColumnType("uuid"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(10000) + .HasColumnType("character varying(10000)"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("FormId"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.ToTable("Notes", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationAggregate.MonitoringObserverNotification", b => + { + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("NotificationId") + .HasColumnType("uuid"); + + b.Property("IsRead") + .HasColumnType("boolean"); + + b.HasKey("MonitoringObserverId", "NotificationId"); + + b.HasIndex("NotificationId"); + + b.ToTable("MonitoringObserverNotification"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationAggregate.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Body") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("SenderId") + .HasColumnType("uuid"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("SenderId"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationStubAggregate.NotificationStub", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("HasBeenProcessed") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("SerializedData") + .IsRequired() + .HasColumnType("text"); + + b.Property("StubType") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("NotificationStubs"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationTokenAggregate.NotificationToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ObserverId") + .HasColumnType("uuid"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.HasKey("Id"); + + b.HasIndex("ObserverId"); + + b.ToTable("NotificationTokens"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ApplicationUserId") + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId"); + + b.ToTable("Observers", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverGuideAggregate.ObserverGuide", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("FileName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FilePath") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("GuideType") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MimeType") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MonitoringNgoId") + .HasColumnType("uuid"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UploadedFileName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("WebsiteUrl") + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.HasKey("Id"); + + b.HasIndex("MonitoringNgoId"); + + b.ToTable("ObserversGuides"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Address") + .IsRequired() + .HasMaxLength(2024) + .HasColumnType("character varying(2024)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayOrder") + .HasColumnType("integer"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Level1") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level2") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level3") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level4") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level5") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Number") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Tags") + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.ToTable("PollingStations"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationInfoAggregate.PollingStationInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Answers") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("ArrivalTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DepartureTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FollowUpStatus") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("NotApplicable"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MinutesMonitoring") + .HasColumnType("double precision"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("NumberOfFlaggedAnswers") + .HasColumnType("integer"); + + b.Property("NumberOfQuestionsAnswered") + .HasColumnType("integer"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.Property("PollingStationInformationFormId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.HasIndex("PollingStationInformationFormId"); + + b.HasIndex("ElectionRoundId", "PollingStationId", "MonitoringObserverId", "PollingStationInformationFormId") + .IsUnique(); + + b.ToTable("PollingStationInformation", (string)null); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate.PollingStationInformationForm", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DefaultLanguage") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FormType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Languages") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("LanguagesTranslationStatus") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("NumberOfQuestions") + .HasColumnType("integer"); + + b.Property("Questions") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId") + .IsUnique(); + + b.ToTable("PollingStationInformationForms"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.QuickReportAggregate.QuickReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(10000) + .HasColumnType("character varying(10000)"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FollowUpStatus") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("NotApplicable"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("PollingStationDetails") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("PollingStationId") + .HasColumnType("uuid"); + + b.Property("QuickReportLocationType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("Id"); + + b.HasIndex("MonitoringObserverId"); + + b.HasIndex("PollingStationId"); + + b.ToTable("QuickReports"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.QuickReportAttachmentAggregate.QuickReportAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasColumnType("text"); + + b.Property("FilePath") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsCompleted") + .HasColumnType("boolean"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("MimeType") + .IsRequired() + .HasColumnType("text"); + + b.Property("MonitoringObserverId") + .HasColumnType("uuid"); + + b.Property("QuickReportId") + .HasColumnType("uuid"); + + b.Property("UploadedFileName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.HasIndex("MonitoringObserverId"); + + b.ToTable("QuickReportAttachments"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", b => + { + b.OwnsOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.UserPreferences", "Preferences", b1 => + { + b1.Property("ApplicationUserId") + .HasColumnType("uuid"); + + b1.Property("LanguageCode") + .IsRequired() + .HasColumnType("text"); + + b1.HasKey("ApplicationUserId"); + + b1.ToTable("AspNetUsers"); + + b1.ToJson("Preferences"); + + b1.WithOwner() + .HasForeignKey("ApplicationUserId"); + }); + + b.Navigation("Preferences") + .IsRequired(); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.AttachmentAggregate.Attachment", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.LocationAggregate.Location", "Location") + .WithMany() + .HasForeignKey("LocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + + b.Navigation("Location"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAttachmentAggregate.CitizenReportAttachment", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", "CitizenReport") + .WithMany("Attachments") + .HasForeignKey("CitizenReportId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CitizenReport"); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportNoteAggregate.CitizenReportNote", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", "CitizenReport") + .WithMany("Notes") + .HasForeignKey("CitizenReportId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CitizenReport"); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.CountryAggregate.Country", "Country") + .WithMany() + .HasForeignKey("CountryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", "MonitoringNgoForCitizenReporting") + .WithMany() + .HasForeignKey("MonitoringNgoForCitizenReportingId"); + + b.Navigation("Country"); + + b.Navigation("MonitoringNgoForCitizenReporting"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ExportedDataAggregate.ExportedData", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FeedbackAggregate.Feedback", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", "Observer") + .WithMany() + .HasForeignKey("ObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Observer"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormAggregate.Form", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", "MonitoringNgo") + .WithMany() + .HasForeignKey("MonitoringNgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringNgo"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.FormSubmissionAggregate.FormSubmission", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.LocationAggregate.Location", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany("MonitoringNgos") + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.NgoAggregate.Ngo", "Ngo") + .WithMany() + .HasForeignKey("NgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Ngo"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", "MonitoringNgo") + .WithMany("MonitoringObservers") + .HasForeignKey("MonitoringNgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", "Observer") + .WithMany("MonitoringObservers") + .HasForeignKey("ObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringNgo"); + + b.Navigation("Observer"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NgoAdminAggregate.NgoAdmin", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", "ApplicationUser") + .WithMany() + .HasForeignKey("ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.NgoAggregate.Ngo", "Ngo") + .WithMany("Admins") + .HasForeignKey("NgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApplicationUser"); + + b.Navigation("Ngo"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NoteAggregate.Note", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.FormAggregate.Form", "Form") + .WithMany() + .HasForeignKey("FormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Form"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationAggregate.MonitoringObserverNotification", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.NotificationAggregate.Notification", "Notification") + .WithMany() + .HasForeignKey("NotificationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MonitoringObserver"); + + b.Navigation("Notification"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationAggregate.Notification", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.NgoAdminAggregate.NgoAdmin", "Sender") + .WithMany() + .HasForeignKey("SenderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NotificationTokenAggregate.NotificationToken", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", null) + .WithMany() + .HasForeignKey("ObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ApplicationUserAggregate.ApplicationUser", "ApplicationUser") + .WithMany() + .HasForeignKey("ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApplicationUser"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverGuideAggregate.ObserverGuide", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", "MonitoringNgo") + .WithMany() + .HasForeignKey("MonitoringNgoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MonitoringNgo"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationInfoAggregate.PollingStationInformation", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate.PollingStationInformationForm", "PollingStationInformationForm") + .WithMany() + .HasForeignKey("PollingStationInformationFormId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + + b.Navigation("PollingStationInformationForm"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate.PollingStationInformationForm", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithOne() + .HasForeignKey("Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate.PollingStationInformationForm", "ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.QuickReportAggregate.QuickReport", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.PollingStationAggregate.PollingStation", "PollingStation") + .WithMany() + .HasForeignKey("PollingStationId"); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringObserver"); + + b.Navigation("PollingStation"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.QuickReportAttachmentAggregate.QuickReportAttachment", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Vote.Monitor.Domain.Entities.MonitoringObserverAggregate.MonitoringObserver", "MonitoringObserver") + .WithMany() + .HasForeignKey("MonitoringObserverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + + b.Navigation("MonitoringObserver"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAggregate.CitizenReport", b => + { + b.Navigation("Attachments"); + + b.Navigation("Notes"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", b => + { + b.Navigation("MonitoringNgos"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", b => + { + b.Navigation("MonitoringObservers"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.NgoAggregate.Ngo", b => + { + b.Navigation("Admins"); + }); + + modelBuilder.Entity("Vote.Monitor.Domain.Entities.ObserverAggregate.Observer", b => + { + b.Navigation("MonitoringObservers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/api/src/Vote.Monitor.Domain/Migrations/20240917090918_AddLocationVersionColumn.cs b/api/src/Vote.Monitor.Domain/Migrations/20240917090918_AddLocationVersionColumn.cs new file mode 100644 index 000000000..09cdca6bd --- /dev/null +++ b/api/src/Vote.Monitor.Domain/Migrations/20240917090918_AddLocationVersionColumn.cs @@ -0,0 +1,30 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Vote.Monitor.Domain.Migrations +{ + /// + public partial class AddLocationVersionColumn : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "LocationsVersion", + table: "ElectionRounds", + type: "uuid", + nullable: false, + defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "LocationsVersion", + table: "ElectionRounds"); + } + } +} diff --git a/api/src/Vote.Monitor.Domain/Migrations/VoteMonitorContextModelSnapshot.cs b/api/src/Vote.Monitor.Domain/Migrations/VoteMonitorContextModelSnapshot.cs index e6ec837f1..d7aeb8eb9 100644 --- a/api/src/Vote.Monitor.Domain/Migrations/VoteMonitorContextModelSnapshot.cs +++ b/api/src/Vote.Monitor.Domain/Migrations/VoteMonitorContextModelSnapshot.cs @@ -414,6 +414,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("LastModifiedOn") .HasColumnType("timestamp with time zone"); + b.Property("LocationId") + .HasColumnType("uuid"); + b.Property("NumberOfFlaggedAnswers") .HasColumnType("integer"); @@ -426,6 +429,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("FormId"); + b.HasIndex("LocationId"); + b.ToTable("CitizenReports"); }); @@ -3113,6 +3118,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("LastModifiedOn") .HasColumnType("timestamp with time zone"); + b.Property("LocationsVersion") + .HasColumnType("uuid"); + b.Property("MonitoringNgoForCitizenReportingId") .HasColumnType("uuid"); @@ -4949,6 +4957,61 @@ protected override void BuildModel(ModelBuilder modelBuilder) }); }); + modelBuilder.Entity("Vote.Monitor.Domain.Entities.LocationAggregate.Location", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayOrder") + .HasColumnType("integer"); + + b.Property("ElectionRoundId") + .HasColumnType("uuid"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastModifiedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Level1") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level2") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level3") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level4") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Level5") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Tags") + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("ElectionRoundId"); + + b.ToTable("Locations"); + }); + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", b => { b.Property("Id") @@ -5460,6 +5523,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("MonitoringObserverId") .HasColumnType("uuid"); + b.Property("NumberOfFlaggedAnswers") + .HasColumnType("integer"); + b.Property("NumberOfQuestionsAnswered") .HasColumnType("integer"); @@ -5489,6 +5555,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("uuid"); + b.Property("Code") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + b.Property("CreatedBy") .HasColumnType("uuid"); @@ -5500,19 +5571,35 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(256) .HasColumnType("character varying(256)"); + b.Property("Description") + .IsRequired() + .HasColumnType("jsonb"); + b.Property("ElectionRoundId") .HasColumnType("uuid"); + b.Property("FormType") + .IsRequired() + .HasColumnType("text"); + b.Property("Languages") .IsRequired() .HasColumnType("text[]"); + b.Property("LanguagesTranslationStatus") + .IsRequired() + .HasColumnType("jsonb"); + b.Property("LastModifiedBy") .HasColumnType("uuid"); b.Property("LastModifiedOn") .HasColumnType("timestamp with time zone"); + b.Property("Name") + .IsRequired() + .HasColumnType("jsonb"); + b.Property("NumberOfQuestions") .HasColumnType("integer"); @@ -5520,6 +5607,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired() .HasColumnType("jsonb"); + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + b.HasKey("Id"); b.HasIndex("ElectionRoundId") @@ -5775,9 +5866,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.HasOne("Vote.Monitor.Domain.Entities.LocationAggregate.Location", "Location") + .WithMany() + .HasForeignKey("LocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + b.Navigation("ElectionRound"); b.Navigation("Form"); + + b.Navigation("Location"); }); modelBuilder.Entity("Vote.Monitor.Domain.Entities.CitizenReportAttachmentAggregate.CitizenReportAttachment", b => @@ -5935,6 +6034,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("PollingStation"); }); + modelBuilder.Entity("Vote.Monitor.Domain.Entities.LocationAggregate.Location", b => + { + b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") + .WithMany() + .HasForeignKey("ElectionRoundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ElectionRound"); + }); + modelBuilder.Entity("Vote.Monitor.Domain.Entities.MonitoringNgoAggregate.MonitoringNgo", b => { b.HasOne("Vote.Monitor.Domain.Entities.ElectionRoundAggregate.ElectionRound", "ElectionRound") diff --git a/api/src/Vote.Monitor.Domain/VoteMonitorContext.cs b/api/src/Vote.Monitor.Domain/VoteMonitorContext.cs index fc32726ed..fec2c66a5 100644 --- a/api/src/Vote.Monitor.Domain/VoteMonitorContext.cs +++ b/api/src/Vote.Monitor.Domain/VoteMonitorContext.cs @@ -10,6 +10,7 @@ using Vote.Monitor.Domain.Entities.FormAggregate; using Vote.Monitor.Domain.Entities.FormSubmissionAggregate; using Vote.Monitor.Domain.Entities.FormTemplateAggregate; +using Vote.Monitor.Domain.Entities.LocationAggregate; using Vote.Monitor.Domain.Entities.MonitoringNgoAggregate; using Vote.Monitor.Domain.Entities.MonitoringObserverAggregate; using Vote.Monitor.Domain.Entities.NgoAdminAggregate; @@ -72,6 +73,8 @@ public VoteMonitorContext(DbContextOptions options, public DbSet CitizenReportNotes { get; set; } public DbSet CitizenReportAttachments { get; set; } public DbSet MonitoringObserverNotification { get; set; } + + public DbSet Locations { get; set; } protected override void OnModelCreating(ModelBuilder builder) { @@ -143,6 +146,8 @@ protected override void OnModelCreating(ModelBuilder builder) builder.ApplyConfiguration(new CitizenReportConfiguration()); builder.ApplyConfiguration(new CitizenReportNoteConfiguration()); builder.ApplyConfiguration(new CitizenReportAttachmentConfiguration()); + + builder.ApplyConfiguration(new LocationConfiguration()); } protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/AnswerWriter.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/AnswerWriter.cs similarity index 97% rename from api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/AnswerWriter.cs rename to api/src/Vote.Monitor.Hangfire/Jobs/Export/AnswerWriter.cs index 3e7d8187c..84d57def7 100644 --- a/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/AnswerWriter.cs +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/AnswerWriter.cs @@ -2,8 +2,9 @@ using Vote.Monitor.Domain.Entities.FormBase.Questions; using Vote.Monitor.Hangfire.Extensions; using Vote.Monitor.Hangfire.Jobs.Export.FormSubmissions.ReadModels; +using Vote.Monitor.Hangfire.Models; -namespace Vote.Monitor.Hangfire.Jobs.Export.FormSubmissions; +namespace Vote.Monitor.Hangfire.Jobs.Export; public class AnswerWriter { @@ -84,7 +85,7 @@ private void WriteSelectOptions(IReadOnlyList options) } } - public void WithSubmission(Guid submissionId, BaseAnswer answer, List attachments, List notes) + public void WithSubmission(Guid submissionId, BaseAnswer answer, List attachments, List notes) { _maxNumberOfAttachments = Math.Max(_maxNumberOfAttachments, attachments.Count); _maxNumberOfNotes = Math.Max(_maxNumberOfNotes, notes.Count); diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/CitizenReports/CitizenReportsDataTable.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/CitizenReports/CitizenReportsDataTable.cs new file mode 100644 index 000000000..8e55e16f2 --- /dev/null +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/CitizenReports/CitizenReportsDataTable.cs @@ -0,0 +1,47 @@ +using Vote.Monitor.Domain.Entities.FormAggregate; +using Vote.Monitor.Domain.Entities.FormBase.Questions; +using Vote.Monitor.Domain.Entities.PollingStationInfoFormAggregate; + +namespace Vote.Monitor.Hangfire.Jobs.Export.CitizenReports; + +public class CitizenReportsDataTable +{ + private readonly List _header; + private readonly List> _dataTable; + private readonly Guid _formId; + private readonly List _answerWriters; + + private CitizenReportsDataTable(Guid formId, string defaultLanguage, IReadOnlyList questions) + { + _header = new List(); + _dataTable = new List>(); + _formId = formId; + _answerWriters = questions.Select(question => new AnswerWriter(defaultLanguage, question)).ToList(); + + _header.AddRange([ + "CitizenReportId", + "TimeSubmitted", + "FollowUpStatus", + "Level1", + "Level2", + "Level3", + "Level4", + "Level5" + ]); + } + + public static CitizenReportsDataTable FromForm(PollingStationInformationForm psiForm) + { + return new CitizenReportsDataTable(psiForm.Id, psiForm.DefaultLanguage, psiForm.Questions); + } + + public static CitizenReportsDataTable FromForm(Form form) + { + return new CitizenReportsDataTable(form.Id, form.DefaultLanguage, form.Questions); + } + + public CitizenReportsDataTableGenerator WithData() + { + return CitizenReportsDataTableGenerator.For(_header, _dataTable, _formId, _answerWriters); + } +} diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/CitizenReports/CitizenReportsDataTableGenerator.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/CitizenReports/CitizenReportsDataTableGenerator.cs new file mode 100644 index 000000000..23d1b727b --- /dev/null +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/CitizenReports/CitizenReportsDataTableGenerator.cs @@ -0,0 +1,106 @@ +using Vote.Monitor.Hangfire.Jobs.Export.CitizenReports.ReadModels; + +namespace Vote.Monitor.Hangfire.Jobs.Export.CitizenReports; + +public class CitizenReportsDataTableGenerator +{ + private readonly List _header; + private readonly List> _dataTable; + private readonly Guid _formId; + + private readonly Dictionary _answerWriters; + private readonly List _citizenReports = []; + + private CitizenReportsDataTableGenerator(List header, + List> dataTable, + Guid formId, + List answerWriters) + { + _header = header; + _dataTable = dataTable; + _formId = formId; + _answerWriters = answerWriters.ToDictionary(x => x.QuestionId); + } + + internal static CitizenReportsDataTableGenerator For(List header, + List> dataTable, + Guid formId, + List answerWriters) + { + return new CitizenReportsDataTableGenerator(header, dataTable, formId, answerWriters); + } + + public CitizenReportsDataTableGenerator For(params CitizenReportModel[] citizenReports) + { + foreach (var citizenReport in citizenReports) + { + if (citizenReport.FormId != _formId) + { + // ignore submission if it is not for the current form + continue; + } + + MapToAnswerData(citizenReport); + + var row = new List + { + citizenReport.CitizenReportId.ToString(), + citizenReport.TimeSubmitted.ToString("s"), + citizenReport.FollowUpStatus.Value, + citizenReport.Level1, + citizenReport.Level2, + citizenReport.Level3, + citizenReport.Level4, + citizenReport.Level5, + }; + + _dataTable.Add(row); + } + + return this; + } + + private void MapToAnswerData(CitizenReportModel citizenReport) + { + _citizenReports.Add(citizenReport); + var answerNotes = citizenReport + .Notes + .GroupBy(x => x.QuestionId) + .ToDictionary(x => x.Key, y => y.ToList()); + + var answerAttachments = citizenReport + .Attachments + .GroupBy(x => x.QuestionId) + .ToDictionary(x => x.Key, y => y.ToList()); + + foreach (var answer in citizenReport.Answers) + { + var notes = answerNotes.GetValueOrDefault(answer.QuestionId, []); + var attachments = answerAttachments.GetValueOrDefault(answer.QuestionId, []); + if (_answerWriters.TryGetValue(answer.QuestionId, out var writer)) + { + writer.WithSubmission(citizenReport.CitizenReportId, answer, attachments, notes); + } + } + } + + public (List header, List> dataTable) Please() + { + foreach (var writer in _answerWriters.Values) + { + _header.AddRange(writer.Header); + } + + for (var index = 0; index < _citizenReports.Count; index++) + { + var submission = _citizenReports[index]; + foreach (var writer in _answerWriters.Values) + { + _dataTable[index].AddRange(writer.Write(submission.CitizenReportId)); + } + } + + return (_header, _dataTable); + } + +} diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/CitizenReports/ExportCitizenReportsJob.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/CitizenReports/ExportCitizenReportsJob.cs new file mode 100644 index 000000000..80492c481 --- /dev/null +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/CitizenReports/ExportCitizenReportsJob.cs @@ -0,0 +1,179 @@ +using Dapper; +using Microsoft.EntityFrameworkCore; +using Vote.Monitor.Core.FileGenerators; +using Vote.Monitor.Core.Services.FileStorage.Contracts; +using Vote.Monitor.Core.Services.Hangfire; +using Vote.Monitor.Core.Services.Time; +using Vote.Monitor.Domain; +using Vote.Monitor.Domain.ConnectionFactory; +using Vote.Monitor.Domain.Entities.ExportedDataAggregate; +using Vote.Monitor.Domain.Entities.FormAggregate; +using Vote.Monitor.Hangfire.Jobs.Export.CitizenReports.ReadModels; + +namespace Vote.Monitor.Hangfire.Jobs.Export.CitizenReports; + +public class ExportCitizenReportsJob( + VoteMonitorContext context, + INpgsqlConnectionFactory dbConnectionFactory, + IFileStorageService fileStorageService, + ILogger logger, + ITimeProvider timeProvider) : IExportCitizenReportsJob +{ + public async Task Run(Guid electionRoundId, Guid ngoId, Guid exportedDataId, CancellationToken ct) + { + var exportedData = await context + .ExportedData + .Where(x => x.ElectionRoundId == electionRoundId && x.Id == exportedDataId) + .FirstOrDefaultAsync(ct); + + if (exportedData == null) + { + logger.LogWarning("ExportData was not found for {electionRoundId} {exportedDataId}", + electionRoundId, exportedDataId); + throw new ExportedDataWasNotFoundException(ExportedDataType.CitizenReports, electionRoundId, + exportedDataId); + } + + try + { + if (exportedData.ExportStatus == ExportedDataStatus.Completed) + { + logger.LogWarning("ExportData was completed for {electionRoundId} {ngoId} {exportedDataId}", + electionRoundId, ngoId, exportedDataId); + return; + } + + var utcNow = timeProvider.UtcNow; + + var citizenReportingForm = await context + .Forms + .Where(x => x.ElectionRoundId == electionRoundId + && x.MonitoringNgo.NgoId == ngoId + && x.Status == FormStatus.Published + && x.FormType == FormType.CitizenReporting + && x.ElectionRound.CitizenReportingEnabled + && x.ElectionRound.MonitoringNgoForCitizenReporting.NgoId == ngoId) + .AsNoTracking() + .ToListAsync(ct); + + var citizenReports = await GetCitizenReports(electionRoundId, ngoId, ct); + + foreach (var attachment in citizenReports.SelectMany(citizenReport => citizenReport.Attachments)) + { + var result = + await fileStorageService.GetPresignedUrlAsync(attachment.FilePath, attachment.UploadedFileName); + + if (result is GetPresignedUrlResult.Ok okResult) + { + attachment.PresignedUrl = okResult.Url; + } + } + + var excelFileGenerator = ExcelFileGenerator.New(); + + for (var index = 0; index < citizenReportingForm.Count; index++) + { + var form = citizenReportingForm[index]; + var sheetData = CitizenReportsDataTable + .FromForm(form) + .WithData() + .For(citizenReports) + .Please(); + + excelFileGenerator.WithSheet((index + 1) + "-" + form.Code, sheetData.header, sheetData.dataTable); + } + + var base64EncodedData = excelFileGenerator.Please(); + var fileName = $"citizen-reports-{utcNow:yyyyMMdd_HHmmss}.xlsx"; + exportedData.Complete(fileName, base64EncodedData, utcNow); + + await context.SaveChangesAsync(ct); + } + catch (Exception e) + { + logger.LogError(e, "An error occured when exporting data"); + exportedData.Fail(); + await context.SaveChangesAsync(ct); + + throw; + } + } + + private async Task GetCitizenReports(Guid electionRoundId, Guid ngoId, CancellationToken ct) + { + var sql = """ + SELECT + CR."Id" AS "CitizenReportId", + CR."FormId", + CR."Answers", + CR."FollowUpStatus", + F."Questions", + L."Level1", + L."Level2", + L."Level3", + L."Level4", + L."Level5", + COALESCE( + ( + SELECT + JSONB_AGG( + JSONB_BUILD_OBJECT( + 'QuestionId', + "QuestionId", + 'FilePath', + "FilePath", + 'UploadedFileName', + "UploadedFileName" + ) + ) + FROM + "CitizenReportAttachments" A + WHERE + A."ElectionRoundId" = @electionRoundId + AND A."FormId" = CR."FormId" + AND A."CitizenReportId" = CR."Id" + ), + '[]'::JSONB + ) AS "Attachments", + COALESCE( + ( + SELECT + JSONB_AGG( + JSONB_BUILD_OBJECT('QuestionId', "QuestionId", 'Text', "Text") + ) + FROM + "CitizenReportNotes" N + WHERE + N."ElectionRoundId" = @electionRoundId + AND N."FormId" = CR."FormId" + AND N."CitizenReportId" = CR."Id" + ), + '[]'::JSONB + ) AS "Notes", + COALESCE(CR."LastModifiedOn", CR."CreatedOn") "TimeSubmitted" + FROM + "CitizenReports" CR + INNER JOIN "Forms" F ON F."Id" = CR."FormId" + INNER JOIN "Locations" L ON L."Id" = CR."LocationId" + INNER JOIN "ElectionRounds" E ON CR."ElectionRoundId" = E."Id" + INNER JOIN "MonitoringNgos" MN ON MN."Id" = E."MonitoringNgoForCitizenReportingId" + WHERE + CR."ElectionRoundId" = @electionRoundId + AND E."CitizenReportingEnabled" = TRUE + AND MN."NgoId" = @ngoId + ORDER BY + "TimeSubmitted" DESC + """; + + var queryParams = new { electionRoundId, ngoId }; + + IEnumerable citizenReports = []; + using (var dbConnection = await dbConnectionFactory.GetOpenConnectionAsync(ct)) + { + citizenReports = await dbConnection.QueryAsync(sql, queryParams); + } + + var citizenReportsData = citizenReports.ToArray(); + return citizenReportsData; + } +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/CitizenReports/ReadModels/CitizenReportModel.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/CitizenReports/ReadModels/CitizenReportModel.cs new file mode 100644 index 000000000..a6399a775 --- /dev/null +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/CitizenReports/ReadModels/CitizenReportModel.cs @@ -0,0 +1,26 @@ +using System.Text.Json.Serialization; +using Ardalis.SmartEnum.SystemTextJson; +using Vote.Monitor.Domain.Entities.CitizenReportAggregate; +using Vote.Monitor.Domain.Entities.FormAnswerBase.Answers; +using Vote.Monitor.Hangfire.Models; + +namespace Vote.Monitor.Hangfire.Jobs.Export.CitizenReports.ReadModels; + +public class CitizenReportModel +{ + public Guid CitizenReportId { get; init; } + + [JsonConverter(typeof(SmartEnumNameConverter))] + public CitizenReportFollowUpStatus FollowUpStatus { get; init; } = CitizenReportFollowUpStatus.NotApplicable; + + public Guid FormId { get; init; } + public DateTime TimeSubmitted { get; init; } + public string Level1 { get; init; } = default!; + public string Level2 { get; init; } = default!; + public string Level3 { get; init; } = default!; + public string Level4 { get; init; } = default!; + public string Level5 { get; init; } = default!; + public BaseAnswer[] Answers { get; init; } = []; + public SubmissionNoteModel[] Notes { get; init; } = []; + public SubmissionAttachmentModel[] Attachments { get; init; } = []; +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ExportFormSubmissionsJob.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ExportFormSubmissionsJob.cs index ee4a60e10..d9fe547e2 100644 --- a/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ExportFormSubmissionsJob.cs +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ExportFormSubmissionsJob.cs @@ -12,7 +12,8 @@ namespace Vote.Monitor.Hangfire.Jobs.Export.FormSubmissions; -public class ExportFormSubmissionsJob(VoteMonitorContext context, +public class ExportFormSubmissionsJob( + VoteMonitorContext context, INpgsqlConnectionFactory dbConnectionFactory, IFileStorageService fileStorageService, ILogger logger, @@ -29,7 +30,8 @@ public async Task Run(Guid electionRoundId, Guid ngoId, Guid exportedDataId, Can { logger.LogWarning("ExportData was not found for {electionRoundId} {exportedDataId}", electionRoundId, exportedDataId); - throw new ExportedDataWasNotFoundException(ExportedDataType.FormSubmissions, electionRoundId, exportedDataId); + throw new ExportedDataWasNotFoundException(ExportedDataType.FormSubmissions, electionRoundId, + exportedDataId); } try @@ -63,7 +65,8 @@ public async Task Run(Guid electionRoundId, Guid ngoId, Guid exportedDataId, Can { foreach (var attachment in submission.Attachments) { - var result = await fileStorageService.GetPresignedUrlAsync(attachment.FilePath, attachment.UploadedFileName); + var result = + await fileStorageService.GetPresignedUrlAsync(attachment.FilePath, attachment.UploadedFileName); if (result is GetPresignedUrlResult.Ok okResult) { @@ -114,90 +117,86 @@ public async Task Run(Guid electionRoundId, Guid ngoId, Guid exportedDataId, Can private async Task> GetSubmissions(Guid electionRoundId, Guid ngoId, CancellationToken ct) { - var sql = @" - WITH submissions AS - (SELECT psi.""Id"" AS ""SubmissionId"", - (select ""Id"" - from ""PollingStationInformationForms"" - where ""ElectionRoundId"" = @electionRoundId) AS ""FormId"", - psi.""PollingStationId"", - psi.""MonitoringObserverId"", - psi.""Answers"", - psi.""FollowUpStatus"", - (select ""Questions"" - from ""PollingStationInformationForms"" - where ""ElectionRoundId"" = @electionRoundId) AS ""Questions"", - '[]'::jsonb AS ""Attachments"", - '[]'::jsonb AS ""Notes"", - COALESCE(psi.""LastModifiedOn"", psi.""CreatedOn"") ""TimeSubmitted"" - FROM ""PollingStationInformation"" psi - INNER JOIN ""MonitoringObservers"" mo ON mo.""Id"" = psi.""MonitoringObserverId"" - INNER JOIN ""MonitoringNgos"" mn ON mn.""Id"" = mo.""MonitoringNgoId"" - WHERE mn.""ElectionRoundId"" = @electionRoundId - AND mn.""NgoId"" = @ngoId - UNION ALL - SELECT - fs.""Id"" AS ""SubmissionId"", - f.""Id"" AS ""FormId"", - fs.""PollingStationId"", - fs.""MonitoringObserverId"", - fs.""Answers"", - fs.""FollowUpStatus"", - f.""Questions"", - - COALESCE((select jsonb_agg(jsonb_build_object('QuestionId', ""QuestionId"", 'FileName', ""FileName"", 'MimeType', ""MimeType"", 'FilePath', ""FilePath"", 'UploadedFileName', ""UploadedFileName"", 'TimeSubmitted', COALESCE(""LastModifiedOn"", ""CreatedOn""))) - FROM ""Attachments"" a - WHERE - a.""ElectionRoundId"" = @electionRoundId - AND a.""FormId"" = fs.""FormId"" - AND a.""MonitoringObserverId"" = fs.""MonitoringObserverId"" - AND fs.""PollingStationId"" = a.""PollingStationId""),'[]'::JSONB) AS ""Attachments"", - - COALESCE((select jsonb_agg(jsonb_build_object('QuestionId', ""QuestionId"", 'Text', ""Text"", 'TimeSubmitted', COALESCE(""LastModifiedOn"", ""CreatedOn""))) - FROM ""Notes"" n - WHERE - n.""ElectionRoundId"" = @electionRoundId - AND n.""FormId"" = fs.""FormId"" - AND n.""MonitoringObserverId"" = fs.""MonitoringObserverId"" - AND fs.""PollingStationId"" = n.""PollingStationId""), '[]'::JSONB) AS ""Notes"", - - COALESCE(fs.""LastModifiedOn"", fs.""CreatedOn"") ""TimeSubmitted"" - - FROM ""FormSubmissions"" fs - INNER JOIN ""MonitoringObservers"" mo ON fs.""MonitoringObserverId"" = mo.""Id"" - INNER JOIN ""MonitoringNgos"" mn ON mn.""Id"" = mo.""MonitoringNgoId"" - INNER JOIN ""Forms"" f on f.""Id"" = fs.""FormId"" - WHERE mn.""ElectionRoundId"" = @electionRoundId - AND mn.""NgoId"" = @ngoId - order by ""TimeSubmitted"" desc) - SELECT s.""SubmissionId"", - s.""FormId"", - s.""TimeSubmitted"", - ps.""Id"" AS ""PollingStationId"", - ps.""Level1"", - ps.""Level2"", - ps.""Level3"", - ps.""Level4"", - ps.""Level5"", - ps.""Number"", - s.""MonitoringObserverId"", - u.""FirstName"", - u.""LastName"", - u.""Email"", - u.""PhoneNumber"", - mo.""Tags"", - s.""Attachments"", - s.""Notes"", - s.""Answers"", - s.""Questions"", - s.""FollowUpStatus"" - FROM submissions s - INNER JOIN ""PollingStations"" ps on ps.""Id"" = s.""PollingStationId"" - INNER JOIN ""MonitoringObservers"" mo on mo.""Id"" = s.""MonitoringObserverId"" - INNER JOIN ""MonitoringNgos"" mn ON mn.""Id"" = mo.""MonitoringNgoId"" - INNER JOIN ""Observers"" o ON o.""Id"" = mo.""ObserverId"" - INNER JOIN ""AspNetUsers"" u ON u.""Id"" = o.""ApplicationUserId"" - WHERE mn.""ElectionRoundId"" = @electionRoundId AND mn.""NgoId"" = @ngoId"; + var sql = """ + WITH submissions AS + (SELECT psi."Id" AS "SubmissionId", + (select "Id" from "PollingStationInformationForms" where "ElectionRoundId" = @electionRoundId) AS "FormId", + psi."PollingStationId", + psi."MonitoringObserverId", + psi."Answers", + psi."FollowUpStatus", + (select "Questions" + from "PollingStationInformationForms" + where "ElectionRoundId" = @electionRoundId) AS "Questions", + '[]'::jsonb AS "Attachments", + '[]'::jsonb AS "Notes", + COALESCE(psi."LastModifiedOn", psi."CreatedOn") "TimeSubmitted" + FROM "PollingStationInformation" psi + INNER JOIN "MonitoringObservers" mo ON mo."Id" = psi."MonitoringObserverId" + INNER JOIN "MonitoringNgos" mn ON mn."Id" = mo."MonitoringNgoId" + WHERE mn."ElectionRoundId" = @electionRoundId + AND mn."NgoId" = @ngoId + UNION ALL + SELECT fs."Id" AS "SubmissionId", + f."Id" AS "FormId", + fs."PollingStationId", + fs."MonitoringObserverId", + fs."Answers", + fs."FollowUpStatus", + f."Questions", + + COALESCE((select jsonb_agg(jsonb_build_object('QuestionId', "QuestionId", 'FilePath', "FilePath", 'UploadedFileName', "UploadedFileName")) + FROM "Attachments" a + WHERE a."ElectionRoundId" = @electionRoundId + AND a."FormId" = fs."FormId" + AND a."MonitoringObserverId" = fs."MonitoringObserverId" + AND fs."PollingStationId" = a."PollingStationId"), '[]'::JSONB) AS "Attachments", + + COALESCE((select jsonb_agg(jsonb_build_object('QuestionId', "QuestionId", 'Text', "Text")) + FROM "Notes" n + WHERE n."ElectionRoundId" = @electionRoundId + AND n."FormId" = fs."FormId" + AND n."MonitoringObserverId" = fs."MonitoringObserverId" + AND fs."PollingStationId" = n."PollingStationId"), '[]'::JSONB) AS "Notes", + + COALESCE(fs."LastModifiedOn", fs."CreatedOn") "TimeSubmitted" + + FROM "FormSubmissions" fs + INNER JOIN "MonitoringObservers" mo ON fs."MonitoringObserverId" = mo."Id" + INNER JOIN "MonitoringNgos" mn ON mn."Id" = mo."MonitoringNgoId" + INNER JOIN "Forms" f on f."Id" = fs."FormId" + WHERE mn."ElectionRoundId" = @electionRoundId + AND mn."NgoId" = @ngoId + order by "TimeSubmitted" desc) + SELECT s."SubmissionId", + s."FormId", + s."TimeSubmitted", + ps."Level1", + ps."Level2", + ps."Level3", + ps."Level4", + ps."Level5", + ps."Number", + s."MonitoringObserverId", + u."FirstName", + u."LastName", + u."Email", + u."PhoneNumber", + mo."Tags", + s."Attachments", + s."Notes", + s."Answers", + s."Questions", + s."FollowUpStatus" + FROM submissions s + INNER JOIN "PollingStations" ps on ps."Id" = s."PollingStationId" + INNER JOIN "MonitoringObservers" mo on mo."Id" = s."MonitoringObserverId" + INNER JOIN "MonitoringNgos" mn ON mn."Id" = mo."MonitoringNgoId" + INNER JOIN "Observers" o ON o."Id" = mo."ObserverId" + INNER JOIN "AspNetUsers" u ON u."Id" = o."ApplicationUserId" + WHERE mn."ElectionRoundId" = @electionRoundId + AND mn."NgoId" = @ngoId + """; var queryParams = new { electionRoundId, ngoId }; @@ -206,7 +205,8 @@ FROM submissions s { submissions = await dbConnection.QueryAsync(sql, queryParams); } + var submissionsData = submissions.ToList(); return submissionsData; } -} +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ReadModels/NoteModel.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ReadModels/NoteModel.cs deleted file mode 100644 index 4c1c7d6ee..000000000 --- a/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ReadModels/NoteModel.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Vote.Monitor.Hangfire.Jobs.Export.FormSubmissions.ReadModels; - -public class NoteModel -{ - public Guid QuestionId { get; init; } - public string Text { get; init; } - public DateTime TimeSubmitted { get; init; } - public Guid MonitoringObserverId { get; set; } -} diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ReadModels/SubmissionAttachmentModel.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ReadModels/SubmissionAttachmentModel.cs deleted file mode 100644 index 75cf4c956..000000000 --- a/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ReadModels/SubmissionAttachmentModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Vote.Monitor.Hangfire.Jobs.Export.FormSubmissions.ReadModels; - -public class SubmissionAttachmentModel -{ - public Guid QuestionId { get; set; } - public Guid MonitoringObserverId { get; set; } - public string FilePath { get; set; } - public string UploadedFileName { get; set; } - public string FileName { get; set; } - public string MimeType { get; set; } - public string PresignedUrl { get; set; } - public int UrlValidityInSeconds { get; set; } - - public DateTime TimeSubmitted { get; init; } -} diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ReadModels/SubmissionModel.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ReadModels/SubmissionModel.cs index 5a33814e7..1bbe0dd10 100644 --- a/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ReadModels/SubmissionModel.cs +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/FormSubmissions/ReadModels/SubmissionModel.cs @@ -2,6 +2,7 @@ using Ardalis.SmartEnum.SystemTextJson; using Vote.Monitor.Domain.Entities.FormAnswerBase.Answers; using Vote.Monitor.Domain.Entities.FormSubmissionAggregate; +using Vote.Monitor.Hangfire.Models; namespace Vote.Monitor.Hangfire.Jobs.Export.FormSubmissions.ReadModels; @@ -13,7 +14,6 @@ public class SubmissionModel public SubmissionFollowUpStatus FollowUpStatus { get; set; } public Guid FormId { get; set; } public DateTime TimeSubmitted { get; init; } - public Guid PollingStationId { get; init; } public string Level1 { get; init; } = default!; public string Level2 { get; init; } = default!; public string Level3 { get; init; } = default!; @@ -26,6 +26,6 @@ public class SubmissionModel public string Email { get; init; } = default!; public string PhoneNumber { get; init; } = default!; public BaseAnswer[] Answers { get; init; } - public NoteModel[] Notes { get; init; } + public SubmissionNoteModel[] Notes { get; init; } public SubmissionAttachmentModel[] Attachments { get; init; } } diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/Locations/ExportLocationsJob.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/Locations/ExportLocationsJob.cs new file mode 100644 index 000000000..814636794 --- /dev/null +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/Locations/ExportLocationsJob.cs @@ -0,0 +1,105 @@ +using Dapper; +using Microsoft.EntityFrameworkCore; +using Vote.Monitor.Core.FileGenerators; +using Vote.Monitor.Core.Services.Hangfire; +using Vote.Monitor.Core.Services.Time; +using Vote.Monitor.Domain; +using Vote.Monitor.Domain.ConnectionFactory; +using Vote.Monitor.Domain.Entities.ExportedDataAggregate; +using Vote.Monitor.Hangfire.Jobs.Export.Locations.ReadModels; + +namespace Vote.Monitor.Hangfire.Jobs.Export.Locations; + +public class ExportLocationsJob( + VoteMonitorContext context, + INpgsqlConnectionFactory dbConnectionFactory, + ILogger logger, + ITimeProvider timeProvider) : IExportLocationsJob +{ + public async Task Run(Guid electionRoundId, Guid exportedDataId, CancellationToken ct) + { + var exportedData = await context + .ExportedData + .Where(x => x.ElectionRoundId == electionRoundId && x.Id == exportedDataId) + .FirstOrDefaultAsync(ct); + + if (exportedData == null) + { + logger.LogWarning("ExportData was not found for {exportDataType} {electionRoundId} {exportedDataId}", + ExportedDataType.Locations, electionRoundId, exportedDataId); + throw new ExportedDataWasNotFoundException(ExportedDataType.Locations, electionRoundId, exportedDataId); + } + + try + { + if (exportedData.ExportStatus == ExportedDataStatus.Completed) + { + logger.LogWarning("ExportData was completed for {electionRoundId} {exportedDataId}", + electionRoundId, exportedDataId); + return; + } + + var utcNow = timeProvider.UtcNow; + + var locations = await GetLocationsAsync(electionRoundId, ct); + + var excelFileGenerator = ExcelFileGenerator.New(); + + var sheetData = LocationsDataTable + .New() + .WithData() + .For(locations) + .Please(); + + excelFileGenerator.WithSheet("locations", sheetData.header, sheetData.dataTable); + + var base64EncodedData = excelFileGenerator.Please(); + var fileName = $"locations-{utcNow:yyyyMMdd_HHmmss}.xlsx"; + exportedData.Complete(fileName, base64EncodedData, utcNow); + + await context.SaveChangesAsync(ct); + } + catch (Exception e) + { + logger.LogError(e, "An error occured when exporting data"); + exportedData.Fail(); + await context.SaveChangesAsync(ct); + + throw; + } + } + + private async Task GetLocationsAsync(Guid electionRoundId, CancellationToken ct) + { + var sql = """ + SELECT + "Id", + "Level1", + "Level2", + "Level3", + "Level4", + "Level5", + "Tags" + FROM + "Locations" + WHERE + "ElectionRoundId" = @electionRoundId + ORDER BY + "DisplayOrder" ASC; + """; + + var queryArgs = new + { + electionRoundId, + }; + + IEnumerable locations; + using (var dbConnection = await dbConnectionFactory.GetOpenConnectionAsync(ct)) + { + locations = await dbConnection.QueryAsync(sql, queryArgs); + } + + var locationsData = locations.ToArray(); + return locationsData; + } +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/Locations/LocationsDataTableGenerator.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/Locations/LocationsDataTableGenerator.cs new file mode 100644 index 000000000..15639d454 --- /dev/null +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/Locations/LocationsDataTableGenerator.cs @@ -0,0 +1,109 @@ +using System.Text.Json; +using Vote.Monitor.Hangfire.Jobs.Export.Locations.ReadModels; + +namespace Vote.Monitor.Hangfire.Jobs.Export.Locations; + +public class LocationsDataTableGenerator +{ + private readonly List _header; + private readonly List> _dataTable; + private readonly List _locations = []; + + private LocationsDataTableGenerator(List header, List> dataTable) + { + _header = header; + _dataTable = dataTable; + } + + internal static LocationsDataTableGenerator For(List header, List> dataTable) + { + return new LocationsDataTableGenerator(header, dataTable); + } + + public LocationsDataTableGenerator For(params LocationModel[] locations) + { + foreach (var location in locations) + { + MapLocation(location); + + var row = new List + { + location.Id.ToString(), + location.Level1, + location.Level2, + location.Level3, + location.Level4, + location.Level5, + location.DisplayOrder + }; + + _dataTable.Add(row); + } + + return this; + } + + private void MapLocation(LocationModel location) + { + LocationData locationData = LocationData.For(location); + + _locations.Add(locationData); + } + + public (List header, List> dataTable) Please() + { + // get the tags + var availableTags = _locations + .SelectMany(x => x.Tags.Keys) + .ToHashSet() + .Order() + .ToList(); + + _header.AddRange(availableTags); + + for (var i = 0; i < _locations.Count; i++) + { + var location = _locations[i]; + var row = _dataTable[i]; + + var tags = WriteTags(location.Tags, availableTags); + + row.AddRange(tags); + } + + return (_header, _dataTable); + } + + private static List WriteTags(Dictionary tags, List availableTags) + { + return availableTags.Select(tag => tags.TryGetValue(tag, out var value) ? value : string.Empty).ToList(); + } + + internal class LocationData + { + public Guid Id { get; } + public readonly Dictionary Tags = new(); + + private LocationData(LocationModel location) + { + Id = location.Id; + } + + public static LocationData For(LocationModel location) + { + var locationData = new LocationData(location); + + locationData.WithTags(location.Tags); + + return locationData; + } + + private void WithTags(JsonDocument tags) + { + foreach (JsonProperty property in tags.RootElement.EnumerateObject()) + { + Tags.Add(property.Name, property.Value.GetString() ?? ""); + } + } + } +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/Locations/PollingStationsDataTable.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/Locations/PollingStationsDataTable.cs new file mode 100644 index 000000000..849b851d4 --- /dev/null +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/Locations/PollingStationsDataTable.cs @@ -0,0 +1,33 @@ +namespace Vote.Monitor.Hangfire.Jobs.Export.Locations; + +public class LocationsDataTable +{ + private readonly List _header; + private readonly List> _dataTable; + + private LocationsDataTable() + { + _header = new List(); + _dataTable = new List>(); + + _header.AddRange([ + "Id", + "Level1", + "Level2", + "Level3", + "Level4", + "Level5", + "DisplayOrder" + ]); + } + + public static LocationsDataTable New() + { + return new LocationsDataTable(); + } + + public LocationsDataTableGenerator WithData() + { + return LocationsDataTableGenerator.For(_header, _dataTable); + } +} diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/Locations/ReadModels/LocationModel.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/Locations/ReadModels/LocationModel.cs new file mode 100644 index 000000000..3c310a0ee --- /dev/null +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/Locations/ReadModels/LocationModel.cs @@ -0,0 +1,15 @@ +using System.Text.Json; + +namespace Vote.Monitor.Hangfire.Jobs.Export.Locations.ReadModels; + +public class LocationModel +{ + public Guid Id { get; set; } + public string Level1 { get; set; } + public string Level2 { get; set; } + public string Level3 { get; set; } + public string Level4 { get; set; } + public string Level5 { get; set; } + public string DisplayOrder { get; set; } + public JsonDocument Tags { get; set; } +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/PollingStations/ExportPollingStationsJob.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/PollingStations/ExportPollingStationsJob.cs index 0c75f9c15..c1a164313 100644 --- a/api/src/Vote.Monitor.Hangfire/Jobs/Export/PollingStations/ExportPollingStationsJob.cs +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/PollingStations/ExportPollingStationsJob.cs @@ -26,8 +26,8 @@ public async Task Run(Guid electionRoundId, Guid exportedDataId, CancellationTok if (exportedData == null) { logger.LogWarning("ExportData was not found for {exportDataType} {electionRoundId} {exportedDataId}", - ExportedDataType.QuickReports, electionRoundId, exportedDataId); - throw new ExportedDataWasNotFoundException(ExportedDataType.QuickReports, electionRoundId, exportedDataId); + ExportedDataType.PollingStations, electionRoundId, exportedDataId); + throw new ExportedDataWasNotFoundException(ExportedDataType.PollingStations, electionRoundId, exportedDataId); } try @@ -41,21 +41,20 @@ public async Task Run(Guid electionRoundId, Guid exportedDataId, CancellationTok var utcNow = timeProvider.UtcNow; - var quickReports = await GetPollingStationsAsync(electionRoundId, ct); - - + var pollingStations = await GetPollingStationsAsync(electionRoundId, ct); + var excelFileGenerator = ExcelFileGenerator.New(); var sheetData = PollingStationsDataTable .New() .WithData() - .ForPollingStations(quickReports) + .ForPollingStations(pollingStations) .Please(); excelFileGenerator.WithSheet("polling-stations", sheetData.header, sheetData.dataTable); var base64EncodedData = excelFileGenerator.Please(); - var fileName = $"quick-reports-{utcNow:yyyyMMdd_HHmmss}.xlsx"; + var fileName = $"polling-stations-{utcNow:yyyyMMdd_HHmmss}.xlsx"; exportedData.Complete(fileName, base64EncodedData, utcNow); await context.SaveChangesAsync(ct); @@ -96,12 +95,12 @@ ORDER BY electionRoundId, }; - IEnumerable pollingStations = []; + IEnumerable pollingStations; using (var dbConnection = await dbConnectionFactory.GetOpenConnectionAsync(ct)) { pollingStations = await dbConnection.QueryAsync(sql, queryArgs); } - var quickReportsData = pollingStations.ToList(); - return quickReportsData; + var pollingStationsData = pollingStations.ToList(); + return pollingStationsData; } } diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/PollingStations/PollingStationsDataTableGenerator.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/PollingStations/PollingStationsDataTableGenerator.cs index d49f459bd..bbbee8801 100644 --- a/api/src/Vote.Monitor.Hangfire/Jobs/Export/PollingStations/PollingStationsDataTableGenerator.cs +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/PollingStations/PollingStationsDataTableGenerator.cs @@ -26,15 +26,15 @@ public PollingStationsDataTableGenerator For(PollingStationModel pollingStation) var row = new List { - pollingStation.Id.ToString(), - pollingStation.Level1, - pollingStation.Level2, - pollingStation.Level3, - pollingStation.Level4, - pollingStation.Level5, - pollingStation.Number, - pollingStation.Address, - pollingStation.DisplayOrder + pollingStation.Id.ToString(), + pollingStation.Level1, + pollingStation.Level2, + pollingStation.Level3, + pollingStation.Level4, + pollingStation.Level5, + pollingStation.Number, + pollingStation.Address, + pollingStation.DisplayOrder }; _dataTable.Add(row); @@ -51,9 +51,9 @@ public PollingStationsDataTableGenerator ForPollingStations(List Tags = new(); - private PollingStationData(PollingStationModel quickReport) + private PollingStationData(PollingStationModel pollingStation) { - Id = quickReport.Id; + Id = pollingStation.Id; } public static PollingStationData For(PollingStationModel pollingStation) @@ -114,4 +114,4 @@ private void WithTags(JsonDocument tags) } } } -} +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/QuickReports/QuickReportsDataTable.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/QuickReports/QuickReportsDataTable.cs index 0da992367..ec1071940 100644 --- a/api/src/Vote.Monitor.Hangfire/Jobs/Export/QuickReports/QuickReportsDataTable.cs +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/QuickReports/QuickReportsDataTable.cs @@ -20,7 +20,6 @@ private QuickReportsDataTable() "Email", "PhoneNumber", "LocationType", - "PollingStationId", "Level1", "Level2", "Level3", diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/QuickReports/QuickReportsDataTableGenerator.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/QuickReports/QuickReportsDataTableGenerator.cs index f31736dbf..e66eb8bd6 100644 --- a/api/src/Vote.Monitor.Hangfire/Jobs/Export/QuickReports/QuickReportsDataTableGenerator.cs +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/QuickReports/QuickReportsDataTableGenerator.cs @@ -34,7 +34,6 @@ public QuickReportsDataTableGenerator For(QuickReportModel quickReport) quickReport.Email, quickReport.PhoneNumber, quickReport.QuickReportLocationType.Value, - quickReport.PollingStationId?.ToString() ?? "", quickReport.Level1 ?? "", quickReport.Level2 ?? "", quickReport.Level3 ?? "", diff --git a/api/src/Vote.Monitor.Hangfire/Jobs/Export/QuickReports/ReadModels/QuickReportModel.cs b/api/src/Vote.Monitor.Hangfire/Jobs/Export/QuickReports/ReadModels/QuickReportModel.cs index 5025639f1..d80fad884 100644 --- a/api/src/Vote.Monitor.Hangfire/Jobs/Export/QuickReports/ReadModels/QuickReportModel.cs +++ b/api/src/Vote.Monitor.Hangfire/Jobs/Export/QuickReports/ReadModels/QuickReportModel.cs @@ -19,7 +19,6 @@ public class QuickReportModel public string Email { get; set; } public string PhoneNumber { get; set; } public string? PollingStationDetails { get; set; } - public Guid? PollingStationId { get; set; } public string? Level1 { get; set; } public string? Level2 { get; set; } public string? Level3 { get; set; } diff --git a/api/src/Vote.Monitor.Hangfire/Models/SubmissionAttachmentModel.cs b/api/src/Vote.Monitor.Hangfire/Models/SubmissionAttachmentModel.cs new file mode 100644 index 000000000..cafed80a7 --- /dev/null +++ b/api/src/Vote.Monitor.Hangfire/Models/SubmissionAttachmentModel.cs @@ -0,0 +1,9 @@ +namespace Vote.Monitor.Hangfire.Models; + +public class SubmissionAttachmentModel +{ + public Guid QuestionId { get; set; } + public string FilePath { get; set; } + public string UploadedFileName { get; set; } + public string PresignedUrl { get; set; } +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Hangfire/Models/SubmissionNoteModel.cs b/api/src/Vote.Monitor.Hangfire/Models/SubmissionNoteModel.cs new file mode 100644 index 000000000..453c20c4c --- /dev/null +++ b/api/src/Vote.Monitor.Hangfire/Models/SubmissionNoteModel.cs @@ -0,0 +1,7 @@ +namespace Vote.Monitor.Hangfire.Models; + +public class SubmissionNoteModel +{ + public Guid QuestionId { get; init; } + public string Text { get; init; } +} \ No newline at end of file diff --git a/api/src/Vote.Monitor.Hangfire/Program.cs b/api/src/Vote.Monitor.Hangfire/Program.cs index e055efac8..de25f04b2 100644 --- a/api/src/Vote.Monitor.Hangfire/Program.cs +++ b/api/src/Vote.Monitor.Hangfire/Program.cs @@ -32,11 +32,14 @@ using Vote.Monitor.Domain.Entities.NgoAggregate; using Vote.Monitor.Domain.Entities.QuickReportAggregate; using Ardalis.SmartEnum.Dapper; +using Vote.Monitor.Hangfire.Jobs.Export.CitizenReports; using Vote.Monitor.Hangfire.Jobs.Export.FormSubmissions; using Vote.Monitor.Hangfire.Jobs.Export.FormSubmissions.ReadModels; +using Vote.Monitor.Hangfire.Jobs.Export.Locations; using Vote.Monitor.Hangfire.Jobs.Export.PollingStations; using Vote.Monitor.Hangfire.Jobs.Export.QuickReports; using Vote.Monitor.Hangfire.Jobs.Export.QuickReports.ReadModels; +using Vote.Monitor.Hangfire.Models; var builder = WebApplication.CreateBuilder(args); builder.Services.AddOptions(); @@ -61,7 +64,7 @@ SqlMapper.AddTypeHandler(typeof(BaseQuestion[]), new JsonToObjectConverter()); SqlMapper.AddTypeHandler(typeof(BaseAnswer[]), new JsonToObjectConverter()); -SqlMapper.AddTypeHandler(typeof(NoteModel[]), new JsonToObjectConverter()); +SqlMapper.AddTypeHandler(typeof(SubmissionNoteModel[]), new JsonToObjectConverter()); SqlMapper.AddTypeHandler(typeof(SubmissionAttachmentModel[]), new JsonToObjectConverter()); SqlMapper.AddTypeHandler(typeof(QuickReportAttachmentModel[]), new JsonToObjectConverter()); SqlMapper.AddTypeHandler(typeof(JsonDocument), new JsonToObjectConverter()); @@ -112,6 +115,8 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); #endregion var dbConnectionString = builder.Configuration.GetNpgsqlConnectionString("Core:HangfireConnectionConfig"); diff --git a/api/tests/Feature.CitizenReports.UnitTests/Endpoints/UpsertEndpointTests.cs b/api/tests/Feature.CitizenReports.UnitTests/Endpoints/UpsertEndpointTests.cs index 3150baf80..281d0a9b9 100644 --- a/api/tests/Feature.CitizenReports.UnitTests/Endpoints/UpsertEndpointTests.cs +++ b/api/tests/Feature.CitizenReports.UnitTests/Endpoints/UpsertEndpointTests.cs @@ -2,12 +2,14 @@ using Feature.CitizenReports.Specifications; using Feature.CitizenReports.Upsert; using Vote.Monitor.Domain.Entities.CitizenReportAggregate; +using Vote.Monitor.Domain.Entities.LocationAggregate; namespace Feature.CitizenReports.UnitTests.Endpoints; public class UpsertEndpointTests { private readonly IRepository _repository; + private readonly IReadRepository _locationsRepository; private readonly IReadRepository _formRepository; private readonly Endpoint _endpoint; @@ -16,14 +18,43 @@ public UpsertEndpointTests() { _repository = Substitute.For>(); _formRepository = Substitute.For>(); + _locationsRepository = Substitute.For>(); - _endpoint = Factory.Create(_repository, _formRepository); + _endpoint = Factory.Create(_repository, _locationsRepository, _formRepository); } [Fact] - public async Task ShouldReturnNotFound_WhenFormSubmissionFormNotFound() + public async Task ShouldReturnNotFound_WhenLocationNotFound() { // Arrange + _locationsRepository + .FirstOrDefaultAsync(Arg.Any()) + .ReturnsNull(); + + // Act + var request = new Request + { + ElectionRoundId = Guid.NewGuid(), + CitizenReportId = Guid.NewGuid(), + }; + + var result = await _endpoint.ExecuteAsync(request, default); + + // Assert + result + .Should().BeOfType, NotFound>>() + .Which + .Result.Should().BeOfType(); + } + + [Fact] + public async Task ShouldReturnNotFound_WhenFormNotFound() + { + // Arrange + _locationsRepository + .FirstOrDefaultAsync(Arg.Any()) + .Returns(new LocationAggregateFaker()); + _formRepository .FirstOrDefaultAsync(Arg.Any()) .ReturnsNull(); @@ -48,6 +79,11 @@ public async Task ShouldReturnNotFound_WhenFormSubmissionFormNotFound() public async Task ShouldUpdateFormSubmission_WhenFormSubmissionExists() { // Arrange + var location = new LocationAggregateFaker().Generate(); + _locationsRepository + .FirstOrDefaultAsync(Arg.Any()) + .Returns(location); + var form = new FormAggregateFaker().Generate(); _formRepository .FirstOrDefaultAsync(Arg.Any()) @@ -63,6 +99,7 @@ public async Task ShouldUpdateFormSubmission_WhenFormSubmissionExists() { ElectionRoundId = Guid.NewGuid(), CitizenReportId = Guid.NewGuid(), + LocationId = Guid.NewGuid(), Answers = [ new NumberAnswerRequest @@ -83,17 +120,22 @@ public async Task ShouldUpdateFormSubmission_WhenFormSubmissionExists() .Which .Result.Should().BeOfType>(); } - - + [Fact] public async Task ShouldThrow_WhenInvalidAnswersReceived() { // Arrange var electionRoundId = Guid.NewGuid(); var citizenReportId = Guid.NewGuid(); + var locationId = Guid.NewGuid(); var electionRound = new ElectionRoundAggregateFaker(electionRoundId).Generate(); + var location = new LocationAggregateFaker(electionRound, id: locationId).Generate(); + _locationsRepository + .FirstOrDefaultAsync(Arg.Any()) + .Returns(location); + var formSubmission = new FormAggregateFaker(electionRound: electionRound).Generate(); _formRepository .FirstOrDefaultAsync(Arg.Any()) @@ -106,6 +148,7 @@ public async Task ShouldThrow_WhenInvalidAnswersReceived() { ElectionRoundId = electionRoundId, CitizenReportId = citizenReportId, + LocationId = locationId, Answers = [ new NumberAnswerRequest @@ -130,9 +173,15 @@ public async Task ShouldCreateFormSubmission_WhenNotExists() // Arrange var electionRoundId = Guid.NewGuid(); var citizenReportId = Guid.NewGuid(); + var locationId = Guid.NewGuid(); var electionRound = new ElectionRoundAggregateFaker(electionRoundId).Generate(); + var location = new LocationAggregateFaker(electionRound, id: locationId).Generate(); + _locationsRepository + .FirstOrDefaultAsync(Arg.Any()) + .Returns(location); + var form = new FormAggregateFaker(electionRound).Generate(); _formRepository .FirstOrDefaultAsync(Arg.Any()) @@ -147,6 +196,7 @@ public async Task ShouldCreateFormSubmission_WhenNotExists() { ElectionRoundId = electionRoundId, CitizenReportId = citizenReportId, + LocationId = locationId, Answers = [ new NumberAnswerRequest @@ -164,7 +214,7 @@ public async Task ShouldCreateFormSubmission_WhenNotExists() await _repository .Received(1) .AddAsync(Arg.Is(x => x.ElectionRoundId == electionRoundId - && x.Id == citizenReportId)); + && x.Id == citizenReportId && x.LocationId == locationId)); result .Should().BeOfType, NotFound>>() diff --git a/api/tests/Feature.CitizenReports.UnitTests/ValidatorTests/UpsertValidatorTests.cs b/api/tests/Feature.CitizenReports.UnitTests/ValidatorTests/UpsertValidatorTests.cs index b60d3f7fa..986927a3f 100644 --- a/api/tests/Feature.CitizenReports.UnitTests/ValidatorTests/UpsertValidatorTests.cs +++ b/api/tests/Feature.CitizenReports.UnitTests/ValidatorTests/UpsertValidatorTests.cs @@ -31,6 +31,19 @@ public void Validation_ShouldFail_When_PollingStationId_Empty() result.ShouldHaveValidationErrorFor(x => x.CitizenReportId); } + [Fact] + public void Validation_ShouldFail_When_LocationId_Empty() + { + // Arrange + var request = new Upsert.Request { LocationId = Guid.Empty }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.LocationId); + } + [Fact] public void Validation_ShouldFail_When_FormId_Empty() { @@ -82,6 +95,7 @@ public void Validation_ShouldPass_When_ValidRequest() FormId = Guid.NewGuid(), ElectionRoundId = Guid.NewGuid(), CitizenReportId = Guid.NewGuid(), + LocationId = Guid.NewGuid(), }; // Act @@ -100,6 +114,7 @@ public void Validation_ShouldPass_When_Answers_Empty() FormId = Guid.NewGuid(), ElectionRoundId = Guid.NewGuid(), CitizenReportId = Guid.NewGuid(), + LocationId = Guid.NewGuid(), Answers = [] }; @@ -119,6 +134,7 @@ public void Validation_ShouldPass_When_Answers_Null() FormId = Guid.NewGuid(), ElectionRoundId = Guid.NewGuid(), CitizenReportId = Guid.NewGuid(), + LocationId = Guid.NewGuid(), Answers = null }; diff --git a/api/tests/Feature.Locations.UnitTests/Feature.Locations.UnitTests.csproj b/api/tests/Feature.Locations.UnitTests/Feature.Locations.UnitTests.csproj new file mode 100644 index 000000000..c2b83b5a0 --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/Feature.Locations.UnitTests.csproj @@ -0,0 +1,32 @@ + + + + net8.0 + enable + enable + false + true + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + diff --git a/api/tests/Feature.Locations.UnitTests/GlobalUsings.cs b/api/tests/Feature.Locations.UnitTests/GlobalUsings.cs new file mode 100644 index 000000000..1ba184012 --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/GlobalUsings.cs @@ -0,0 +1,17 @@ +// Global using directives + +global using System.Text.Json; +global using Bogus; +global using FluentAssertions; +global using FluentValidation; +global using FluentValidation.TestHelper; +global using Microsoft.Extensions.Logging.Abstractions; +global using Microsoft.Extensions.Options; +global using NSubstitute; +global using Vote.Monitor.Core.Services.Csv; +global using Feature.Locations.Options; +global using Feature.Locations.Services; +global using Feature.Locations.Specifications; +global using Vote.Monitor.TestUtils; +global using Xunit; +global using LocationAggregate = Vote.Monitor.Domain.Entities.LocationAggregate.Location; diff --git a/api/tests/Feature.Locations.UnitTests/ServicesTests/LocationParserTests.cs b/api/tests/Feature.Locations.UnitTests/ServicesTests/LocationParserTests.cs new file mode 100644 index 000000000..6f136f627 --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/ServicesTests/LocationParserTests.cs @@ -0,0 +1,197 @@ +using Vote.Monitor.Core.Models; +using Vote.Monitor.TestUtils.Utils; + +namespace Feature.Locations.UnitTests.ServicesTests; + +public class LocationParserTests +{ + private readonly IOptions _parserConfig = new LocationParserConfig() + { + MaxParserErrorsReturned = 10 + }.AsIOption(); + + private readonly Faker _faker = new(); + + [Fact] + public void Parsing_ShouldFail_When_Invalid_Data() + { + // Arrange + var reader = Substitute.For>(); + var parsedRows = new LocationImportModel().Repeat(1); + + reader + .Read(Arg.Any()) + .Returns(parsedRows); + + var sut = new LocationParser(reader, NullLogger.Instance, _parserConfig); + + // Act + var result = sut.Parse(new MemoryStream()); + + // Assert + result.Should().BeOfType() + .Which.ValidationErrors + .Should().HaveCount(1) + .And + .Subject.First().Errors.Should().HaveCount(1); + } + + [Fact] + public void Parsing_ShouldFail_AndRespectMaxErrorConfig_When_Invalid_Data() + { + // Arrange + var reader = Substitute.For>(); + var parsedRows = new LocationImportModel().Repeat(121); + reader + .Read(Arg.Any()) + .Returns(parsedRows); + + var sut = new LocationParser(reader, NullLogger.Instance, _parserConfig); + + // Act + var result = sut.Parse(new MemoryStream()); + + // Assert + result.Should().BeOfType() + .Which.ValidationErrors + .Should().HaveCount(10); + } + + [Fact] + public void Parsing_ShouldSucceed_When_ValidData() + { + // Arrange + var reader = Substitute.For>(); + var parsedRows = Enumerable.Range(1, 100) + .Select(_ => new LocationImportModel + { + Level1 = "Level1", + Level2 = "Level2", + Level3 = "Level3", + Level4 = "Level4", + Level5 = "Level5", + DisplayOrder = _faker.Random.Int(0, 100), + Tags = new List + { + new() { Name = "Tag1", Value = "value1" }, + new() { Name = "Tag2", Value = "value2" } + } + }).ToList(); + + reader + .Read(Arg.Any()) + .Returns(parsedRows); + + var sut = new LocationParser(reader, NullLogger.Instance, _parserConfig); + + // Act + var result = sut.Parse(new MemoryStream()); + + // Assert + result.Should().BeOfType() + .Which.Locations + .Should().HaveCount(100) + .And.Subject.Should().BeEquivalentTo(parsedRows); + } + + [Fact] + public void Parsing_ShouldSucceed_When_ValidCsv() + { + // Arrange + var reader = new CsvReader(); + var sut = new LocationParser(reader, NullLogger.Instance, _parserConfig); + + var csvData = "Level1,Level2,Level3,Level4,Level5,DisplayOrder,Tag1,Tag2\n" + + "Level1,Level2,Level3,Level4,Level5,1,TagA,TagB\n" + + "Level1,Level2,Level3,Level4,Level5,2,TagC,TagD\n" + + "Level1,Level2,Level3,Level4,Level5,3,TagE,TagF"; + using var stream = new MemoryStream(); + using var writer = new StreamWriter(stream); + writer.Write(csvData); + writer.Flush(); + stream.Position = 0; + + // Act + var result = sut.Parse(stream); + + // Assert + result.Should().BeOfType() + .Which.Locations + .Should().HaveCount(3); + + result.Should().BeOfType() + .Which.Locations[0] + .Should().BeEquivalentTo(new LocationImportModel + { + Level1 = "Level1", + Level2 = "Level2", + Level3 = "Level3", + Level4 = "Level4", + Level5 = "Level5", + DisplayOrder = 1, + Tags = new List + { + new() + { + Name = "Tag1", + Value = "TagA" + }, + new() + { + Name = "Tag2", + Value = "TagB" + } + } + }); + + result.Should().BeOfType() + .Which.Locations[1] + .Should().BeEquivalentTo(new LocationImportModel + { + Level1 = "Level1", + Level2 = "Level2", + Level3 = "Level3", + Level4 = "Level4", + Level5 = "Level5", + DisplayOrder = 2, + Tags = new List + { + new() + { + Name = "Tag1", + Value = "TagC" + }, + new() + { + Name = "Tag2", + Value = "TagD" + } + } + }); + + result.Should().BeOfType() + .Which.Locations[2] + .Should().BeEquivalentTo(new LocationImportModel + { + Level1 = "Level1", + Level2 = "Level2", + Level3 = "Level3", + Level4 = "Level4", + Level5 = "Level5", + DisplayOrder = 3, + Tags = new List + { + new() + { + Name = "Tag1", + Value = "TagE" + }, + new() + { + Name = "Tag2", + Value = "TagF" + } + } + }); + } +} \ No newline at end of file diff --git a/api/tests/Feature.Locations.UnitTests/Specifications/GetLocationByIdSpecificationTests.cs b/api/tests/Feature.Locations.UnitTests/Specifications/GetLocationByIdSpecificationTests.cs new file mode 100644 index 000000000..d26103ae7 --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/Specifications/GetLocationByIdSpecificationTests.cs @@ -0,0 +1,29 @@ +using Vote.Monitor.TestUtils.Fakes.Aggregates; + +namespace Feature.Locations.UnitTests.Specifications; + +public class GetLocationByIdSpecificationTests +{ + [Fact] + public void GetLocationByIdSpecification_AppliesCorrectFilters() + { + // Arrange + var electionRound = new ElectionRoundAggregateFaker().Generate(); + var location = new LocationAggregateFaker(id: Guid.NewGuid(), electionRound: electionRound).Generate(); + + var testCollection = new LocationAggregateFaker(electionRound: electionRound) + .Generate(500) + .Union(new[] { location }) + .Union(new LocationAggregateFaker(id: location.Id).Generate(500)) + .ToList(); + + var spec = new GetLocationByIdSpecification(location.ElectionRoundId, location.Id); + + // Act + var result = spec.Evaluate(testCollection).ToList(); + + // Assert + result.Should().HaveCount(1); + result.Should().Contain(location); + } +} diff --git a/api/tests/Feature.Locations.UnitTests/Specifications/GetLocationSpecificationTests.cs b/api/tests/Feature.Locations.UnitTests/Specifications/GetLocationSpecificationTests.cs new file mode 100644 index 000000000..8cf98888e --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/Specifications/GetLocationSpecificationTests.cs @@ -0,0 +1,30 @@ +using Vote.Monitor.TestUtils.Fakes.Aggregates; + +namespace Feature.Locations.UnitTests.Specifications; + +public class GetLocationSpecificationTests +{ + [Fact] + public void GetLocationSpecification_AppliesCorrectFilters() + { + // Arrange + var electionRound = new ElectionRoundAggregateFaker().Generate(); + var location = new LocationAggregateFaker(electionRound: electionRound).Generate(); + + var testCollection = new LocationAggregateFaker(electionRound: electionRound) + .Generate(500) + .Union(new[] { location }) + .Union(new LocationAggregateFaker(electionRound: electionRound).Generate(500)) + .ToList(); + + var spec = new GetLocationSpecification(electionRound.Id, location.Level1, location.Level2, location.Level3, + location.Level4, location.Level5); + + // Act + var result = spec.Evaluate(testCollection).ToList(); + + // Assert + result.Should().HaveCount(1); + result.Should().Contain(location); + } +} diff --git a/api/tests/Feature.Locations.UnitTests/Specifications/ListLocationsSpecificationTests.cs b/api/tests/Feature.Locations.UnitTests/Specifications/ListLocationsSpecificationTests.cs new file mode 100644 index 000000000..ceb51c5be --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/Specifications/ListLocationsSpecificationTests.cs @@ -0,0 +1,169 @@ +using Feature.Locations.List; +using Vote.Monitor.Core.Models; +using Vote.Monitor.TestUtils.Fakes.Aggregates; + +namespace Feature.Locations.UnitTests.Specifications; + +public class ListLocationsSpecificationTests +{ + [Fact] + public void ListLocationSpecification_AppliesCorrectFilters() + { + // Arrange + var electionRound = new ElectionRoundAggregateFaker().Generate(); + var location1 = new LocationAggregateFaker(electionRound: electionRound, displayOrder: 101).Generate(); + var location2 = new LocationAggregateFaker(electionRound: electionRound, displayOrder: 102).Generate(); + + var testCollection = Enumerable.Range(1, 100) + .Select(displayOrder => + new LocationAggregateFaker(electionRound: electionRound, displayOrder: displayOrder).Generate()) + .Union(new[] { location1, location2 }) + .ToList(); + + var request = new Request + { + ElectionRoundId = electionRound.Id, + PageSize = 100, + PageNumber = 2 + }; + + var spec = new ListLocationsSpecification(request); + + // Act + var result = spec.Evaluate(testCollection).ToList(); + + // Assert + result.Should().HaveCount(2); + result.Should().Contain(location1); + result.Should().Contain(location2); + } + + [Fact] + public void ListLocationsSpecification_AppliesCorrectFilters_WhenAddressFilterApplied() + { + // Arrange + var electionRound = new ElectionRoundAggregateFaker().Generate(); + var location1 = + new LocationAggregateFaker(electionRound: electionRound, displayOrder: 101) + .Generate(); + var location2 = + new LocationAggregateFaker(electionRound: electionRound, displayOrder: 102) + .Generate(); + + var testCollection = Enumerable + .Range(1, 100) + .Select(displayOrder => + new LocationAggregateFaker(electionRound: electionRound, displayOrder: displayOrder).Generate()) + .Union(new[] { location1, location2 }) + .ToList(); + + var request = new Request + { + ElectionRoundId = electionRound.Id, + PageSize = 100, + PageNumber = 2 + }; + var spec = new ListLocationsSpecification(request); + + // Act + var result = spec.Evaluate(testCollection).ToList(); + + // Assert + result.Should().HaveCount(2); + result.Should().Contain(location1); + result.Should().Contain(location2); + } + + [Theory] + [InlineData("Fluwelen Burgwal 58")] + [InlineData("2511 CJ Den Haag")] + public void ListPollingStationsSpecification_AppliesCorrectFilters_WhenPartialAddressFilterApplied( + string searchString) + { + // Arrange + var electionRound = new ElectionRoundAggregateFaker().Generate(); + var pollingStation1 = + new LocationAggregateFaker(electionRound: electionRound, displayOrder: 101) + .Generate(); + var pollingStation2 = + new LocationAggregateFaker(electionRound: electionRound, displayOrder: 102) + .Generate(); + + var testCollection = Enumerable + .Range(1, 100) + .Select(displayOrder => + new LocationAggregateFaker(electionRound: electionRound, displayOrder: displayOrder).Generate()) + .Union(new[] { pollingStation1, pollingStation2 }) + .ToList(); + + var request = new Request + { + ElectionRoundId = electionRound.Id, + PageSize = 100, + PageNumber = 2 + }; + + var spec = new ListLocationsSpecification(request); + + // Act + var result = spec.Evaluate(testCollection).ToList(); + + // Assert + result.Should().HaveCount(2); + result.Should().Contain(pollingStation1); + result.Should().Contain(pollingStation2); + } + + + [Theory] + [MemberData(nameof(SortingTestCases))] + public void ListPollingStationsSpecification_AppliesSortingCorrectly(string columnName, SortOrder? sortOrder) + { + // Arrange + var electionRound = new ElectionRoundAggregateFaker().Generate(); + var pollingStation1 = + new LocationAggregateFaker(electionRound: electionRound, displayOrder: 102) + .Generate(); + var pollingStation2 = + new LocationAggregateFaker(electionRound: electionRound, displayOrder: 103) + .Generate(); + + var testCollection = Enumerable + .Range(1, 100) + .Select(displayOrder => + new LocationAggregateFaker(electionRound: electionRound, displayOrder: displayOrder).Generate()) + .Union(new[] { pollingStation1, pollingStation2 }) + .Reverse() + .ToList(); + + var request = new Request + { + ElectionRoundId = electionRound.Id, + SortOrder = sortOrder, + SortColumnName = columnName, + PageSize = 100, + PageNumber = 2 + }; + + var spec = new ListLocationsSpecification(request); + + // Act + var result = spec.Evaluate(testCollection).ToList(); + + // Assert + result.Should().HaveCount(2); + result.Should().Contain(pollingStation1); + result.Should().Contain(pollingStation2); + } + + public static IEnumerable SortingTestCases => + new List + { + new object[] { "name", null }, + new object[] { "Name", null }, + new object[] { "displayOrder", null }, + new object[] { "name", SortOrder.Asc }, + new object[] { "Name", SortOrder.Asc }, + new object[] { "DisplayOrder", SortOrder.Asc } + }; +} \ No newline at end of file diff --git a/api/tests/Feature.Locations.UnitTests/ValidatorTests/CreateRequestValidatorTests.cs b/api/tests/Feature.Locations.UnitTests/ValidatorTests/CreateRequestValidatorTests.cs new file mode 100644 index 000000000..77de5f709 --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/ValidatorTests/CreateRequestValidatorTests.cs @@ -0,0 +1,36 @@ +namespace Feature.Locations.UnitTests.ValidatorTests; + +public class CreateRequestValidatorTests +{ + private readonly Create.Validator _validator = new(); + + [Fact] + public void Validation_ShouldFail_When_ElectionRoundIdEmpty() + { + // Arrange + var request = new Create.Request + { + ElectionRoundId = Guid.Empty + }; + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.ElectionRoundId); + } + + [Fact] + public void Validation_ShouldFail_When_DisplayOrder_LessThanZero() + { + // Arrange + var request = new Create.Request + { + DisplayOrder = -1 + }; + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.DisplayOrder); + } +} \ No newline at end of file diff --git a/api/tests/Feature.Locations.UnitTests/ValidatorTests/DeleteRequestValidatorTests.cs b/api/tests/Feature.Locations.UnitTests/ValidatorTests/DeleteRequestValidatorTests.cs new file mode 100644 index 000000000..19db9e233 --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/ValidatorTests/DeleteRequestValidatorTests.cs @@ -0,0 +1,57 @@ +namespace Feature.Locations.UnitTests.ValidatorTests; + +public class DeleteRequestValidatorTests +{ + private readonly Delete.Validator _validator = new(); + + [Fact] + public void Validation_ShouldFail_When_ElectionRoundId_Empty() + { + // Arrange + var request = new Delete.Request + { + ElectionRoundId = Guid.Empty, + Id = Guid.NewGuid() + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.ElectionRoundId); + } + + [Fact] + public void Validation_ShouldFail_When_Id_Empty() + { + // Arrange + var request = new Delete.Request + { + Id = Guid.Empty, + ElectionRoundId = Guid.NewGuid() + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.Id); + } + + [Fact] + public void Validation_ShouldPass_WhenValidRequest() + { + // Arrange + var request = new Delete.Request + { + Id = Guid.NewGuid(), + ElectionRoundId = Guid.NewGuid() + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldNotHaveAnyValidationErrors(); + } +} diff --git a/api/tests/Feature.Locations.UnitTests/ValidatorTests/GetRequestValidatorTests.cs b/api/tests/Feature.Locations.UnitTests/ValidatorTests/GetRequestValidatorTests.cs new file mode 100644 index 000000000..2136a66f0 --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/ValidatorTests/GetRequestValidatorTests.cs @@ -0,0 +1,55 @@ +namespace Feature.Locations.UnitTests.ValidatorTests; + +public class GetRequestValidatorTests +{ + private readonly Get.Validator _validator = new(); + + [Fact] + public void Validation_ShouldFail_When_ElectionRoundId_Empty() + { + // Arrange + var request = new Get.Request + { + ElectionRoundId = Guid.Empty + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.ElectionRoundId); + } + + [Fact] + public void Validation_ShouldFail_When_Id_Empty() + { + // Arrange + var request = new Get.Request + { + Id = Guid.Empty, + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.Id); + } + + [Fact] + public void Validation_ShouldPass_When_ValidRequest() + { + // Arrange + var request = new Get.Request + { + Id = Guid.NewGuid(), + ElectionRoundId = Guid.NewGuid() + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldNotHaveAnyValidationErrors(); + } +} diff --git a/api/tests/Feature.Locations.UnitTests/ValidatorTests/ImportRequestValidatorTests.cs b/api/tests/Feature.Locations.UnitTests/ValidatorTests/ImportRequestValidatorTests.cs new file mode 100644 index 000000000..c1b9cafac --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/ValidatorTests/ImportRequestValidatorTests.cs @@ -0,0 +1,113 @@ +using Vote.Monitor.TestUtils.Fakes; + +namespace Feature.Locations.UnitTests.ValidatorTests; + +public class ImportRequestValidatorTests +{ + private readonly Import.Validator _validator = new(); + + [Fact] + public void Validation_ShouldPass_When_File_NotEmpty() + { + // Arrange + var formFile = FakeFormFile.New() + .HavingFileName("file.csv") + .HavingLength(123) + .Please(); + + var request = new Import.Request + { + ElectionRoundId = Guid.NewGuid(), + File = formFile + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldNotHaveValidationErrorFor(x => x.File); + } + + [Fact] + public void Validation_ShouldFail_When_File_Empty() + { + // Arrange + var request = new Import.Request + { + ElectionRoundId = Guid.NewGuid(), + File = null + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.File); + } + + [Fact] + public void Validation_ShouldPass_When_FileSize_Valid() + { + // Arrange + var formFile = FakeFormFile.New() + .HavingFileName("file.csv") + .HavingLength(25 * 1024 * 1024 - 1) + .Please(); + + var request = new Import.Request + { + ElectionRoundId = Guid.NewGuid(), + File = formFile + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldNotHaveValidationErrorFor(x => x.File); + } + + + [Fact] + public void Validation_ShouldPass_When_FileExtension_Valid() + { + // Arrange + var formFile = FakeFormFile.New() + .HavingFileName("file.csv") + .HavingLength(123) + .Please(); + + var request = new Import.Request + { + ElectionRoundId = Guid.NewGuid(), + File = formFile }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldNotHaveValidationErrorFor(x => x.File); + } + + [Fact] + public void Validation_ShouldFail_When_FileExtension_Invalid() + { + // Arrange + var formFile = FakeFormFile.New() + .HavingFileName("file.txt") + .HavingLength(123) + .Please(); + + var request = new Import.Request + { + ElectionRoundId = Guid.NewGuid(), + File = formFile }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.File) + .WithErrorMessage("Only CSV files are accepted."); + } +} diff --git a/api/tests/Feature.Locations.UnitTests/ValidatorTests/ListRequestValidatorTests.cs b/api/tests/Feature.Locations.UnitTests/ValidatorTests/ListRequestValidatorTests.cs new file mode 100644 index 000000000..3d7d26356 --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/ValidatorTests/ListRequestValidatorTests.cs @@ -0,0 +1,89 @@ +namespace Feature.Locations.UnitTests.ValidatorTests; + +public class ListRequestValidatorTests +{ + private readonly List.Validator _validator = new(); + + [Theory] + [InlineData(1)] + [InlineData(50)] + [InlineData(100)] + public void Validation_ShouldPass_When_PageSize_ValidValues(int pageSize) + { + // Arrange + var request = new List.Request + { + ElectionRoundId = Guid.NewGuid(), + PageSize = pageSize, + PageNumber = 1, + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldNotHaveValidationErrorFor(x => x.PageSize); + } + + [Theory] + [InlineData(0)] + [InlineData(101)] + [InlineData(-5)] + public void Validation_ShouldFail_When_PageSize_InvalidValues(int pageSize) + { + // Arrange + var request = new List.Request + { + ElectionRoundId = Guid.NewGuid(), + PageSize = pageSize, + PageNumber = 1, + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.PageSize); + } + + [Theory] + [InlineData(1)] + [InlineData(10)] + [InlineData(100)] + public void Validation_ShouldPass_When_PageNumber_ValidValues(int pageNumber) + { + // Arrange + var request = new List.Request + { + ElectionRoundId = Guid.NewGuid(), + PageSize = 10, + PageNumber = pageNumber, + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldNotHaveValidationErrorFor(x => x.PageNumber); + } + + [Theory] + [InlineData(0)] + [InlineData(-5)] + public void Validation_ShouldFail_When_PageNumber_InvalidValues(int pageNumber) + { + // Arrange + var request = new List.Request + { + ElectionRoundId = Guid.NewGuid(), + PageSize = 10, + PageNumber = pageNumber, + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.PageNumber); + } +} diff --git a/api/tests/Feature.Locations.UnitTests/ValidatorTests/LocationImportModelValidatorTests.cs b/api/tests/Feature.Locations.UnitTests/ValidatorTests/LocationImportModelValidatorTests.cs new file mode 100644 index 000000000..f9fe8ec5a --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/ValidatorTests/LocationImportModelValidatorTests.cs @@ -0,0 +1,81 @@ +namespace Feature.Locations.UnitTests.ValidatorTests; + +public class LocationImportModelValidatorTests +{ + private readonly LocationImportModelValidator _validator = new(); + + [Fact] + public void Should_Not_Have_Error_When_Level2_Is_Empty_And_Level3_Is_Empty() + { + // Arrange + var importModel = new LocationImportModel { Level2 = string.Empty, Level3 = string.Empty }; + var context = new ValidationContext(importModel); + context.RootContextData["RowIndex"] = 1; + + // Act + var result = _validator.TestValidate(context); + + // Assert + result.ShouldNotHaveValidationErrorFor(x => x.Level2); + } + + [Fact] + public void Should_Have_Error_When_Level2_Is_Empty_And_Level3_Is_Not_Empty() + { + // Arrange + var importModel = new LocationImportModel { Level2 = string.Empty, Level3 = "Non-empty" }; + var context = new ValidationContext(importModel); + context.RootContextData["RowIndex"] = 1; + + // Act + var result = _validator.TestValidate(context); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.Level2); + } + + [Fact] + public void Should_Have_Error_When_Level3_Is_Empty_And_Level4_Is_Not_Empty() + { + // Arrange + var importModel = new LocationImportModel { Level3 = string.Empty, Level4 = "Non-empty" }; + var context = new ValidationContext(importModel); + context.RootContextData["RowIndex"] = 1; + + // Act + var result = _validator.TestValidate(context); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.Level3); + } + + [Fact] + public void Should_Have_Error_When_Level4_Is_Empty_And_Level5_Is_Not_Empty() + { + // Arrange + var importModel = new LocationImportModel { Level4 = string.Empty, Level5 = "Non-empty" }; + var context = new ValidationContext(importModel); + context.RootContextData["RowIndex"] = 1; + + // Act + var result = _validator.TestValidate(context); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.Level4); + } + + [Fact] + public void Should_Have_Error_When_DisplayOrder_Is_Negative() + { + // Arrange + var importModel = new LocationImportModel { DisplayOrder = -1 }; + var context = new ValidationContext(importModel); + context.RootContextData["RowIndex"] = 1; + + // Act + var result = _validator.TestValidate(context); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.DisplayOrder); + } +} \ No newline at end of file diff --git a/api/tests/Feature.Locations.UnitTests/ValidatorTests/UpdateRequestValidatorTests.cs b/api/tests/Feature.Locations.UnitTests/ValidatorTests/UpdateRequestValidatorTests.cs new file mode 100644 index 000000000..13ce3c503 --- /dev/null +++ b/api/tests/Feature.Locations.UnitTests/ValidatorTests/UpdateRequestValidatorTests.cs @@ -0,0 +1,142 @@ +namespace Feature.Locations.UnitTests.ValidatorTests; + +public class UpdateRequestValidatorTests +{ + private readonly Update.Validator _validator = new(); + + [Fact] + public void Should_Have_Error_When_ElectionRoundId_Is_Empty() + { + // Arrange + var request = new Update.Request { ElectionRoundId = Guid.Empty }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.ElectionRoundId); + } + + [Fact] + public void Should_Have_Error_When_Id_Is_Empty() + { + // Arrange + var request = new Update.Request { Id = Guid.Empty }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.Id); + } + + [Fact] + public void Should_Not_Have_Error_When_Level2_Is_Empty_And_Level3_Is_Empty() + { + // Arrange + var request = new Update.Request { Level2 = string.Empty, Level3 = string.Empty }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldNotHaveValidationErrorFor(x => x.Level2); + } + + [Fact] + public void Should_Have_Error_When_Level2_Is_Empty_And_Level3_Is_Not_Empty() + { + // Arrange + var request = new Update.Request { Level2 = string.Empty, Level3 = "Non-empty" }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.Level2); + } + + [Fact] + public void Should_Have_Error_When_Level3_Is_Empty_And_Level4_Is_Not_Empty() + { + // Arrange + var request = new Update.Request { Level3 = string.Empty, Level4 = "Non-empty" }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.Level3); + } + + [Fact] + public void Should_Have_Error_When_Level4_Is_Empty_And_Level5_Is_Not_Empty() + { + // Arrange + var request = new Update.Request { Level4 = string.Empty, Level5 = "Non-empty" }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.Level4); + } + + [Fact] + public void Should_Have_Error_When_DisplayOrder_Is_Negative() + { + // Arrange + var request = new Update.Request { DisplayOrder = -1 }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.DisplayOrder); + } + + [Fact] + public void Should_Not_Have_Error_When_DisplayOrder_Is_Zero_Or_Greater() + { + // Arrange + var request = new Update.Request { DisplayOrder = 0 }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldNotHaveValidationErrorFor(x => x.DisplayOrder); + } + + [Fact] + public void Should_Have_Error_When_Tags_Has_Empty_Keys() + { + // Arrange + var request = new Update.Request + { + Tags = new Dictionary { { string.Empty, "Value" } } + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldHaveValidationErrorFor(x => x.Tags); + } + + [Fact] + public void Should_Not_Have_Error_When_Tags_Are_Valid() + { + // Arrange + var request = new Update.Request + { + Tags = new Dictionary { { "ValidKey", "Value" } } + }; + + // Act + var result = _validator.TestValidate(request); + + // Assert + result.ShouldNotHaveValidationErrorFor(x => x.Tags); + } +} \ No newline at end of file diff --git a/api/tests/Vote.Monitor.Answer.Module.UnitTests/Aggregators/PSIFormSubmissionsAggregateTests.cs b/api/tests/Vote.Monitor.Answer.Module.UnitTests/Aggregators/PSIFormSubmissionsAggregateTests.cs index 634a698ba..e32bc0b15 100644 --- a/api/tests/Vote.Monitor.Answer.Module.UnitTests/Aggregators/PSIFormSubmissionsAggregateTests.cs +++ b/api/tests/Vote.Monitor.Answer.Module.UnitTests/Aggregators/PSIFormSubmissionsAggregateTests.cs @@ -32,7 +32,8 @@ public PSIFormSubmissionsAggregateTests() _singleSelectQuestion = new SingleSelectQuestionFaker(singleSelectOptions).Generate(); _multiSelectQuestion = new MultiSelectQuestionFaker(multiSelectOptions).Generate(); - List questions = [ + List questions = + [ _textQuestion, _numberQuestion, _dateQuestion, @@ -103,8 +104,10 @@ public void AggregateAnswers_ShouldIncrementSubmissionCount() var pollingStation = new PollingStationFaker(electionRound: _electionRound).Generate(); var monitoringObserver = new MonitoringObserverFaker().Generate(); - var formSubmission1 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver, _form, DateTime.Now, DateTime.Now, [], 0); - var formSubmission2 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver, _form, DateTime.Now, DateTime.Now, [], 0); + var formSubmission1 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver, + _form, DateTime.Now, DateTime.Now, [], 0, 0); + var formSubmission2 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver, + _form, DateTime.Now, DateTime.Now, [], 0, 0); // Act aggregate.AggregateAnswers(formSubmission1); @@ -125,9 +128,12 @@ public void AggregateAnswers_ShouldAddResponderIdToResponders() var monitoringObserver1 = new MonitoringObserverFaker().Generate(); var monitoringObserver2 = new MonitoringObserverFaker().Generate(); - var formSubmission1 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver1, _form, DateTime.Now, DateTime.Now, [], 0); - var formSubmission2 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver2, _form, DateTime.Now, DateTime.Now, [], 0); - var formSubmission3 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver1, _form, DateTime.Now, DateTime.Now, [], 0); + var formSubmission1 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver1, + _form, DateTime.Now, DateTime.Now, [], 0, 0); + var formSubmission2 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver2, + _form, DateTime.Now, DateTime.Now, [], 0, 0); + var formSubmission3 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver1, + _form, DateTime.Now, DateTime.Now, [], 0, 0); // Act aggregate.AggregateAnswers(formSubmission1); @@ -138,8 +144,10 @@ public void AggregateAnswers_ShouldAddResponderIdToResponders() aggregate.Responders.Should().HaveCount(2); var observer1 = monitoringObserver1.Observer.ApplicationUser; var observer2 = monitoringObserver2.Observer.ApplicationUser; - var responder1 = new Responder(monitoringObserver1.Id, observer1.FirstName, observer1.LastName, observer1.Email, observer1.PhoneNumber); - var responder2 = new Responder(monitoringObserver2.Id, observer2.FirstName, observer2.LastName, observer2.Email, observer2.PhoneNumber); + var responder1 = new Responder(monitoringObserver1.Id, observer1.FirstName, observer1.LastName, observer1.Email, + observer1.PhoneNumber); + var responder2 = new Responder(monitoringObserver2.Id, observer2.FirstName, observer2.LastName, observer2.Email, + observer2.PhoneNumber); aggregate.Responders.Should().Contain([responder1, responder2]); } @@ -154,9 +162,12 @@ public void AggregateAnswers_ShouldAddNumberOfQuestionsAnswered() var monitoringObserver = new MonitoringObserverFaker().Generate(); - var formSubmission1 = PollingStationInformation.Create(_electionRound, pollingStation1, monitoringObserver, _form, DateTime.Now, DateTime.Now, [], 22); - var formSubmission2 = PollingStationInformation.Create(_electionRound, pollingStation2, monitoringObserver, _form, DateTime.Now, DateTime.Now, [], 44); - var formSubmission3 = PollingStationInformation.Create(_electionRound, pollingStation1, monitoringObserver, _form, DateTime.Now, DateTime.Now, [], 55); + var formSubmission1 = PollingStationInformation.Create(_electionRound, pollingStation1, monitoringObserver, + _form, DateTime.Now, DateTime.Now, [], 22, 0); + var formSubmission2 = PollingStationInformation.Create(_electionRound, pollingStation2, monitoringObserver, + _form, DateTime.Now, DateTime.Now, [], 44, 0); + var formSubmission3 = PollingStationInformation.Create(_electionRound, pollingStation1, monitoringObserver, + _form, DateTime.Now, DateTime.Now, [], 55, 0); // Act aggregate.AggregateAnswers(formSubmission1); @@ -167,6 +178,33 @@ public void AggregateAnswers_ShouldAddNumberOfQuestionsAnswered() aggregate.TotalNumberOfQuestionsAnswered.Should().Be(121); } + [Fact] + public void AggregateAnswers_ShouldAddNumberOfFlaggedAnswers() + { + // Arrange + var aggregate = new FormSubmissionsAggregate(_form); + + var pollingStation1 = new PollingStationFaker(electionRound: _electionRound).Generate(); + var pollingStation2 = new PollingStationFaker(electionRound: _electionRound).Generate(); + + var monitoringObserver = new MonitoringObserverFaker().Generate(); + + var formSubmission1 = PollingStationInformation.Create(_electionRound, pollingStation1, monitoringObserver, + _form, DateTime.Now, DateTime.Now, [], 0, 12); + var formSubmission2 = PollingStationInformation.Create(_electionRound, pollingStation2, monitoringObserver, + _form, DateTime.Now, DateTime.Now, [], 0, 22); + var formSubmission3 = PollingStationInformation.Create(_electionRound, pollingStation1, monitoringObserver, + _form, DateTime.Now, DateTime.Now, [], 0, 35); + + // Act + aggregate.AggregateAnswers(formSubmission1); + aggregate.AggregateAnswers(formSubmission2); + aggregate.AggregateAnswers(formSubmission3); + + // Assert + aggregate.TotalNumberOfFlaggedAnswers.Should().Be(69); + } + [Fact] public void AggregateAnswers_ShouldAggregateAnswersCorrectly() { @@ -175,7 +213,8 @@ public void AggregateAnswers_ShouldAggregateAnswersCorrectly() var pollingStation = new PollingStationFaker(electionRound: _electionRound).Generate(); var monitoringObserver = new MonitoringObserverFaker().Generate(); - List submission1Answers = [ + List submission1Answers = + [ new DateAnswerFaker(_dateQuestion.Id), new TextAnswerFaker(_textQuestion.Id), new RatingAnswerFaker(_ratingQuestion.Id), @@ -184,20 +223,25 @@ public void AggregateAnswers_ShouldAggregateAnswersCorrectly() new MultiSelectAnswerFaker(_multiSelectQuestion.Id, _multiSelectQuestion.Options.Select(o => o.Select())) ]; - List submission2Answers = [ + List submission2Answers = + [ new SingleSelectAnswerFaker(_singleSelectQuestion.Id, _singleSelectQuestion.Options[2].Select()), new MultiSelectAnswerFaker(_multiSelectQuestion.Id, _multiSelectQuestion.Options.Select(o => o.Select())) ]; - List submission3Answers = [ + List submission3Answers = + [ new DateAnswerFaker(_dateQuestion.Id), new TextAnswerFaker(_textQuestion.Id), new NumberAnswerFaker(_numberQuestion.Id), ]; - var formSubmission1 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver, _form, DateTime.Now, DateTime.Now, submission1Answers, 0); - var formSubmission2 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver, _form, DateTime.Now, DateTime.Now, submission2Answers, 0); - var formSubmission3 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver, _form, DateTime.Now, DateTime.Now, submission3Answers, 0); + var formSubmission1 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver, + _form, DateTime.Now, DateTime.Now, submission1Answers, 0, 0); + var formSubmission2 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver, + _form, DateTime.Now, DateTime.Now, submission2Answers, 0, 0); + var formSubmission3 = PollingStationInformation.Create(_electionRound, pollingStation, monitoringObserver, + _form, DateTime.Now, DateTime.Now, submission3Answers, 0, 0); // Act aggregate.AggregateAnswers(formSubmission1); @@ -212,4 +256,4 @@ public void AggregateAnswers_ShouldAggregateAnswersCorrectly() aggregate.Aggregates[_singleSelectQuestion.Id].AnswersAggregated.Should().Be(2); aggregate.Aggregates[_multiSelectQuestion.Id].AnswersAggregated.Should().Be(2); } -} +} \ No newline at end of file diff --git a/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/GlobalUsings.cs b/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/GlobalUsings.cs index 5fde234f1..c7161d3f5 100644 --- a/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/GlobalUsings.cs +++ b/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/GlobalUsings.cs @@ -8,7 +8,6 @@ global using Microsoft.Extensions.Logging.Abstractions; global using Microsoft.Extensions.Options; global using NSubstitute; -global using Vote.Monitor.Api.Feature.PollingStation.Helpers; global using Vote.Monitor.Core.Services.Csv; global using Vote.Monitor.Api.Feature.PollingStation.Options; global using Vote.Monitor.Api.Feature.PollingStation.Services; diff --git a/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/ServicesTests/PollingStationParserTests.cs b/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/ServicesTests/PollingStationParserTests.cs index 024a4869f..c8bd2da5e 100644 --- a/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/ServicesTests/PollingStationParserTests.cs +++ b/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/ServicesTests/PollingStationParserTests.cs @@ -1,4 +1,5 @@ -using Vote.Monitor.TestUtils.Utils; +using Vote.Monitor.Core.Models; +using Vote.Monitor.TestUtils.Utils; namespace Vote.Monitor.Api.Feature.PollingStation.UnitTests.ServicesTests; @@ -202,54 +203,35 @@ public void Parsing_ShouldSucceed_When_ValidCsv() }); } - //[Theory] - //[MemberData(nameof(MalformedCsvTestCases))] - //public void Parsing_ShouldFail_When_MalformedCsv(string malformedCsvData, string expectedErrorMessage) - //{ - // // Arrange - // var reader = new CsvReader(); - // var sut = new PollingStationParser(reader, NullLogger.Instance, _parserConfig); - - // using var stream = new MemoryStream(); - // using var writer = new StreamWriter(stream); - // writer.Write(malformedCsvData); - // writer.Flush(); - // stream.Position = 0; - - // // Act - // var result = sut.Parse(stream); - - // // Assert - // result.Should().BeOfType(); - // result.As().ValidationErrors[0].Errors[0].ErrorMessage.Should().Be(expectedErrorMessage); - //} - public static IEnumerable MalformedCsvTestCases => new List { // Extra tag name no tag values - new object[] { + new object[] + { ",\n" + - "1,Address1,TagA,TagB\n" + - "2,Address2,TagC,TagD\n" + - "3,Address3,TagE,TagF", + "1,Address1,TagA,TagB\n" + + "2,Address2,TagC,TagD\n" + + "3,Address3,TagE,TagF", "Invalid header provided in import polling stations file." }, // Extra tag values no tag name - new object[] { + new object[] + { "DisplayOrder,Address,Tag1,Tag2\n" + - "1,Address1,TagATagB,\n" + - "2,Address2,TagC,TagD,\n" + - "3,", + "1,Address1,TagATagB,\n" + + "2,Address2,TagC,TagD,\n" + + "3,", "Malformed import polling stations file provided." }, // No display order - new object[] { + new object[] + { "DisplayOrder,Address,Tag1,Tag2\n" + - ",Address1,TagATagB,\n" + - ",Address2,TagC,TagD,\n" + - ",", + ",Address1,TagATagB,\n" + + ",Address2,TagC,TagD,\n" + + ",", "Malformed import polling stations file provided." } }; -} +} \ No newline at end of file diff --git a/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/Specifications/PollingStationAggregateFaker.cs b/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/Specifications/PollingStationAggregateFaker.cs index 9bc804114..3c860dd3b 100644 --- a/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/Specifications/PollingStationAggregateFaker.cs +++ b/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/Specifications/PollingStationAggregateFaker.cs @@ -1,4 +1,6 @@ -using Vote.Monitor.Domain.Entities.ElectionRoundAggregate; +using Vote.Monitor.Core.Helpers; +using Vote.Monitor.Core.Models; +using Vote.Monitor.Domain.Entities.ElectionRoundAggregate; using Vote.Monitor.TestUtils.Fakes; using Vote.Monitor.TestUtils.Fakes.Aggregates; diff --git a/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/ValidatorTests/CreateRequestValidatorTests.cs b/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/ValidatorTests/CreateRequestValidatorTests.cs index b2e7a613f..39fcbf7c3 100644 --- a/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/ValidatorTests/CreateRequestValidatorTests.cs +++ b/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/ValidatorTests/CreateRequestValidatorTests.cs @@ -16,7 +16,7 @@ public void Validation_ShouldFail_When_ElectionRoundIdEmpty() var result = _validator.TestValidate(request); // Assert - result.ShouldNotHaveValidationErrorFor(x => x.Address); + result.ShouldHaveValidationErrorFor(x => x.ElectionRoundId); } [Theory] diff --git a/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/ValidatorTests/PollingStationImportModelValidatorTests.cs b/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/ValidatorTests/PollingStationImportModelValidatorTests.cs index 0af9dba83..c2d4268a7 100644 --- a/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/ValidatorTests/PollingStationImportModelValidatorTests.cs +++ b/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/ValidatorTests/PollingStationImportModelValidatorTests.cs @@ -1,8 +1,9 @@ -namespace Vote.Monitor.Api.Feature.PollingStation.UnitTests.ValidatorTests; +using Vote.Monitor.Core.Models; + +namespace Vote.Monitor.Api.Feature.PollingStation.UnitTests.ValidatorTests; public class PollingStationImportModelValidatorTests { - private readonly PollingStationImportModelValidator _validator = new(); [Theory] diff --git a/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/HelpersTests/TagHelpersTests.cs b/api/tests/Vote.Monitor.Core.UnitTests/HelpersTests/TagHelpersTests.cs similarity index 91% rename from api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/HelpersTests/TagHelpersTests.cs rename to api/tests/Vote.Monitor.Core.UnitTests/HelpersTests/TagHelpersTests.cs index 5baad7f02..debfd13d2 100644 --- a/api/tests/Vote.Monitor.Api.Feature.PollingStation.UnitTests/HelpersTests/TagHelpersTests.cs +++ b/api/tests/Vote.Monitor.Core.UnitTests/HelpersTests/TagHelpersTests.cs @@ -1,4 +1,8 @@ -namespace Vote.Monitor.Api.Feature.PollingStation.UnitTests.HelpersTests; +using System.Text.Json; +using Vote.Monitor.Core.Helpers; +using Vote.Monitor.Core.Models; + +namespace Vote.Monitor.Core.UnitTests.HelpersTests; public class TagHelpersTests { diff --git a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/CitizenReportsDataTableGeneratorTests.cs b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/CitizenReportsDataTableGeneratorTests.cs new file mode 100644 index 000000000..0ea7ecb76 --- /dev/null +++ b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/CitizenReportsDataTableGeneratorTests.cs @@ -0,0 +1,862 @@ +using Vote.Monitor.Core.FileGenerators; +using Vote.Monitor.Core.Models; +using Vote.Monitor.Domain.Entities.FormAnswerBase.Answers; +using Vote.Monitor.Domain.Entities.FormBase.Questions; +using Vote.Monitor.Hangfire.Jobs.Export.CitizenReports; +using Vote.Monitor.Hangfire.Jobs.Export.CitizenReports.ReadModels; +using Vote.Monitor.Hangfire.Models; +using Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData.Fakes; + +namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData; + +public class CitizenReportsDataTableGeneratorTests +{ + private const string DefaultLanguageCode = "EN"; + private const string OtherLanguageCode = "RO"; + private const string QuestionText = "Question text"; + + private const string TextQuestionCode = "TQ"; + private const string NumberQuestionCode = "NQ"; + private const string RatingQuestionCode = "RQ"; + private const string DateQuestionCode = "DQ"; + private const string SingleSelectQuestionCode = "SC"; + private const string MultiSelectQuestionCode = "MC"; + + private const string Option1Text = "Option 1"; + private const string Option2Text = "Option 2"; + private const string Option3Text = "Option 3"; + private const string Option4Text = "Free text option"; + + private const string Note1 = "Some Note 1"; + private const string Note2 = "Some Note 2"; + + private const string Attachment1Url = "https://example.com/1"; + private const string Attachment2Url = "https://example.com/2"; + + private static readonly TranslatedString _questionText = new() + { + [DefaultLanguageCode] = QuestionText, + [OtherLanguageCode] = $"Translated {QuestionText}", + }; + + private static readonly Guid _option1Id = Guid.NewGuid(); + private static readonly Guid _option2Id = Guid.NewGuid(); + private static readonly Guid _option3Id = Guid.NewGuid(); + private static readonly Guid _option4Id = Guid.NewGuid(); + + private static readonly DateTime _utcNow = DateTime.UtcNow; + + private static readonly TranslatedString _option1Text = new() + { + [DefaultLanguageCode] = Option1Text, + [OtherLanguageCode] = "Translated Question 1", + }; + + private static readonly TranslatedString _option2Text = new() + { + [DefaultLanguageCode] = Option2Text, + [OtherLanguageCode] = "Translated some question text", + }; + + private static readonly TranslatedString _option3Text = new() + { + [DefaultLanguageCode] = Option3Text, + [OtherLanguageCode] = "Translated some question text", + }; + + private static readonly TranslatedString _option4Text = new() + { + [DefaultLanguageCode] = Option4Text, + [OtherLanguageCode] = "Translated some question text", + }; + + private static readonly SelectOption[] _selectOptions = + [ + SelectOption.Create(_option1Id, _option1Text), + SelectOption.Create(_option2Id, _option2Text), + SelectOption.Create(_option3Id, _option3Text, false, true), + SelectOption.Create(_option4Id, _option4Text, true) + ]; + + + private static readonly Guid _textQuestionId = Guid.NewGuid(); + + private static readonly TextQuestion _textQuestion = + TextQuestion.Create(_textQuestionId, TextQuestionCode, _questionText); + + private static readonly Guid _numberQuestionId = Guid.NewGuid(); + + private static readonly NumberQuestion _numberQuestion = + NumberQuestion.Create(_numberQuestionId, NumberQuestionCode, _questionText); + + private static readonly Guid _dateQuestionId = Guid.NewGuid(); + + private static readonly DateQuestion _dateQuestion = + DateQuestion.Create(_dateQuestionId, DateQuestionCode, _questionText); + + private static readonly Guid _ratingQuestionId = Guid.NewGuid(); + + private static readonly RatingQuestion _ratingQuestion = + RatingQuestion.Create(_ratingQuestionId, RatingQuestionCode, _questionText, RatingScale.OneTo10); + + private static readonly Guid _singleSelectQuestionId = Guid.NewGuid(); + + private static readonly SingleSelectQuestion _singleSelectQuestion = + SingleSelectQuestion.Create(_singleSelectQuestionId, SingleSelectQuestionCode, _questionText, _selectOptions); + + private static readonly Guid _multiSelectQuestionId = Guid.NewGuid(); + + private static readonly MultiSelectQuestion _multiSelectQuestion = + MultiSelectQuestion.Create(_multiSelectQuestionId, MultiSelectQuestionCode, _questionText, _selectOptions); + + private static readonly string[] _submissionColumns = + [ + "CitizenReportId", + "TimeSubmitted", + "FollowUpStatus", + "Level1", + "Level2", + "Level3", + "Level4", + "Level5" + ]; + + [Fact] + public void CitizenReportsDataTableGenerator_Should_Generate_DataTable_With_Default_Columns() + { + // Arrange + var generator = CitizenReportsDataTable + .FromForm(Fake.Form(DefaultLanguageCode)) + .WithData(); + + // Act + var result = generator.Please(); + + // Assert + result.Should().NotBeNull(); + result.header.Should().ContainInOrder(_submissionColumns); + result.header.Should().HaveSameCount(_submissionColumns); + } + + [Fact] + public void CitizenReportsDataTableGenerator_Should_Generates_Correct_DataTable_WhenTextAnswers() + { + // Arrange + var form = Fake.Form(DefaultLanguageCode, _textQuestion); + + // No notes, no attachments + var citizenReport1 = Fake.CitizenReport(form.Id, TextAnswer.Create(_textQuestionId, "answer 1"), [], []); + // No notes, 2 attachments + var citizenReport2 = Fake.CitizenReport(form.Id, TextAnswer.Create(_textQuestionId, "answer 2"), [], + FakeAttachmentsFor(_textQuestionId)); + // 2 notes, no attachments + var citizenReport3 = Fake.CitizenReport(form.Id, TextAnswer.Create(_textQuestionId, "answer 3"), + FakeNotesFor(_textQuestionId), []); + // 2 notes, 2 attachments + var citizenReport4 = Fake.CitizenReport(form.Id, TextAnswer.Create(_textQuestionId, "answer 4"), + FakeNotesFor(_textQuestionId), FakeAttachmentsFor(_textQuestionId)); + + List expectedData = + [ + [.. GetDefaultExpectedColumns(citizenReport1), "answer 1", 0, "", "", 0, "", ""], + [.. GetDefaultExpectedColumns(citizenReport2), "answer 2", 0, "", "", 2, Attachment1Url, Attachment2Url], + [.. GetDefaultExpectedColumns(citizenReport3), "answer 3", 2, Note1, Note2, 0, "", ""], + [ + .. GetDefaultExpectedColumns(citizenReport4), "answer 4", 2, Note1, Note2, 2, Attachment1Url, + Attachment2Url + ], + ]; + + // Act + var result = CitizenReportsDataTable + .FromForm(form) + .WithData() + .For(citizenReport1) + .For(citizenReport2) + .For(citizenReport3) + .For(citizenReport4) + .Please(); + + // Assert + string[] expectedColumns = + [ + .. _submissionColumns, + "TQ - Question text", + "Notes", + "Note 1", + "Note 2", + "Attachments", + "Attachment 1", + "Attachment 2", + ]; + + result.Should().NotBeNull(); + result.header.Should().HaveSameCount(expectedColumns); + result.dataTable.Should().HaveCount(4); + + result.dataTable[0].Should().ContainInOrder(expectedData[0]); + result.dataTable[1].Should().ContainInOrder(expectedData[1]); + result.dataTable[2].Should().ContainInOrder(expectedData[2]); + result.dataTable[3].Should().ContainInOrder(expectedData[3]); + } + + [Fact] + public void CitizenReportsDataTableGenerator_Should_Generates_Correct_DataTable_WhenNumberAnswers() + { + // Arrange + var form = Fake.Form(DefaultLanguageCode, _numberQuestion); + // No notes, no attachments + var submission1 = Fake.CitizenReport(form.Id, NumberAnswer.Create(_numberQuestionId, 42), [], []); + // No notes, 2 attachments + var submission2 = Fake.CitizenReport(form.Id, NumberAnswer.Create(_numberQuestionId, 43), [], + FakeAttachmentsFor(_numberQuestionId)); + // 2 notes, no attachments + var submission3 = Fake.CitizenReport(form.Id, NumberAnswer.Create(_numberQuestionId, 44), + FakeNotesFor(_numberQuestionId), []); + // 2 notes, 2 attachments + var submission4 = Fake.CitizenReport(form.Id, NumberAnswer.Create(_numberQuestionId, 45), + FakeNotesFor(_numberQuestionId), FakeAttachmentsFor(_numberQuestionId)); + + List expectedData = + [ + [.. GetDefaultExpectedColumns(submission1), 42, 0, "", "", 0, "", ""], + [.. GetDefaultExpectedColumns(submission2), 43, 0, "", "", 2, Attachment1Url, Attachment2Url], + [.. GetDefaultExpectedColumns(submission3), 44, 2, Note1, Note2, 0, "", ""], + [.. GetDefaultExpectedColumns(submission4), 45, 2, Note1, Note2, 2, Attachment1Url, Attachment2Url], + ]; + + // Act + var result = CitizenReportsDataTable + .FromForm(form) + .WithData() + .For(submission1) + .For(submission2) + .For(submission3) + .For(submission4) + .Please(); + + // Assert + string[] expectedColumns = + [ + .. _submissionColumns, + "NQ - Question text", + "Notes", + "Note 1", + "Note 2", + "Attachments", + "Attachment 1", + "Attachment 2", + ]; + + result.Should().NotBeNull(); + result.header.Should().ContainInOrder(expectedColumns); + result.dataTable.Should().HaveCount(4); + + result.dataTable[0].Should().ContainInOrder(expectedData[0]); + result.dataTable[1].Should().ContainInOrder(expectedData[1]); + result.dataTable[2].Should().ContainInOrder(expectedData[2]); + result.dataTable[3].Should().ContainInOrder(expectedData[3]); + } + + [Fact] + public void CitizenReportsDataTableGenerator_Should_Generates_Correct_DataTable_WhenRatingAnswer() + { + // Arrange + var form = Fake.Form(DefaultLanguageCode, _ratingQuestion); + // No notes, no attachments + var submission1 = Fake.CitizenReport(form.Id, RatingAnswer.Create(_ratingQuestionId, 4), [], []); + // No notes, 2 attachments + var submission2 = Fake.CitizenReport(form.Id, RatingAnswer.Create(_ratingQuestionId, 5), [], + FakeAttachmentsFor(_ratingQuestionId)); + // 2 notes, no attachments + var submission3 = Fake.CitizenReport(form.Id, RatingAnswer.Create(_ratingQuestionId, 9), + FakeNotesFor(_ratingQuestionId), []); + // 2 notes, 2 attachments + var submission4 = Fake.CitizenReport(form.Id, RatingAnswer.Create(_ratingQuestionId, 10), + FakeNotesFor(_ratingQuestionId), FakeAttachmentsFor(_ratingQuestionId)); + + List expectedData = + [ + [.. GetDefaultExpectedColumns(submission1), 4, 0, "", "", 0, "", ""], + [.. GetDefaultExpectedColumns(submission2), 5, 0, "", "", 2, Attachment1Url, Attachment2Url], + [.. GetDefaultExpectedColumns(submission3), 9, 2, Note1, Note2, 0, "", ""], + [.. GetDefaultExpectedColumns(submission4), 10, 2, Note1, Note2, 2, Attachment1Url, Attachment2Url], + ]; + + // Act + var result = CitizenReportsDataTable + .FromForm(form) + .WithData() + .For(submission1) + .For(submission2) + .For(submission3) + .For(submission4) + .Please(); + + // Assert + string[] expectedColumns = + [ + .. _submissionColumns, + "RQ - Question text", + "Notes", + "Note 1", + "Note 2", + "Attachments", + "Attachment 1", + "Attachment 2", + ]; + + result.Should().NotBeNull(); + result.header.Should().ContainInOrder(expectedColumns); + result.dataTable.Should().HaveCount(4); + + result.dataTable[0].Should().ContainInOrder(expectedData[0]); + result.dataTable[1].Should().ContainInOrder(expectedData[1]); + result.dataTable[2].Should().ContainInOrder(expectedData[2]); + result.dataTable[3].Should().ContainInOrder(expectedData[3]); + } + + [Fact] + public void CitizenReportsDataTableGenerator_Should_Generates_Correct_DataTable_WhenDateAnswer() + { + // Arrange + var form = Fake.Form(DefaultLanguageCode, _dateQuestion); + var date1 = _utcNow.AddDays(-1); + var date2 = _utcNow.AddDays(-1); + var date3 = _utcNow.AddDays(-1); + var date4 = _utcNow.AddDays(-1); + + // No notes, no attachments + var submission1 = Fake.CitizenReport(form.Id, DateAnswer.Create(_dateQuestionId, date1), [], []); + // No notes, 2 attachments + var submission2 = Fake.CitizenReport(form.Id, DateAnswer.Create(_dateQuestionId, date2), [], + FakeAttachmentsFor(_dateQuestionId)); + // 2 notes, no attachments + var submission3 = Fake.CitizenReport(form.Id, DateAnswer.Create(_dateQuestionId, date3), + FakeNotesFor(_dateQuestionId), []); + // 2 notes, 2 attachments + var submission4 = Fake.CitizenReport(form.Id, DateAnswer.Create(_dateQuestionId, date4), + FakeNotesFor(_dateQuestionId), FakeAttachmentsFor(_dateQuestionId)); + + List expectedData = + [ + [.. GetDefaultExpectedColumns(submission1), date1.ToString("s"), 0, "", "", 0, "", ""], + [ + .. GetDefaultExpectedColumns(submission2), date2.ToString("s"), 0, "", "", 2, Attachment1Url, + Attachment2Url + ], + [.. GetDefaultExpectedColumns(submission3), date3.ToString("s"), 2, Note1, Note2, 0, "", ""], + [ + .. GetDefaultExpectedColumns(submission4), date4.ToString("s"), 2, Note1, Note2, 2, Attachment1Url, + Attachment2Url + ], + ]; + + // Act + var result = CitizenReportsDataTable + .FromForm(form) + .WithData() + .For(submission1) + .For(submission2) + .For(submission3) + .For(submission4) + .Please(); + + // Assert + string[] expectedColumns = + [ + .. _submissionColumns, + "DQ - Question text", + "Notes", + "Note 1", + "Note 2", + "Attachments", + "Attachment 1", + "Attachment 2", + ]; + + result.Should().NotBeNull(); + result.header.Should().ContainInOrder(expectedColumns); + result.dataTable.Should().HaveCount(4); + + result.dataTable[0].Should().ContainInOrder(expectedData[0]); + result.dataTable[1].Should().ContainInOrder(expectedData[1]); + result.dataTable[2].Should().ContainInOrder(expectedData[2]); + result.dataTable[3].Should().ContainInOrder(expectedData[3]); + } + + [Fact] + public void CitizenReportsDataTableGenerator_Should_Generates_Correct_DataTable_WhenSingleSelectAnswer() + { + // Arrange + var form = Fake.Form(DefaultLanguageCode, _singleSelectQuestion); + // No notes, no attachments + var submission1 = Fake.CitizenReport(form.Id, + SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option1Id, null)), [], []); + // No notes, 2 attachments + var submission2 = Fake.CitizenReport(form.Id, + SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option2Id, null)), [], + FakeAttachmentsFor(_singleSelectQuestionId)); + // 2 notes, no attachments + var submission3 = Fake.CitizenReport(form.Id, + SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option3Id, null)), + FakeNotesFor(_singleSelectQuestionId), []); + // 2 notes, 2 attachments + var submission4 = Fake.CitizenReport(form.Id, + SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option4Id, "some free text")), + FakeNotesFor(_singleSelectQuestionId), FakeAttachmentsFor(_singleSelectQuestionId)); + + List expectedData = + [ + [.. GetDefaultExpectedColumns(submission1), "", true, false, false, false, "", 0, "", "", 0, "", ""], + [ + .. GetDefaultExpectedColumns(submission2), "", false, true, false, false, "", 0, "", "", 2, + Attachment1Url, Attachment2Url + ], + [.. GetDefaultExpectedColumns(submission3), "", false, false, true, false, "", 2, Note1, Note2, 0, "", ""], + [ + .. GetDefaultExpectedColumns(submission4), "", false, false, false, true, "some free text", 2, Note1, + Note2, 2, Attachment1Url, Attachment2Url + ], + ]; + + // Act + var result = CitizenReportsDataTable + .FromForm(form) + .WithData() + .For(submission1) + .For(submission2) + .For(submission3) + .For(submission4) + .Please(); + + // Assert + string[] expectedColumns = + [ + .. _submissionColumns, + "SC - Question text", + Option1Text, + Option2Text, + Option3Text + ColorMarkers.Red, + Option4Text, + Option4Text + "-UserInput", + "Notes", + "Note 1", + "Note 2", + "Attachments", + "Attachment 1", + "Attachment 2", + ]; + + result.Should().NotBeNull(); + result.header.Should().ContainInOrder(expectedColumns); + result.dataTable.Should().HaveCount(4); + + result.dataTable[0].Should().ContainInOrder(expectedData[0]); + result.dataTable[1].Should().ContainInOrder(expectedData[1]); + result.dataTable[2].Should().ContainInOrder(expectedData[2]); + result.dataTable[3].Should().ContainInOrder(expectedData[3]); + } + + [Fact] + public void CitizenReportsDataTableGenerator_Should_Generates_Correct_DataTable_WhenMultiSelectAnswer() + { + // Arrange + var form = Fake.Form(DefaultLanguageCode, _multiSelectQuestion); + // No notes, no attachments + SelectedOption[] submission1Selection = + [ + SelectedOption.Create(_option4Id, "user written text"), + SelectedOption.Create(_option2Id, ""), + SelectedOption.Create(_option3Id, ""), + SelectedOption.Create(_option1Id, ""), + ]; + var submission1 = Fake.CitizenReport(form.Id, + MultiSelectAnswer.Create(_multiSelectQuestionId, submission1Selection), [], []); + + // No notes, 2 attachments + SelectedOption[] submission2Selection = [SelectedOption.Create(_option4Id, "some written text")]; + var submission2 = Fake.CitizenReport(form.Id, + MultiSelectAnswer.Create(_multiSelectQuestionId, submission2Selection), [], + FakeAttachmentsFor(_multiSelectQuestionId)); + + // 2 notes, no attachments + SelectedOption[] submission3Selection = + [SelectedOption.Create(_option3Id, ""), SelectedOption.Create(_option2Id, "")]; + var submission3 = Fake.CitizenReport(form.Id, + MultiSelectAnswer.Create(_multiSelectQuestionId, submission3Selection), + FakeNotesFor(_multiSelectQuestionId), []); + + // 2 notes, 2 attachments + SelectedOption[] submission4Selection = + [SelectedOption.Create(_option4Id, "some free text"), SelectedOption.Create(_option1Id, "")]; + var submission4 = Fake.CitizenReport(form.Id, + MultiSelectAnswer.Create(_multiSelectQuestionId, submission4Selection), + FakeNotesFor(_multiSelectQuestionId), FakeAttachmentsFor(_multiSelectQuestionId)); + + List expectedData = + [ + [ + .. GetDefaultExpectedColumns(submission1), "", true, true, true, true, "user written text", 0, "", "", + 0, "", "" + ], + [ + .. GetDefaultExpectedColumns(submission2), "", false, false, false, true, "some written text", 0, "", + "", 2, Attachment1Url, Attachment2Url + ], + [.. GetDefaultExpectedColumns(submission3), "", false, true, true, false, "", 2, Note1, Note2, 0, "", ""], + [ + .. GetDefaultExpectedColumns(submission4), "", true, false, false, true, "some free text", 2, Note1, + Note2, 2, Attachment1Url, Attachment2Url + ], + ]; + + // Act + var result = CitizenReportsDataTable + .FromForm(form) + .WithData() + .For(submission1) + .For(submission2) + .For(submission3) + .For(submission4) + .Please(); + + // Assert + string[] expectedColumns = + [ + .. _submissionColumns, + "MC - Question text", + Option1Text, + Option2Text, + Option3Text + ColorMarkers.Red, + Option4Text, + Option4Text + "-UserInput", + "Notes", + "Note 1", + "Note 2", + "Attachments", + "Attachment 1", + "Attachment 2", + ]; + + result.Should().NotBeNull(); + result.header.Should().ContainInOrder(expectedColumns); + result.dataTable.Should().HaveCount(4); + + result.dataTable[0].Should().ContainInOrder(expectedData[0]); + result.dataTable[1].Should().ContainInOrder(expectedData[1]); + result.dataTable[2].Should().ContainInOrder(expectedData[2]); + result.dataTable[3].Should().ContainInOrder(expectedData[3]); + } + + + [Fact] + public void CitizenReportsDataTableGenerator_Should_Generates_Correct_DataTable_WhenMultipleQuestions() + { + // Arrange + var form = Fake.Form(DefaultLanguageCode, _textQuestion, + _numberQuestion, + _ratingQuestion, + _dateQuestion, + _singleSelectQuestion, + _multiSelectQuestion); + + SelectedOption[] selection = + [ + SelectedOption.Create(_option4Id, "user written text"), + SelectedOption.Create(_option2Id, ""), + SelectedOption.Create(_option3Id, ""), + SelectedOption.Create(_option1Id, ""), + ]; + + var submission1 = Fake.PartialCitizenReport(form.Id, + dateAnswer: (DateAnswer.Create(_dateQuestionId, _utcNow), FakeNotesFor(_dateQuestionId), + FakeAttachmentsFor(_dateQuestionId)), + numberAnswer: (NumberAnswer.Create(_numberQuestionId, 42), FakeNotesFor(_numberQuestionId), + FakeAttachmentsFor(_numberQuestionId)), + ratingAnswer: (RatingAnswer.Create(_ratingQuestionId, 3), FakeNotesFor(_ratingQuestionId), + FakeAttachmentsFor(_ratingQuestionId)), + singleSelectAnswer: ( + SingleSelectAnswer.Create(_singleSelectQuestionId, + SelectedOption.Create(_option4Id, "user written text")), FakeNotesFor(_singleSelectQuestionId), + FakeAttachmentsFor(_singleSelectQuestionId)), + multiSelectAnswer: (MultiSelectAnswer.Create(_multiSelectQuestionId, selection), + FakeNotesFor(_multiSelectQuestionId), FakeAttachmentsFor(_multiSelectQuestionId)) + ); + + var submission2 = Fake.PartialCitizenReport(form.Id, + textAnswer: (TextAnswer.Create(_textQuestionId, "some answer"), FakeNotesFor(_textQuestionId), + FakeAttachmentsFor(_textQuestionId)), + dateAnswer: (DateAnswer.Create(_dateQuestionId, _utcNow), FakeNotesFor(_dateQuestionId), + FakeAttachmentsFor(_dateQuestionId)), + numberAnswer: (NumberAnswer.Create(_numberQuestionId, 42), FakeNotesFor(_numberQuestionId), + FakeAttachmentsFor(_numberQuestionId)), + singleSelectAnswer: ( + SingleSelectAnswer.Create(_singleSelectQuestionId, + SelectedOption.Create(_option4Id, "user written text")), FakeNotesFor(_singleSelectQuestionId), + FakeAttachmentsFor(_singleSelectQuestionId)), + multiSelectAnswer: (MultiSelectAnswer.Create(_multiSelectQuestionId, selection), + FakeNotesFor(_multiSelectQuestionId), FakeAttachmentsFor(_multiSelectQuestionId)) + ); + + var submission3 = Fake.PartialCitizenReport(form.Id, + textAnswer: (TextAnswer.Create(_textQuestionId, "some answer"), FakeNotesFor(_textQuestionId), + FakeAttachmentsFor(_textQuestionId)), + dateAnswer: (DateAnswer.Create(_dateQuestionId, _utcNow), FakeNotesFor(_dateQuestionId), + FakeAttachmentsFor(_dateQuestionId)), + numberAnswer: (NumberAnswer.Create(_numberQuestionId, 42), FakeNotesFor(_numberQuestionId), + FakeAttachmentsFor(_numberQuestionId)), + ratingAnswer: (RatingAnswer.Create(_ratingQuestionId, 3), FakeNotesFor(_ratingQuestionId), + FakeAttachmentsFor(_ratingQuestionId)), + multiSelectAnswer: (MultiSelectAnswer.Create(_multiSelectQuestionId, selection), + FakeNotesFor(_multiSelectQuestionId), FakeAttachmentsFor(_multiSelectQuestionId)) + ); + + object[] expectedTextAnswerColumns = ["some answer", 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; + object[] expectedNumberAnswerColumns = [42, 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; + object[] expectedRatingAnswerColumns = [3, 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; + object[] expectedDateAnswerColumns = + [_utcNow.ToString("s"), 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; + + object[] expectedSingleSelectAnswerColumns = + ["", false, false, false, true, "user written text", 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; + object[] expectedMultiSelectAnswerColumns = + ["", true, true, true, true, "user written text", 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; + + List expectedData = + [ + [ + .. GetDefaultExpectedColumns(submission1), + "", "", "", "", "", "", "", + .. expectedNumberAnswerColumns, + .. expectedRatingAnswerColumns, + .. expectedDateAnswerColumns, + .. expectedSingleSelectAnswerColumns, + .. expectedMultiSelectAnswerColumns + ], + + [ + .. GetDefaultExpectedColumns(submission2), + .. expectedTextAnswerColumns, + .. expectedNumberAnswerColumns, + "", "", "", "", "", "", "", + .. expectedDateAnswerColumns, + .. expectedSingleSelectAnswerColumns, + .. expectedMultiSelectAnswerColumns + ], + + [ + .. GetDefaultExpectedColumns(submission3), + .. expectedTextAnswerColumns, + .. expectedNumberAnswerColumns, + .. expectedRatingAnswerColumns, + .. expectedDateAnswerColumns, + "", "", "", "", "", "", "", "", "", "", "", "", + .. expectedMultiSelectAnswerColumns + ] + ]; + + // Act + var result = CitizenReportsDataTable + .FromForm(form) + .WithData() + .For(submission1) + .For(submission2) + .For(submission3) + .Please(); + + // Assert + string[] expectedColumns = + [ + .. _submissionColumns, + // text question columns + "TQ - Question text", + "Notes", + "Note 1", + "Note 2", + "Attachments", + "Attachment 1", + "Attachment 2", + // number answer columns + "NQ - Question text", + "Notes", + "Note 1", + "Note 2", + "Attachments", + "Attachment 1", + "Attachment 2", + // rating answer columns + "RQ - Question text", + "Notes", + "Note 1", + "Note 2", + "Attachments", + "Attachment 1", + "Attachment 2", + // Date question columns + "DQ - Question text", + "Notes", + "Note 1", + "Note 2", + "Attachments", + "Attachment 1", + "Attachment 2", + // Single select question columns + "SC - Question text", + Option1Text, + Option2Text, + Option3Text + ColorMarkers.Red, + Option4Text, + Option4Text + "-UserInput", + "Notes", + "Note 1", + "Note 2", + "Attachments", + "Attachment 1", + "Attachment 2", + // Multi select question columns + "MC - Question text", + Option1Text, + Option2Text, + Option3Text + ColorMarkers.Red, + Option4Text, + Option4Text + "-UserInput", + "Notes", + "Note 1", + "Note 2", + "Attachments", + "Attachment 1", + "Attachment 2", + ]; + + result.Should().NotBeNull(); + result.header.Should().ContainInOrder(expectedColumns); + result.dataTable.Should().HaveCount(3); + + result.dataTable[0].Should().ContainInOrder(expectedData[0]); + result.dataTable[1].Should().ContainInOrder(expectedData[1]); + result.dataTable[2].Should().ContainInOrder(expectedData[2]); + } + + [Fact] + public void + CitizenReportsDataTableGenerator_Should_Generates_Correct_DataTable_WhenMultipleQuestions_AndEmptyResponses() + { + // Arrange + var form = Fake.Form(DefaultLanguageCode, _textQuestion, + _numberQuestion, + _ratingQuestion, + _dateQuestion, + _singleSelectQuestion, + _multiSelectQuestion); + + var submission = Fake.CitizenReport(form.Id); + + object[] expectedTextAnswerColumns = ["", "", ""]; + object[] expectedNumberAnswerColumns = ["", "", ""]; + object[] expectedRatingAnswerColumns = ["", "", ""]; + object[] expectedDateAnswerColumns = ["", "", ""]; + + object[] expectedSingleSelectAnswerColumns = + ["", "", "", "", "", "", "", ""]; + object[] expectedMultiSelectAnswerColumns = + ["", "", "", "", "", "", "", ""]; + + object[] expectedData = + [ + .. GetDefaultExpectedColumns(submission), + .. expectedTextAnswerColumns, + .. expectedNumberAnswerColumns, + .. expectedRatingAnswerColumns, + .. expectedDateAnswerColumns, + .. expectedSingleSelectAnswerColumns, + .. expectedMultiSelectAnswerColumns + ]; + + // Act + var result = CitizenReportsDataTable + .FromForm(form) + .WithData() + .For(submission) + .Please(); + + // Assert + string[] expectedColumns = + [ + .. _submissionColumns, + // text question columns + "TQ - Question text", + "Notes", + "Attachments", + // number answer columns + "NQ - Question text", + "Notes", + "Attachments", + // rating answer columns + "RQ - Question text", + "Notes", + "Attachments", + // Date question columns + "DQ - Question text", + "Notes", + "Attachments", + // Single select question columns + "SC - Question text", + Option1Text, + Option2Text, + Option3Text + ColorMarkers.Red, + Option4Text, + Option4Text + "-UserInput", + "Notes", + "Attachments", + // Multi select question columns + "MC - Question text", + Option1Text, + Option2Text, + Option3Text + ColorMarkers.Red, + Option4Text, + Option4Text + "-UserInput", + "Notes", + "Attachments", + ]; + + result.Should().NotBeNull(); + result.header.Should().ContainInOrder(expectedColumns); + result.dataTable.Should().HaveCount(1); + + result.dataTable[0].Should().ContainInOrder(expectedData); + } + + private object[] GetDefaultExpectedColumns(CitizenReportModel citizenReport) + { + return + [ + citizenReport.CitizenReportId.ToString(), + citizenReport.TimeSubmitted.ToString("s"), + citizenReport.FollowUpStatus.Value, + citizenReport.Level1, + citizenReport.Level2, + citizenReport.Level3, + citizenReport.Level4, + citizenReport.Level5, + ]; + } + + private SubmissionNoteModel[] FakeNotesFor(Guid questionId) + { + return + [ + new SubmissionNoteModel { QuestionId = questionId, Text = Note1 }, + new SubmissionNoteModel { QuestionId = questionId, Text = Note2 }, + ]; + } + + private SubmissionAttachmentModel[] FakeAttachmentsFor(Guid questionId) + { + return + [ + new SubmissionAttachmentModel { QuestionId = questionId, PresignedUrl = Attachment1Url }, + new SubmissionAttachmentModel { QuestionId = questionId, PresignedUrl = Attachment2Url }, + ]; + } +} \ No newline at end of file diff --git a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.CitizenReports.cs b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.CitizenReports.cs new file mode 100644 index 000000000..89bb600e7 --- /dev/null +++ b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.CitizenReports.cs @@ -0,0 +1,154 @@ +using Bogus; +using Vote.Monitor.Domain.Entities.CitizenReportAggregate; +using Vote.Monitor.Domain.Entities.FormAnswerBase.Answers; +using Vote.Monitor.Hangfire.Jobs.Export.CitizenReports.ReadModels; +using Vote.Monitor.Hangfire.Models; + +namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData.Fakes; + +public sealed partial class Fake +{ + private static readonly CitizenReportFollowUpStatus[] _citizenReportFollowUpStatuses = + [ + CitizenReportFollowUpStatus.NeedsFollowUp, + CitizenReportFollowUpStatus.NotApplicable, + CitizenReportFollowUpStatus.Resolved + ]; + + private static CitizenReportModel GenerateCitizenReport(Guid formId, BaseAnswer[]? answers = null, + SubmissionNoteModel[]? notes = null, SubmissionAttachmentModel[]? attachments = null) + { + var fakeCitizenReport = new Faker() + .RuleFor(x => x.FormId, formId) + .RuleFor(x => x.CitizenReportId, f => f.Random.Guid()) + .RuleFor(x => x.TimeSubmitted, f => f.Date.Recent(1, DateTime.UtcNow)) + .RuleFor(x => x.Level1, f => f.Lorem.Word()) + .RuleFor(x => x.Level2, f => f.Lorem.Word()) + .RuleFor(x => x.Level3, f => f.Lorem.Word()) + .RuleFor(x => x.Level4, f => f.Lorem.Word()) + .RuleFor(x => x.Level5, f => f.Lorem.Word()) + .RuleFor(x => x.Answers, answers ?? []) + .RuleFor(x => x.Notes, notes ?? []) + .RuleFor(x => x.FollowUpStatus, f => f.PickRandom(_citizenReportFollowUpStatuses)) + .RuleFor(x => x.Attachments, attachments ?? []); + + return fakeCitizenReport.Generate(); + } + + public static CitizenReportModel CitizenReport(Guid formId, BaseAnswer answer, SubmissionNoteModel[] notes, + SubmissionAttachmentModel[] attachments) + { + return GenerateCitizenReport(formId, [answer], notes, attachments); + } + + public static CitizenReportModel CitizenReport(Guid formId) + { + return GenerateCitizenReport(formId); + } + + public static CitizenReportModel CitizenReport(Guid formId, + TextAnswer textAnswer, SubmissionNoteModel[] textAnswerNotes, SubmissionAttachmentModel[] textAnswerAttachments, + DateAnswer dateAnswer, SubmissionNoteModel[] dateAnswerNotes, SubmissionAttachmentModel[] dateAnswerAttachments, + NumberAnswer numberAnswer, SubmissionNoteModel[] numberAnswerNotes, + SubmissionAttachmentModel[] numberAnswerAttachments, + RatingAnswer ratingAnswer, SubmissionNoteModel[] ratingAnswerNotes, + SubmissionAttachmentModel[] ratingAnswerAttachments, + SingleSelectAnswer singleSelectAnswer, SubmissionNoteModel[] singleSelectAnswerNotes, + SubmissionAttachmentModel[] singleSelectAnswerAttachments, + MultiSelectAnswer multiSelectAnswer, SubmissionNoteModel[] multiSelectAnswerNotes, + SubmissionAttachmentModel[] multiSelectAnswerAttachments) + { + BaseAnswer[] answers = + [ + textAnswer, + dateAnswer, + numberAnswer, + ratingAnswer, + singleSelectAnswer, + multiSelectAnswer + ]; + + SubmissionNoteModel[] notes = + [ + .. textAnswerNotes, + .. dateAnswerNotes, + .. numberAnswerNotes, + .. ratingAnswerNotes, + .. singleSelectAnswerNotes, + .. multiSelectAnswerNotes + ]; + + SubmissionAttachmentModel[] attachments = + [ + .. textAnswerAttachments, + .. dateAnswerAttachments, + .. numberAnswerAttachments, + .. ratingAnswerAttachments, + .. singleSelectAnswerAttachments, + .. multiSelectAnswerAttachments + ]; + + return GenerateCitizenReport(formId, answers, notes, attachments); + } + + public static CitizenReportModel PartialCitizenReport(Guid formId, + (TextAnswer answer, SubmissionNoteModel[] notes, SubmissionAttachmentModel[] attachments)? textAnswer = null, + (DateAnswer answer, SubmissionNoteModel[] notes, SubmissionAttachmentModel[] attachments)? dateAnswer = null, + (NumberAnswer answer, SubmissionNoteModel[] notes, SubmissionAttachmentModel[] attachments)? numberAnswer = + null, + (RatingAnswer answer, SubmissionNoteModel[] notes, SubmissionAttachmentModel[] attachments)? ratingAnswer = + null, + (SingleSelectAnswer answer, SubmissionNoteModel[] notes, SubmissionAttachmentModel[] attachments)? + singleSelectAnswer = null, + (MultiSelectAnswer answer, SubmissionNoteModel[] notes, SubmissionAttachmentModel[] attachments)? + multiSelectAnswer = null) + { + List answers = []; + List notes = []; + List attachments = []; + + if (textAnswer != null) + { + answers.Add(textAnswer.Value.answer); + notes.AddRange(textAnswer.Value.notes); + attachments.AddRange(textAnswer.Value.attachments); + } + + if (dateAnswer != null) + { + answers.Add(dateAnswer.Value.answer); + notes.AddRange(dateAnswer.Value.notes); + attachments.AddRange(dateAnswer.Value.attachments); + } + + if (numberAnswer != null) + { + answers.Add(numberAnswer.Value.answer); + notes.AddRange(numberAnswer.Value.notes); + attachments.AddRange(numberAnswer.Value.attachments); + } + + if (ratingAnswer != null) + { + answers.Add(ratingAnswer.Value.answer); + notes.AddRange(ratingAnswer.Value.notes); + attachments.AddRange(ratingAnswer.Value.attachments); + } + + if (singleSelectAnswer != null) + { + answers.Add(singleSelectAnswer.Value.answer); + notes.AddRange(singleSelectAnswer.Value.notes); + attachments.AddRange(singleSelectAnswer.Value.attachments); + } + + if (multiSelectAnswer != null) + { + answers.Add(multiSelectAnswer.Value.answer); + notes.AddRange(multiSelectAnswer.Value.notes); + attachments.AddRange(multiSelectAnswer.Value.attachments); + } + + return GenerateCitizenReport(formId, answers.ToArray(), notes.ToArray(), attachments.ToArray()); + } +} \ No newline at end of file diff --git a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fake.Form.cs b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.Form.cs similarity index 89% rename from api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fake.Form.cs rename to api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.Form.cs index 231ebd696..0cee59cc4 100644 --- a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fake.Form.cs +++ b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.Form.cs @@ -3,7 +3,7 @@ using Vote.Monitor.Domain.Entities.FormBase.Questions; using FormAggregate = Vote.Monitor.Domain.Entities.FormAggregate.Form; -namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData; +namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData.Fakes; public sealed partial class Fake { diff --git a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.Location.cs b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.Location.cs new file mode 100644 index 000000000..b5f1a85f2 --- /dev/null +++ b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.Location.cs @@ -0,0 +1,23 @@ +using System.Text.Json; +using Bogus; +using Vote.Monitor.Hangfire.Jobs.Export.Locations.ReadModels; + +namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData.Fakes; + +public sealed partial class Fake +{ + public static LocationModel Location(Guid pollingStationId, JsonDocument? tags = null) + { + var fakePollingStation = new Faker() + .RuleFor(x => x.Id, pollingStationId) + .RuleFor(x => x.Level1, f => f.Lorem.Word()) + .RuleFor(x => x.Level2, f => f.Lorem.Word()) + .RuleFor(x => x.Level3, f => f.Lorem.Word()) + .RuleFor(x => x.Level4, f => f.Lorem.Word()) + .RuleFor(x => x.Level5, f => f.Lorem.Word()) + .RuleFor(x => x.DisplayOrder, f => f.Random.Int().ToString()) + .RuleFor(x => x.Tags, tags ?? _emptyTags); + + return fakePollingStation.Generate(); + } +} \ No newline at end of file diff --git a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fake.PollingStation.cs b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.PollingStation.cs similarity index 94% rename from api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fake.PollingStation.cs rename to api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.PollingStation.cs index a75e00bb9..a720721b7 100644 --- a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fake.PollingStation.cs +++ b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.PollingStation.cs @@ -2,7 +2,7 @@ using Bogus; using Vote.Monitor.Hangfire.Jobs.Export.PollingStations.ReadModels; -namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData; +namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData.Fakes; public sealed partial class Fake { diff --git a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fake.QuickReport.cs b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.QuickReport.cs similarity index 81% rename from api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fake.QuickReport.cs rename to api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.QuickReport.cs index 33f14329d..2f675d8a5 100644 --- a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fake.QuickReport.cs +++ b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.QuickReport.cs @@ -2,11 +2,19 @@ using Vote.Monitor.Domain.Entities.QuickReportAggregate; using Vote.Monitor.Hangfire.Jobs.Export.QuickReports.ReadModels; -namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData; +namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData.Fakes; public sealed partial class Fake { - public static QuickReportModel QuickReport(Guid quickReportId, QuickReportLocationType locationType, QuickReportAttachmentModel[] attachments) + private static readonly QuickReportFollowUpStatus[] _quickReportsFollowUpStatuses = + [ + QuickReportFollowUpStatus.NeedsFollowUp, + QuickReportFollowUpStatus.NotApplicable, + QuickReportFollowUpStatus.Resolved + ]; + + public static QuickReportModel QuickReport(Guid quickReportId, QuickReportLocationType locationType, + QuickReportAttachmentModel[] attachments) { var fakeQuickReport = new Faker() .RuleFor(x => x.Id, quickReportId) @@ -26,8 +34,6 @@ public static QuickReportModel QuickReport(Guid quickReportId, QuickReportLocati if (locationType == QuickReportLocationType.VisitedPollingStation) { - x.PollingStationId = f.Random.Guid(); - x.Level1 = f.Lorem.Word(); x.Level2 = f.Lorem.Word(); x.Level3 = f.Lorem.Word(); @@ -45,4 +51,4 @@ public static QuickReportModel QuickReport(Guid quickReportId, QuickReportLocati return fakeQuickReport.Generate(); } -} +} \ No newline at end of file diff --git a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fake.Submission.cs b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.Submission.cs similarity index 66% rename from api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fake.Submission.cs rename to api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.Submission.cs index 47fab99f6..f46384198 100644 --- a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fake.Submission.cs +++ b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/Fakes/Fake.Submission.cs @@ -1,10 +1,10 @@ using Bogus; using Vote.Monitor.Domain.Entities.FormAnswerBase.Answers; using Vote.Monitor.Domain.Entities.FormSubmissionAggregate; -using Vote.Monitor.Domain.Entities.QuickReportAggregate; using Vote.Monitor.Hangfire.Jobs.Export.FormSubmissions.ReadModels; +using Vote.Monitor.Hangfire.Models; -namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData; +namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData.Fakes; public sealed partial class Fake { @@ -15,14 +15,8 @@ public sealed partial class Fake SubmissionFollowUpStatus.Resolved ]; - private static readonly QuickReportFollowUpStatus[] _quickReportsFollowUpStatuses = - [ - QuickReportFollowUpStatus.NeedsFollowUp, - QuickReportFollowUpStatus.NotApplicable, - QuickReportFollowUpStatus.Resolved - ]; - - private static SubmissionModel GenerateSubmission(Guid formId, BaseAnswer[]? answers = null, NoteModel[]? notes = null, SubmissionAttachmentModel[]? attachments = null) + private static SubmissionModel GenerateSubmission(Guid formId, BaseAnswer[]? answers = null, + SubmissionNoteModel[]? notes = null, SubmissionAttachmentModel[]? attachments = null) { var fakeSubmission = new Faker() .RuleFor(x => x.FormId, formId) @@ -47,7 +41,8 @@ private static SubmissionModel GenerateSubmission(Guid formId, BaseAnswer[]? ans return fakeSubmission.Generate(); } - public static SubmissionModel Submission(Guid formId, BaseAnswer answer, NoteModel[] notes, SubmissionAttachmentModel[] attachments) + public static SubmissionModel Submission(Guid formId, BaseAnswer answer, SubmissionNoteModel[] notes, + SubmissionAttachmentModel[] attachments) { return GenerateSubmission(formId, [answer], notes, attachments); } @@ -56,15 +51,21 @@ public static SubmissionModel Submission(Guid formId) { return GenerateSubmission(formId); } + public static SubmissionModel Submission(Guid formId, - TextAnswer textAnswer, NoteModel[] textAnswerNotes, SubmissionAttachmentModel[] textAnswerAttachments, - DateAnswer dateAnswer, NoteModel[] dateAnswerNotes, SubmissionAttachmentModel[] dateAnswerAttachments, - NumberAnswer numberAnswer, NoteModel[] numberAnswerNotes, SubmissionAttachmentModel[] numberAnswerAttachments, - RatingAnswer ratingAnswer, NoteModel[] ratingAnswerNotes, SubmissionAttachmentModel[] ratingAnswerAttachments, - SingleSelectAnswer singleSelectAnswer, NoteModel[] singleSelectAnswerNotes, SubmissionAttachmentModel[] singleSelectAnswerAttachments, - MultiSelectAnswer multiSelectAnswer, NoteModel[] multiSelectAnswerNotes, SubmissionAttachmentModel[] multiSelectAnswerAttachments) + TextAnswer textAnswer, SubmissionNoteModel[] textAnswerNotes, SubmissionAttachmentModel[] textAnswerAttachments, + DateAnswer dateAnswer, SubmissionNoteModel[] dateAnswerNotes, SubmissionAttachmentModel[] dateAnswerAttachments, + NumberAnswer numberAnswer, SubmissionNoteModel[] numberAnswerNotes, + SubmissionAttachmentModel[] numberAnswerAttachments, + RatingAnswer ratingAnswer, SubmissionNoteModel[] ratingAnswerNotes, + SubmissionAttachmentModel[] ratingAnswerAttachments, + SingleSelectAnswer singleSelectAnswer, SubmissionNoteModel[] singleSelectAnswerNotes, + SubmissionAttachmentModel[] singleSelectAnswerAttachments, + MultiSelectAnswer multiSelectAnswer, SubmissionNoteModel[] multiSelectAnswerNotes, + SubmissionAttachmentModel[] multiSelectAnswerAttachments) { - BaseAnswer[] answers = [ + BaseAnswer[] answers = + [ textAnswer, dateAnswer, numberAnswer, @@ -73,7 +74,8 @@ public static SubmissionModel Submission(Guid formId, multiSelectAnswer ]; - NoteModel[] notes = [ + SubmissionNoteModel[] notes = + [ .. textAnswerNotes, .. dateAnswerNotes, .. numberAnswerNotes, @@ -82,7 +84,8 @@ public static SubmissionModel Submission(Guid formId, .. multiSelectAnswerNotes ]; - SubmissionAttachmentModel[] attachments = [ + SubmissionAttachmentModel[] attachments = + [ .. textAnswerAttachments, .. dateAnswerAttachments, .. numberAnswerAttachments, @@ -95,15 +98,19 @@ .. multiSelectAnswerAttachments } public static SubmissionModel PartialSubmission(Guid formId, - (TextAnswer answer, NoteModel[] notes, SubmissionAttachmentModel[] attachments)? textAnswer = null, - (DateAnswer answer, NoteModel[] notes, SubmissionAttachmentModel[] attachments)? dateAnswer = null, - (NumberAnswer answer, NoteModel[] notes, SubmissionAttachmentModel[] attachments)? numberAnswer = null, - (RatingAnswer answer, NoteModel[] notes, SubmissionAttachmentModel[] attachments)? ratingAnswer = null, - (SingleSelectAnswer answer, NoteModel[] notes, SubmissionAttachmentModel[] attachments)? singleSelectAnswer = null, - (MultiSelectAnswer answer, NoteModel[] notes, SubmissionAttachmentModel[] attachments)? multiSelectAnswer = null) + (TextAnswer answer, SubmissionNoteModel[] notes, SubmissionAttachmentModel[] attachments)? textAnswer = null, + (DateAnswer answer, SubmissionNoteModel[] notes, SubmissionAttachmentModel[] attachments)? dateAnswer = null, + (NumberAnswer answer, SubmissionNoteModel[] notes, SubmissionAttachmentModel[] attachments)? numberAnswer = + null, + (RatingAnswer answer, SubmissionNoteModel[] notes, SubmissionAttachmentModel[] attachments)? ratingAnswer = + null, + (SingleSelectAnswer answer, SubmissionNoteModel[] notes, SubmissionAttachmentModel[] attachments)? + singleSelectAnswer = null, + (MultiSelectAnswer answer, SubmissionNoteModel[] notes, SubmissionAttachmentModel[] attachments)? + multiSelectAnswer = null) { List answers = []; - List notes = []; + List notes = []; List attachments = []; if (textAnswer != null) @@ -111,29 +118,29 @@ public static SubmissionModel PartialSubmission(Guid formId, answers.Add(textAnswer.Value.answer); notes.AddRange(textAnswer.Value.notes); attachments.AddRange(textAnswer.Value.attachments); - } - + } + if (dateAnswer != null) { answers.Add(dateAnswer.Value.answer); notes.AddRange(dateAnswer.Value.notes); attachments.AddRange(dateAnswer.Value.attachments); - } - + } + if (numberAnswer != null) { answers.Add(numberAnswer.Value.answer); notes.AddRange(numberAnswer.Value.notes); attachments.AddRange(numberAnswer.Value.attachments); - } - + } + if (ratingAnswer != null) { answers.Add(ratingAnswer.Value.answer); notes.AddRange(ratingAnswer.Value.notes); attachments.AddRange(ratingAnswer.Value.attachments); - } - + } + if (singleSelectAnswer != null) { answers.Add(singleSelectAnswer.Value.answer); @@ -150,5 +157,4 @@ public static SubmissionModel PartialSubmission(Guid formId, return GenerateSubmission(formId, answers.ToArray(), notes.ToArray(), attachments.ToArray()); } - -} +} \ No newline at end of file diff --git a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/FormSubmissionsDataTableGeneratorTests.cs b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/FormSubmissionsDataTableGeneratorTests.cs index 8e85ac4ab..153fec30e 100644 --- a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/FormSubmissionsDataTableGeneratorTests.cs +++ b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/FormSubmissionsDataTableGeneratorTests.cs @@ -4,6 +4,8 @@ using Vote.Monitor.Domain.Entities.FormBase.Questions; using Vote.Monitor.Hangfire.Jobs.Export.FormSubmissions; using Vote.Monitor.Hangfire.Jobs.Export.FormSubmissions.ReadModels; +using Vote.Monitor.Hangfire.Models; +using Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData.Fakes; namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData; @@ -70,30 +72,42 @@ public class FormSubmissionsDataTableGeneratorTests private static readonly SelectOption[] _selectOptions = [ - SelectOption.Create(_option1Id, _option1Text, false, false), - SelectOption.Create(_option2Id, _option2Text, false, false), + SelectOption.Create(_option1Id, _option1Text), + SelectOption.Create(_option2Id, _option2Text), SelectOption.Create(_option3Id, _option3Text, false, true), - SelectOption.Create(_option4Id, _option4Text, true, false) + SelectOption.Create(_option4Id, _option4Text, true) ]; private static readonly Guid _textQuestionId = Guid.NewGuid(); - private static readonly TextQuestion _textQuestion = TextQuestion.Create(_textQuestionId, TextQuestionCode, _questionText); + + private static readonly TextQuestion _textQuestion = + TextQuestion.Create(_textQuestionId, TextQuestionCode, _questionText); private static readonly Guid _numberQuestionId = Guid.NewGuid(); - private static readonly NumberQuestion _numberQuestion = NumberQuestion.Create(_numberQuestionId, NumberQuestionCode, _questionText); + + private static readonly NumberQuestion _numberQuestion = + NumberQuestion.Create(_numberQuestionId, NumberQuestionCode, _questionText); private static readonly Guid _dateQuestionId = Guid.NewGuid(); - private static readonly DateQuestion _dateQuestion = DateQuestion.Create(_dateQuestionId, DateQuestionCode, _questionText); + + private static readonly DateQuestion _dateQuestion = + DateQuestion.Create(_dateQuestionId, DateQuestionCode, _questionText); private static readonly Guid _ratingQuestionId = Guid.NewGuid(); - private static readonly RatingQuestion _ratingQuestion = RatingQuestion.Create(_ratingQuestionId, RatingQuestionCode, _questionText, RatingScale.OneTo10); + + private static readonly RatingQuestion _ratingQuestion = + RatingQuestion.Create(_ratingQuestionId, RatingQuestionCode, _questionText, RatingScale.OneTo10); private static readonly Guid _singleSelectQuestionId = Guid.NewGuid(); - private static readonly SingleSelectQuestion _singleSelectQuestion = SingleSelectQuestion.Create(_singleSelectQuestionId, SingleSelectQuestionCode, _questionText, _selectOptions); + + private static readonly SingleSelectQuestion _singleSelectQuestion = + SingleSelectQuestion.Create(_singleSelectQuestionId, SingleSelectQuestionCode, _questionText, _selectOptions); private static readonly Guid _multiSelectQuestionId = Guid.NewGuid(); - private static readonly MultiSelectQuestion _multiSelectQuestion = MultiSelectQuestion.Create(_multiSelectQuestionId, MultiSelectQuestionCode, _questionText, _selectOptions); + + private static readonly MultiSelectQuestion _multiSelectQuestion = + MultiSelectQuestion.Create(_multiSelectQuestionId, MultiSelectQuestionCode, _questionText, _selectOptions); private static readonly string[] _submissionColumns = [ @@ -139,11 +153,14 @@ public void FormSubmissionsDataTableGenerator_Should_Generates_Correct_DataTable // No notes, no attachments var submission1 = Fake.Submission(form.Id, TextAnswer.Create(_textQuestionId, "answer 1"), [], []); // No notes, 2 attachments - var submission2 = Fake.Submission(form.Id, TextAnswer.Create(_textQuestionId, "answer 2"), [], FakeAttachmentsFor(_textQuestionId)); + var submission2 = Fake.Submission(form.Id, TextAnswer.Create(_textQuestionId, "answer 2"), [], + FakeAttachmentsFor(_textQuestionId)); // 2 notes, no attachments - var submission3 = Fake.Submission(form.Id, TextAnswer.Create(_textQuestionId, "answer 3"), FakeNotesFor(_textQuestionId), []); + var submission3 = Fake.Submission(form.Id, TextAnswer.Create(_textQuestionId, "answer 3"), + FakeNotesFor(_textQuestionId), []); // 2 notes, 2 attachments - var submission4 = Fake.Submission(form.Id, TextAnswer.Create(_textQuestionId, "answer 4"), FakeNotesFor(_textQuestionId), FakeAttachmentsFor(_textQuestionId)); + var submission4 = Fake.Submission(form.Id, TextAnswer.Create(_textQuestionId, "answer 4"), + FakeNotesFor(_textQuestionId), FakeAttachmentsFor(_textQuestionId)); List expectedData = [ @@ -164,7 +181,8 @@ [.. GetDefaultExpectedColumns(submission4), "answer 4", 2, Note1, Note2, 2, Atta .Please(); // Assert - string[] expectedColumns = [ + string[] expectedColumns = + [ .. _submissionColumns, "TQ - Question text", "Notes", @@ -193,11 +211,14 @@ public void FormSubmissionsDataTableGenerator_Should_Generates_Correct_DataTable // No notes, no attachments var submission1 = Fake.Submission(form.Id, NumberAnswer.Create(_numberQuestionId, 42), [], []); // No notes, 2 attachments - var submission2 = Fake.Submission(form.Id, NumberAnswer.Create(_numberQuestionId, 43), [], FakeAttachmentsFor(_numberQuestionId)); + var submission2 = Fake.Submission(form.Id, NumberAnswer.Create(_numberQuestionId, 43), [], + FakeAttachmentsFor(_numberQuestionId)); // 2 notes, no attachments - var submission3 = Fake.Submission(form.Id, NumberAnswer.Create(_numberQuestionId, 44), FakeNotesFor(_numberQuestionId), []); + var submission3 = Fake.Submission(form.Id, NumberAnswer.Create(_numberQuestionId, 44), + FakeNotesFor(_numberQuestionId), []); // 2 notes, 2 attachments - var submission4 = Fake.Submission(form.Id, NumberAnswer.Create(_numberQuestionId, 45), FakeNotesFor(_numberQuestionId), FakeAttachmentsFor(_numberQuestionId)); + var submission4 = Fake.Submission(form.Id, NumberAnswer.Create(_numberQuestionId, 45), + FakeNotesFor(_numberQuestionId), FakeAttachmentsFor(_numberQuestionId)); List expectedData = [ @@ -218,7 +239,8 @@ [.. GetDefaultExpectedColumns(submission4), 45, 2, Note1, Note2, 2, Attachment1U .Please(); // Assert - string[] expectedColumns = [ + string[] expectedColumns = + [ .. _submissionColumns, "NQ - Question text", "Notes", @@ -247,11 +269,14 @@ public void FormSubmissionsDataTableGenerator_Should_Generates_Correct_DataTable // No notes, no attachments var submission1 = Fake.Submission(form.Id, RatingAnswer.Create(_ratingQuestionId, 4), [], []); // No notes, 2 attachments - var submission2 = Fake.Submission(form.Id, RatingAnswer.Create(_ratingQuestionId, 5), [], FakeAttachmentsFor(_ratingQuestionId)); + var submission2 = Fake.Submission(form.Id, RatingAnswer.Create(_ratingQuestionId, 5), [], + FakeAttachmentsFor(_ratingQuestionId)); // 2 notes, no attachments - var submission3 = Fake.Submission(form.Id, RatingAnswer.Create(_ratingQuestionId, 9), FakeNotesFor(_ratingQuestionId), []); + var submission3 = Fake.Submission(form.Id, RatingAnswer.Create(_ratingQuestionId, 9), + FakeNotesFor(_ratingQuestionId), []); // 2 notes, 2 attachments - var submission4 = Fake.Submission(form.Id, RatingAnswer.Create(_ratingQuestionId, 10), FakeNotesFor(_ratingQuestionId), FakeAttachmentsFor(_ratingQuestionId)); + var submission4 = Fake.Submission(form.Id, RatingAnswer.Create(_ratingQuestionId, 10), + FakeNotesFor(_ratingQuestionId), FakeAttachmentsFor(_ratingQuestionId)); List expectedData = [ @@ -272,7 +297,8 @@ [.. GetDefaultExpectedColumns(submission4), 10, 2, Note1, Note2, 2, Attachment1U .Please(); // Assert - string[] expectedColumns = [ + string[] expectedColumns = + [ .. _submissionColumns, "RQ - Question text", "Notes", @@ -306,18 +332,27 @@ public void FormSubmissionsDataTableGenerator_Should_Generates_Correct_DataTable // No notes, no attachments var submission1 = Fake.Submission(form.Id, DateAnswer.Create(_dateQuestionId, date1), [], []); // No notes, 2 attachments - var submission2 = Fake.Submission(form.Id, DateAnswer.Create(_dateQuestionId, date2), [], FakeAttachmentsFor(_dateQuestionId)); + var submission2 = Fake.Submission(form.Id, DateAnswer.Create(_dateQuestionId, date2), [], + FakeAttachmentsFor(_dateQuestionId)); // 2 notes, no attachments - var submission3 = Fake.Submission(form.Id, DateAnswer.Create(_dateQuestionId, date3), FakeNotesFor(_dateQuestionId), []); + var submission3 = Fake.Submission(form.Id, DateAnswer.Create(_dateQuestionId, date3), + FakeNotesFor(_dateQuestionId), []); // 2 notes, 2 attachments - var submission4 = Fake.Submission(form.Id, DateAnswer.Create(_dateQuestionId, date4), FakeNotesFor(_dateQuestionId), FakeAttachmentsFor(_dateQuestionId)); + var submission4 = Fake.Submission(form.Id, DateAnswer.Create(_dateQuestionId, date4), + FakeNotesFor(_dateQuestionId), FakeAttachmentsFor(_dateQuestionId)); List expectedData = [ [.. GetDefaultExpectedColumns(submission1), date1.ToString("s"), 0, "", "", 0, "", ""], - [.. GetDefaultExpectedColumns(submission2), date2.ToString("s"), 0, "", "", 2, Attachment1Url, Attachment2Url], + [ + .. GetDefaultExpectedColumns(submission2), date2.ToString("s"), 0, "", "", 2, Attachment1Url, + Attachment2Url + ], [.. GetDefaultExpectedColumns(submission3), date3.ToString("s"), 2, Note1, Note2, 0, "", ""], - [.. GetDefaultExpectedColumns(submission4), date4.ToString("s"), 2, Note1, Note2, 2, Attachment1Url, Attachment2Url], + [ + .. GetDefaultExpectedColumns(submission4), date4.ToString("s"), 2, Note1, Note2, 2, Attachment1Url, + Attachment2Url + ], ]; // Act @@ -331,7 +366,8 @@ [.. GetDefaultExpectedColumns(submission4), date4.ToString("s"), 2, Note1, Note2 .Please(); // Assert - string[] expectedColumns = [ + string[] expectedColumns = + [ .. _submissionColumns, "DQ - Question text", "Notes", @@ -358,20 +394,33 @@ public void FormSubmissionsDataTableGenerator_Should_Generates_Correct_DataTable // Arrange var form = Fake.Form(DefaultLanguageCode, _singleSelectQuestion); // No notes, no attachments - var submission1 = Fake.Submission(form.Id, SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option1Id, null)), [], []); + var submission1 = Fake.Submission(form.Id, + SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option1Id, null)), [], []); // No notes, 2 attachments - var submission2 = Fake.Submission(form.Id, SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option2Id, null)), [], FakeAttachmentsFor(_singleSelectQuestionId)); + var submission2 = Fake.Submission(form.Id, + SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option2Id, null)), [], + FakeAttachmentsFor(_singleSelectQuestionId)); // 2 notes, no attachments - var submission3 = Fake.Submission(form.Id, SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option3Id, null)), FakeNotesFor(_singleSelectQuestionId), []); + var submission3 = Fake.Submission(form.Id, + SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option3Id, null)), + FakeNotesFor(_singleSelectQuestionId), []); // 2 notes, 2 attachments - var submission4 = Fake.Submission(form.Id, SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option4Id, "some free text")), FakeNotesFor(_singleSelectQuestionId), FakeAttachmentsFor(_singleSelectQuestionId)); + var submission4 = Fake.Submission(form.Id, + SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option4Id, "some free text")), + FakeNotesFor(_singleSelectQuestionId), FakeAttachmentsFor(_singleSelectQuestionId)); List expectedData = [ - [.. GetDefaultExpectedColumns(submission1), "", true, false, false, false, "",0, "", "", 0, "", ""], - [.. GetDefaultExpectedColumns(submission2), "", false, true, false, false, "", 0, "", "", 2, Attachment1Url, Attachment2Url], + [.. GetDefaultExpectedColumns(submission1), "", true, false, false, false, "", 0, "", "", 0, "", ""], + [ + .. GetDefaultExpectedColumns(submission2), "", false, true, false, false, "", 0, "", "", 2, + Attachment1Url, Attachment2Url + ], [.. GetDefaultExpectedColumns(submission3), "", false, false, true, false, "", 2, Note1, Note2, 0, "", ""], - [.. GetDefaultExpectedColumns(submission4), "", false, false, false, true, "some free text", 2, Note1, Note2, 2, Attachment1Url, Attachment2Url], + [ + .. GetDefaultExpectedColumns(submission4), "", false, false, false, true, "some free text", 2, Note1, + Note2, 2, Attachment1Url, Attachment2Url + ], ]; // Act @@ -385,12 +434,13 @@ [.. GetDefaultExpectedColumns(submission4), "", false, false, false, true, "some .Please(); // Assert - string[] expectedColumns = [ + string[] expectedColumns = + [ .. _submissionColumns, "SC - Question text", Option1Text, Option2Text, - Option3Text+ColorMarkers.Red, + Option3Text + ColorMarkers.Red, Option4Text, Option4Text + "-UserInput", "Notes", @@ -417,32 +467,51 @@ public void FormSubmissionsDataTableGenerator_Should_Generates_Correct_DataTable // Arrange var form = Fake.Form(DefaultLanguageCode, _multiSelectQuestion); // No notes, no attachments - SelectedOption[] submission1Selection = [ + SelectedOption[] submission1Selection = + [ SelectedOption.Create(_option4Id, "user written text"), SelectedOption.Create(_option2Id, ""), SelectedOption.Create(_option3Id, ""), SelectedOption.Create(_option1Id, ""), ]; - var submission1 = Fake.Submission(form.Id, MultiSelectAnswer.Create(_multiSelectQuestionId, submission1Selection), [], []); + var submission1 = Fake.Submission(form.Id, + MultiSelectAnswer.Create(_multiSelectQuestionId, submission1Selection), [], []); // No notes, 2 attachments SelectedOption[] submission2Selection = [SelectedOption.Create(_option4Id, "some written text")]; - var submission2 = Fake.Submission(form.Id, MultiSelectAnswer.Create(_multiSelectQuestionId, submission2Selection), [], FakeAttachmentsFor(_multiSelectQuestionId)); + var submission2 = Fake.Submission(form.Id, + MultiSelectAnswer.Create(_multiSelectQuestionId, submission2Selection), [], + FakeAttachmentsFor(_multiSelectQuestionId)); // 2 notes, no attachments - SelectedOption[] submission3Selection = [SelectedOption.Create(_option3Id, ""), SelectedOption.Create(_option2Id, "")]; - var submission3 = Fake.Submission(form.Id, MultiSelectAnswer.Create(_multiSelectQuestionId, submission3Selection), FakeNotesFor(_multiSelectQuestionId), []); + SelectedOption[] submission3Selection = + [SelectedOption.Create(_option3Id, ""), SelectedOption.Create(_option2Id, "")]; + var submission3 = Fake.Submission(form.Id, + MultiSelectAnswer.Create(_multiSelectQuestionId, submission3Selection), + FakeNotesFor(_multiSelectQuestionId), []); // 2 notes, 2 attachments - SelectedOption[] submission4Selection = [SelectedOption.Create(_option4Id, "some free text"), SelectedOption.Create(_option1Id, "")]; - var submission4 = Fake.Submission(form.Id, MultiSelectAnswer.Create(_multiSelectQuestionId, submission4Selection), FakeNotesFor(_multiSelectQuestionId), FakeAttachmentsFor(_multiSelectQuestionId)); + SelectedOption[] submission4Selection = + [SelectedOption.Create(_option4Id, "some free text"), SelectedOption.Create(_option1Id, "")]; + var submission4 = Fake.Submission(form.Id, + MultiSelectAnswer.Create(_multiSelectQuestionId, submission4Selection), + FakeNotesFor(_multiSelectQuestionId), FakeAttachmentsFor(_multiSelectQuestionId)); List expectedData = [ - [.. GetDefaultExpectedColumns(submission1), "", true, true, true, true, "user written text", 0, "", "", 0, "", ""], - [.. GetDefaultExpectedColumns(submission2), "", false, false, false, true, "some written text", 0, "", "", 2, Attachment1Url, Attachment2Url], + [ + .. GetDefaultExpectedColumns(submission1), "", true, true, true, true, "user written text", 0, "", "", + 0, "", "" + ], + [ + .. GetDefaultExpectedColumns(submission2), "", false, false, false, true, "some written text", 0, "", + "", 2, Attachment1Url, Attachment2Url + ], [.. GetDefaultExpectedColumns(submission3), "", false, true, true, false, "", 2, Note1, Note2, 0, "", ""], - [.. GetDefaultExpectedColumns(submission4), "", true, false, false, true, "some free text", 2, Note1, Note2, 2, Attachment1Url, Attachment2Url], + [ + .. GetDefaultExpectedColumns(submission4), "", true, false, false, true, "some free text", 2, Note1, + Note2, 2, Attachment1Url, Attachment2Url + ], ]; // Act @@ -456,12 +525,13 @@ [.. GetDefaultExpectedColumns(submission4), "", true, false, false, true, "some .Please(); // Assert - string[] expectedColumns = [ + string[] expectedColumns = + [ .. _submissionColumns, "MC - Question text", Option1Text, Option2Text, - Option3Text+ColorMarkers.Red, + Option3Text + ColorMarkers.Red, Option4Text, Option4Text + "-UserInput", "Notes", @@ -494,7 +564,8 @@ public void FormSubmissionsDataTableGenerator_Should_Generates_Correct_DataTable _singleSelectQuestion, _multiSelectQuestion); - SelectedOption[] selection = [ + SelectedOption[] selection = + [ SelectedOption.Create(_option4Id, "user written text"), SelectedOption.Create(_option2Id, ""), SelectedOption.Create(_option3Id, ""), @@ -502,41 +573,61 @@ public void FormSubmissionsDataTableGenerator_Should_Generates_Correct_DataTable ]; var submission1 = Fake.PartialSubmission(form.Id, - dateAnswer: (DateAnswer.Create(_dateQuestionId, _utcNow), FakeNotesFor(_dateQuestionId), FakeAttachmentsFor(_dateQuestionId)), - numberAnswer: (NumberAnswer.Create(_numberQuestionId, 42), FakeNotesFor(_numberQuestionId), FakeAttachmentsFor(_numberQuestionId)), - ratingAnswer: (RatingAnswer.Create(_ratingQuestionId, 3), FakeNotesFor(_ratingQuestionId), FakeAttachmentsFor(_ratingQuestionId)), - singleSelectAnswer: (SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option4Id, "user written text")), FakeNotesFor(_singleSelectQuestionId), FakeAttachmentsFor(_singleSelectQuestionId)), - multiSelectAnswer: (MultiSelectAnswer.Create(_multiSelectQuestionId, selection), FakeNotesFor(_multiSelectQuestionId), FakeAttachmentsFor(_multiSelectQuestionId)) - ); + dateAnswer: (DateAnswer.Create(_dateQuestionId, _utcNow), FakeNotesFor(_dateQuestionId), + FakeAttachmentsFor(_dateQuestionId)), + numberAnswer: (NumberAnswer.Create(_numberQuestionId, 42), FakeNotesFor(_numberQuestionId), + FakeAttachmentsFor(_numberQuestionId)), + ratingAnswer: (RatingAnswer.Create(_ratingQuestionId, 3), FakeNotesFor(_ratingQuestionId), + FakeAttachmentsFor(_ratingQuestionId)), + singleSelectAnswer: ( + SingleSelectAnswer.Create(_singleSelectQuestionId, + SelectedOption.Create(_option4Id, "user written text")), FakeNotesFor(_singleSelectQuestionId), + FakeAttachmentsFor(_singleSelectQuestionId)), + multiSelectAnswer: (MultiSelectAnswer.Create(_multiSelectQuestionId, selection), + FakeNotesFor(_multiSelectQuestionId), FakeAttachmentsFor(_multiSelectQuestionId)) + ); var submission2 = Fake.PartialSubmission(form.Id, - textAnswer: (TextAnswer.Create(_textQuestionId, "some answer"), FakeNotesFor(_textQuestionId), FakeAttachmentsFor(_textQuestionId)), - dateAnswer: (DateAnswer.Create(_dateQuestionId, _utcNow), FakeNotesFor(_dateQuestionId), FakeAttachmentsFor(_dateQuestionId)), - numberAnswer: (NumberAnswer.Create(_numberQuestionId, 42), FakeNotesFor(_numberQuestionId), FakeAttachmentsFor(_numberQuestionId)), - singleSelectAnswer: (SingleSelectAnswer.Create(_singleSelectQuestionId, SelectedOption.Create(_option4Id, "user written text")), FakeNotesFor(_singleSelectQuestionId), FakeAttachmentsFor(_singleSelectQuestionId)), - multiSelectAnswer: (MultiSelectAnswer.Create(_multiSelectQuestionId, selection), FakeNotesFor(_multiSelectQuestionId), FakeAttachmentsFor(_multiSelectQuestionId)) + textAnswer: (TextAnswer.Create(_textQuestionId, "some answer"), FakeNotesFor(_textQuestionId), + FakeAttachmentsFor(_textQuestionId)), + dateAnswer: (DateAnswer.Create(_dateQuestionId, _utcNow), FakeNotesFor(_dateQuestionId), + FakeAttachmentsFor(_dateQuestionId)), + numberAnswer: (NumberAnswer.Create(_numberQuestionId, 42), FakeNotesFor(_numberQuestionId), + FakeAttachmentsFor(_numberQuestionId)), + singleSelectAnswer: ( + SingleSelectAnswer.Create(_singleSelectQuestionId, + SelectedOption.Create(_option4Id, "user written text")), FakeNotesFor(_singleSelectQuestionId), + FakeAttachmentsFor(_singleSelectQuestionId)), + multiSelectAnswer: (MultiSelectAnswer.Create(_multiSelectQuestionId, selection), + FakeNotesFor(_multiSelectQuestionId), FakeAttachmentsFor(_multiSelectQuestionId)) ); var submission3 = Fake.PartialSubmission(form.Id, - textAnswer: (TextAnswer.Create(_textQuestionId, "some answer"), FakeNotesFor(_textQuestionId), FakeAttachmentsFor(_textQuestionId)), - dateAnswer: (DateAnswer.Create(_dateQuestionId, _utcNow), FakeNotesFor(_dateQuestionId), FakeAttachmentsFor(_dateQuestionId)), - numberAnswer: (NumberAnswer.Create(_numberQuestionId, 42), FakeNotesFor(_numberQuestionId), FakeAttachmentsFor(_numberQuestionId)), - ratingAnswer: (RatingAnswer.Create(_ratingQuestionId, 3), FakeNotesFor(_ratingQuestionId), FakeAttachmentsFor(_ratingQuestionId)), - multiSelectAnswer: (MultiSelectAnswer.Create(_multiSelectQuestionId, selection), FakeNotesFor(_multiSelectQuestionId), FakeAttachmentsFor(_multiSelectQuestionId)) + textAnswer: (TextAnswer.Create(_textQuestionId, "some answer"), FakeNotesFor(_textQuestionId), + FakeAttachmentsFor(_textQuestionId)), + dateAnswer: (DateAnswer.Create(_dateQuestionId, _utcNow), FakeNotesFor(_dateQuestionId), + FakeAttachmentsFor(_dateQuestionId)), + numberAnswer: (NumberAnswer.Create(_numberQuestionId, 42), FakeNotesFor(_numberQuestionId), + FakeAttachmentsFor(_numberQuestionId)), + ratingAnswer: (RatingAnswer.Create(_ratingQuestionId, 3), FakeNotesFor(_ratingQuestionId), + FakeAttachmentsFor(_ratingQuestionId)), + multiSelectAnswer: (MultiSelectAnswer.Create(_multiSelectQuestionId, selection), + FakeNotesFor(_multiSelectQuestionId), FakeAttachmentsFor(_multiSelectQuestionId)) ); object[] expectedTextAnswerColumns = ["some answer", 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; object[] expectedNumberAnswerColumns = [42, 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; object[] expectedRatingAnswerColumns = [3, 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; - object[] expectedDateAnswerColumns = [_utcNow.ToString("s"), 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; + object[] expectedDateAnswerColumns = + [_utcNow.ToString("s"), 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; object[] expectedSingleSelectAnswerColumns = ["", false, false, false, true, "user written text", 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; object[] expectedMultiSelectAnswerColumns = ["", true, true, true, true, "user written text", 2, Note1, Note2, 2, Attachment1Url, Attachment2Url]; - List expectedData = [ - + List expectedData = + [ [ .. GetDefaultExpectedColumns(submission1), "", "", "", "", "", "", "", @@ -578,7 +669,8 @@ .. expectedMultiSelectAnswerColumns .Please(); // Assert - string[] expectedColumns = [ + string[] expectedColumns = + [ .. _submissionColumns, // text question columns "TQ - Question text", @@ -616,7 +708,7 @@ .. expectedMultiSelectAnswerColumns "SC - Question text", Option1Text, Option2Text, - Option3Text+ColorMarkers.Red, + Option3Text + ColorMarkers.Red, Option4Text, Option4Text + "-UserInput", "Notes", @@ -629,7 +721,7 @@ .. expectedMultiSelectAnswerColumns "MC - Question text", Option1Text, Option2Text, - Option3Text+ColorMarkers.Red, + Option3Text + ColorMarkers.Red, Option4Text, Option4Text + "-UserInput", "Notes", @@ -650,7 +742,8 @@ .. expectedMultiSelectAnswerColumns } [Fact] - public void FormSubmissionsDataTableGenerator_Should_Generates_Correct_DataTable_WhenMultipleQuestions_AndEmptyResponses() + public void + FormSubmissionsDataTableGenerator_Should_Generates_Correct_DataTable_WhenMultipleQuestions_AndEmptyResponses() { // Arrange var form = Fake.Form(DefaultLanguageCode, _textQuestion, @@ -691,7 +784,8 @@ .. expectedMultiSelectAnswerColumns .Please(); // Assert - string[] expectedColumns = [ + string[] expectedColumns = + [ .. _submissionColumns, // text question columns "TQ - Question text", @@ -713,7 +807,7 @@ .. expectedMultiSelectAnswerColumns "SC - Question text", Option1Text, Option2Text, - Option3Text+ColorMarkers.Red, + Option3Text + ColorMarkers.Red, Option4Text, Option4Text + "-UserInput", "Notes", @@ -722,7 +816,7 @@ .. expectedMultiSelectAnswerColumns "MC - Question text", Option1Text, Option2Text, - Option3Text+ColorMarkers.Red, + Option3Text + ColorMarkers.Red, Option4Text, Option4Text + "-UserInput", "Notes", @@ -757,12 +851,12 @@ private object[] GetDefaultExpectedColumns(SubmissionModel submission) ]; } - private NoteModel[] FakeNotesFor(Guid questionId) + private SubmissionNoteModel[] FakeNotesFor(Guid questionId) { return [ - new NoteModel { QuestionId = questionId, Text = Note1 }, - new NoteModel { QuestionId = questionId, Text = Note2 }, + new SubmissionNoteModel { QuestionId = questionId, Text = Note1 }, + new SubmissionNoteModel { QuestionId = questionId, Text = Note2 }, ]; } @@ -774,4 +868,4 @@ private SubmissionAttachmentModel[] FakeAttachmentsFor(Guid questionId) new SubmissionAttachmentModel { QuestionId = questionId, PresignedUrl = Attachment2Url }, ]; } -} +} \ No newline at end of file diff --git a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/LocationsDataTableGeneratorTests.cs b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/LocationsDataTableGeneratorTests.cs new file mode 100644 index 000000000..e88973025 --- /dev/null +++ b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/LocationsDataTableGeneratorTests.cs @@ -0,0 +1,200 @@ +using System.Text.Json; +using Vote.Monitor.Hangfire.Jobs.Export.Locations; +using Vote.Monitor.Hangfire.Jobs.Export.Locations.ReadModels; +using Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData.Fakes; + +namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData; + +public class LocationsDataTableGeneratorTests +{ + private readonly Guid _locationId1 = Guid.NewGuid(); + private readonly Guid _locationId2 = Guid.NewGuid(); + private readonly Guid _locationId3 = Guid.NewGuid(); + + private readonly string _locationId1Tags = """ + { + "tag1": "tag1_value1", + "tag2": "tag2_value1", + "tag4": "tag4_value1", + "tag5": "tag5_value1" + } + """; + + private readonly string _locationId2Tags = """ + { + "tag1": "tag1_value2", + "tag2": "tag2_value2", + "tag3": "tag3_value2", + "tag6": "tag6_value2" + } + + """; + + private readonly string _locationId3Tags = """ + { + "tag1": "tag1_value3", + "tag3": "tag3_value3", + "tag4": "tag4_value3", + "tag7": "tag7_value3" + } + """; + + private static readonly string[] _locationColumns = + [ + "Id", + "Level1", + "Level2", + "Level3", + "Level4", + "Level5", + "DisplayOrder", + ]; + + [Fact] + public void LocationsDataTableGenerator_Should_Generate_DataTable_With_Default_Columns() + { + // Arrange + var generator = LocationsDataTable + .New() + .WithData(); + + // Act + var result = generator.Please(); + + // Assert + result.Should().NotBeNull(); + result.header.Should().ContainInOrder(_locationColumns); + result.header.Should().HaveSameCount(_locationColumns); + } + + [Fact] + public void LocationsDataTableGenerator_Should_Generates_Correct_DataTable_WhenEmptyTags() + { + // Arrange + var location1 = Fake.Location(_locationId1); + var location2 = Fake.Location(_locationId2); + var location3 = Fake.Location(_locationId3); + + List expectedData = + [ + [ + .. GetDefaultExpectedColumns(location1), + ], + [ + .. GetDefaultExpectedColumns(location2), + ], + [ + .. GetDefaultExpectedColumns(location3), + ], + ]; + + // Act + var result = LocationsDataTable + .New() + .WithData() + .For(location1) + .For(location2) + .For(location3) + .Please(); + + // Assert + string[] expectedColumns = [.. _locationColumns]; + + result.Should().NotBeNull(); + result.header.Should().HaveSameCount(expectedColumns); + result.header.Should().ContainInOrder(expectedColumns); + result.dataTable.Should().HaveCount(3); + + result.dataTable[0].Should().ContainInOrder(expectedData[0]); + result.dataTable[1].Should().ContainInOrder(expectedData[1]); + result.dataTable[2].Should().ContainInOrder(expectedData[2]); + } + + [Fact] + public void LocationsDataTableGenerator_Should_Generates_Correct_DataTableWhenTags() + { + // Arrange + var location1 = Fake.Location(_locationId1, JsonDocument.Parse(_locationId1Tags)); + var location2 = Fake.Location(_locationId2, JsonDocument.Parse(_locationId2Tags)); + var location3 = Fake.Location(_locationId3, JsonDocument.Parse(_locationId3Tags)); + + List expectedData = + [ + [ + .. GetDefaultExpectedColumns(location1), + "tag1_value1", + "tag2_value1", + "", + "tag4_value1", + "tag5_value1", + "", + "", + ], + [ + .. GetDefaultExpectedColumns(location2), + "tag1_value2", + "tag2_value2", + "tag3_value2", + "", + "", + "tag6_value2", + "", + ], + [ + .. GetDefaultExpectedColumns(location3), + "tag1_value3", + "", + "tag3_value3", + "tag4_value3", + "", + "", + "tag7_value3", + ], + ]; + + // Act + var result = LocationsDataTable + .New() + .WithData() + .For(location1) + .For(location2) + .For(location3) + .Please(); + + // Assert + string[] expectedColumns = + [ + .. _locationColumns, + "tag1", + "tag2", + "tag3", + "tag4", + "tag5", + "tag6", + "tag7", + ]; + + result.Should().NotBeNull(); + result.header.Should().HaveSameCount(expectedColumns); + result.header.Should().ContainInOrder(expectedColumns); + result.dataTable.Should().HaveCount(3); + + result.dataTable[0].Should().ContainInOrder(expectedData[0]); + result.dataTable[1].Should().ContainInOrder(expectedData[1]); + result.dataTable[2].Should().ContainInOrder(expectedData[2]); + } + + private object[] GetDefaultExpectedColumns(LocationModel location) + { + return + [ + location.Id.ToString(), + location.Level1, + location.Level2, + location.Level3, + location.Level4, + location.Level5, + location.DisplayOrder + ]; + } +} \ No newline at end of file diff --git a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/PollingStationsDataTableGeneratorTests.cs b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/PollingStationsDataTableGeneratorTests.cs index 1b8dde1fa..82232f8a2 100644 --- a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/PollingStationsDataTableGeneratorTests.cs +++ b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/PollingStationsDataTableGeneratorTests.cs @@ -1,6 +1,7 @@ using System.Text.Json; using Vote.Monitor.Hangfire.Jobs.Export.PollingStations; using Vote.Monitor.Hangfire.Jobs.Export.PollingStations.ReadModels; +using Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData.Fakes; namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData; diff --git a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/QuickReportsDataTableGeneratorTests.cs b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/QuickReportsDataTableGeneratorTests.cs index e0fda75e6..e51799cf7 100644 --- a/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/QuickReportsDataTableGeneratorTests.cs +++ b/api/tests/Vote.Monitor.Hangfire.UnitTests/Jobs/ExportData/QuickReportsDataTableGeneratorTests.cs @@ -1,6 +1,7 @@ using Vote.Monitor.Domain.Entities.QuickReportAggregate; using Vote.Monitor.Hangfire.Jobs.Export.QuickReports; using Vote.Monitor.Hangfire.Jobs.Export.QuickReports.ReadModels; +using Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData.Fakes; namespace Vote.Monitor.Hangfire.UnitTests.Jobs.ExportData; @@ -24,7 +25,6 @@ public class QuickReportsDataTableGeneratorTests "Email", "PhoneNumber", "LocationType", - "PollingStationId", "Level1", "Level2", "Level3", @@ -65,7 +65,6 @@ public void QuickReportsDataTableGenerator_Should_Generates_Correct_DataTable() [ [ .. GetDefaultExpectedColumns(quickReport1), - quickReport1.PollingStationId.ToString(), quickReport1.Level1, quickReport1.Level2, quickReport1.Level3, @@ -144,7 +143,6 @@ public void QuickReportsDataTableGenerator_Should_Generates_Correct_DataTableWhe [ [ .. GetDefaultExpectedColumns(quickReport), - quickReport.PollingStationId.ToString(), quickReport.Level1, quickReport.Level2, quickReport.Level3, diff --git a/api/tests/Vote.Monitor.TestUtils/Fakes/Aggregates/CitizenReportFaker.cs b/api/tests/Vote.Monitor.TestUtils/Fakes/Aggregates/CitizenReportFaker.cs index cc9f24ffe..ac96a1b4f 100644 --- a/api/tests/Vote.Monitor.TestUtils/Fakes/Aggregates/CitizenReportFaker.cs +++ b/api/tests/Vote.Monitor.TestUtils/Fakes/Aggregates/CitizenReportFaker.cs @@ -1,5 +1,6 @@ using Vote.Monitor.Domain.Entities.CitizenReportAggregate; using Vote.Monitor.Domain.Entities.FormAggregate; +using Vote.Monitor.Domain.Entities.LocationAggregate; namespace Vote.Monitor.TestUtils.Fakes.Aggregates; @@ -7,16 +8,21 @@ public sealed class CitizenReportFaker : PrivateFaker { public CitizenReportFaker(Guid? id = null, ElectionRound? electionRound = null, + Location? location = null, Form? form = null) { UsePrivateConstructor(); electionRound ??= new ElectionRoundAggregateFaker().Generate(); form ??= new FormAggregateFaker(electionRound).Generate(); + location ??= new LocationAggregateFaker(electionRound).Generate(); RuleFor(fake => fake.Id, faker => id ?? faker.Random.Guid()); RuleFor(fake => fake.ElectionRound, electionRound); RuleFor(fake => fake.ElectionRoundId, electionRound.Id); + RuleFor(fake => fake.Location, location); + RuleFor(fake => fake.LocationId, location.Id); + RuleFor(fake => fake.Form, form); RuleFor(fake => fake.FormId, form.Id); } diff --git a/api/tests/Vote.Monitor.TestUtils/Fakes/Aggregates/LocationAggregateFaker.cs b/api/tests/Vote.Monitor.TestUtils/Fakes/Aggregates/LocationAggregateFaker.cs new file mode 100644 index 000000000..202663895 --- /dev/null +++ b/api/tests/Vote.Monitor.TestUtils/Fakes/Aggregates/LocationAggregateFaker.cs @@ -0,0 +1,33 @@ +using Vote.Monitor.Core.Helpers; +using Vote.Monitor.Core.Models; +using Vote.Monitor.Domain.Entities.LocationAggregate; + +namespace Vote.Monitor.TestUtils.Fakes.Aggregates; + +public sealed class LocationAggregateFaker : PrivateFaker +{ + private readonly DateTime _baseCreationDate = new(2024, 01, 01, 00, 00, 00, DateTimeKind.Utc); + + public LocationAggregateFaker(ElectionRound? electionRound = null, Guid? id = null, int? displayOrder = null) + { + UsePrivateConstructor(); + electionRound ??= new ElectionRoundAggregateFaker().Generate(); + + RuleFor(fake => fake.Id, id ?? Guid.NewGuid()); + RuleFor(fake => fake.ElectionRound, electionRound); + RuleFor(fake => fake.ElectionRoundId, electionRound.Id); + RuleFor(fake => fake.Level1, fake => fake.Address.Country()); + RuleFor(fake => fake.Level2, fake => fake.Address.State()); + RuleFor(fake => fake.Level3, fake => fake.Address.County()); + RuleFor(fake => fake.Level4, fake => fake.Address.City()); + RuleFor(fake => fake.Level5, fake => fake.Address.StreetName()); + RuleFor(fake => fake.DisplayOrder, fake => displayOrder ?? fake.Random.Int(0, 1000)); + RuleFor(fake => fake.Tags, fake => fake.Commerce.Categories(4).Select((x, i) => new TagImportModel + { + Name = $"Tag {i}", + Value = x + }).ToTagsObject()); + RuleFor(fake => fake.CreatedOn, _baseCreationDate); + } + +} diff --git a/api/tests/Vote.Monitor.TestUtils/TestContext.cs b/api/tests/Vote.Monitor.TestUtils/TestContext.cs index 91ef0c91b..6af6f317b 100644 --- a/api/tests/Vote.Monitor.TestUtils/TestContext.cs +++ b/api/tests/Vote.Monitor.TestUtils/TestContext.cs @@ -4,6 +4,7 @@ using Vote.Monitor.Core.Services.Serialization; using Vote.Monitor.Domain; using Vote.Monitor.Domain.Entities.FeedbackAggregate; +using Vote.Monitor.Domain.Entities.LocationAggregate; using Vote.Monitor.Domain.Entities.PollingStationAggregate; namespace Vote.Monitor.TestUtils; @@ -25,6 +26,7 @@ protected override void OnModelCreating(ModelBuilder builder) //needed because the in memory ef core provider cannot map type JsonDocument builder.Entity().Ignore(t => t.Tags); + builder.Entity().Ignore(t => t.Tags); builder.Entity().Ignore(t => t.Metadata); } diff --git a/utils/SubmissionsFaker/Clients/Citizen/Models/CitizenReportRequest.cs b/utils/SubmissionsFaker/Clients/Citizen/Models/CitizenReportRequest.cs index 0c5744039..b9687a71e 100644 --- a/utils/SubmissionsFaker/Clients/Citizen/Models/CitizenReportRequest.cs +++ b/utils/SubmissionsFaker/Clients/Citizen/Models/CitizenReportRequest.cs @@ -7,4 +7,5 @@ public class CitizenReportRequest public string CitizenReportId { get; set; } public string FormId { get; set; } public List Answers { get; set; } = []; + public Guid LocationId { get; set; } } \ No newline at end of file diff --git a/utils/SubmissionsFaker/Clients/Locations/AllLocations.cs b/utils/SubmissionsFaker/Clients/Locations/AllLocations.cs new file mode 100644 index 000000000..2f602e73b --- /dev/null +++ b/utils/SubmissionsFaker/Clients/Locations/AllLocations.cs @@ -0,0 +1,8 @@ +namespace SubmissionsFaker.Clients.Locations; + +public class AllLocations +{ + public Guid ElectionRoundId { get; set; } + public string Version { get; set; } + public List Nodes { get; set; } = []; +} diff --git a/utils/SubmissionsFaker/Clients/Locations/ILocationsApi.cs b/utils/SubmissionsFaker/Clients/Locations/ILocationsApi.cs new file mode 100644 index 000000000..9c3045825 --- /dev/null +++ b/utils/SubmissionsFaker/Clients/Locations/ILocationsApi.cs @@ -0,0 +1,9 @@ +using Refit; + +namespace SubmissionsFaker.Clients.Locations; + +public interface ILocationsApi +{ + [Get("/api/election-rounds/{electionRoundId}/locations:fetchAll")] + Task GetAllLocations([AliasAs("electionRoundId")] string electionRoundId, [Authorize] string token); +} \ No newline at end of file diff --git a/utils/SubmissionsFaker/Clients/Locations/LocationNode.cs b/utils/SubmissionsFaker/Clients/Locations/LocationNode.cs new file mode 100644 index 000000000..a3cb56ab2 --- /dev/null +++ b/utils/SubmissionsFaker/Clients/Locations/LocationNode.cs @@ -0,0 +1,10 @@ +namespace SubmissionsFaker.Clients.Locations; + +public class LocationNode +{ + public int Id { get; set; } + public int Depth { get; set; } + public int? ParentId { get; set; } + public Guid? LocationId { get; set; } + public int? DisplayOrder { get; set; } +} diff --git a/utils/SubmissionsFaker/Clients/PlatformAdmin/IPlatformAdminApi.cs b/utils/SubmissionsFaker/Clients/PlatformAdmin/IPlatformAdminApi.cs index 91e0036a0..892dea342 100644 --- a/utils/SubmissionsFaker/Clients/PlatformAdmin/IPlatformAdminApi.cs +++ b/utils/SubmissionsFaker/Clients/PlatformAdmin/IPlatformAdminApi.cs @@ -17,21 +17,31 @@ public interface IPlatformAdminApi [Multipart] [Post("/api/election-rounds/{electionRoundId}/polling-stations:import")] - Task CreatePollingStations([AliasAs("electionRoundId")] string electionRoundId, [AliasAs("File")] StreamPart stream, [Authorize] string token); + Task ImportPollingStations([AliasAs("electionRoundId")] string electionRoundId, [AliasAs("File")] StreamPart stream, + [Authorize] string token); + + [Multipart] + [Post("/api/election-rounds/{electionRoundId}/locations:import")] + Task ImportLocations([AliasAs("electionRoundId")] string electionRoundId, [AliasAs("File")] StreamPart stream, + [Authorize] string token); [Post("/api/observers")] Task CreateObserver([Body] ApplicationUser observer, [Authorize] string token); - + [Post("/api/election-rounds/{electionRoundId}/monitoring-ngos")] - Task AssignNgoToElectionRound([AliasAs("electionRoundId")] string electionRoundId, [Body] AssignNgoRequest request, [Authorize] string token); - + Task AssignNgoToElectionRound([AliasAs("electionRoundId")] string electionRoundId, + [Body] AssignNgoRequest request, [Authorize] string token); + [Post("/api/election-rounds/{electionRoundId}:enableCitizenReporting")] - Task EnableCitizenReporting([AliasAs("electionRoundId")] string electionRoundId, [Body] EnableCitizenReportingRequest request, [Authorize] string token); + Task EnableCitizenReporting([AliasAs("electionRoundId")] string electionRoundId, + [Body] EnableCitizenReportingRequest request, [Authorize] string token); [Post("/api/election-rounds/{electionRoundId}/monitoring-ngos/{monitoringNgoId}/monitoring-observers")] - Task AssignObserverToMonitoring([AliasAs("electionRoundId")] string electionRoundId, [AliasAs("monitoringNgoId")] string monitoringNgoId, [Body]AssignObserverRequest request, [Authorize] string token); + Task AssignObserverToMonitoring([AliasAs("electionRoundId")] string electionRoundId, + [AliasAs("monitoringNgoId")] string monitoringNgoId, [Body] AssignObserverRequest request, + [Authorize] string token); [Post("/api/election-rounds/{electionRoundId}/polling-station-information-form")] - Task CreatePSIForm([AliasAs("electionRoundId")] string electionRoundId, [Body] UpsertPSIFormRequest psiFormRequest, [Authorize] string token); - + Task CreatePSIForm([AliasAs("electionRoundId")] string electionRoundId, [Body] UpsertPSIFormRequest psiFormRequest, + [Authorize] string token); } \ No newline at end of file diff --git a/utils/SubmissionsFaker/Clients/PollingStations/AllPollingStations.cs b/utils/SubmissionsFaker/Clients/PollingStations/AllPollingStations.cs index 4be9fe729..79f3ed018 100644 --- a/utils/SubmissionsFaker/Clients/PollingStations/AllPollingStations.cs +++ b/utils/SubmissionsFaker/Clients/PollingStations/AllPollingStations.cs @@ -4,5 +4,5 @@ public class AllPollingStations { public Guid ElectionRoundId { get; set; } public string Version { get; set; } - public List Nodes { get; set; } = []; + public List Nodes { get; set; } = []; } diff --git a/utils/SubmissionsFaker/Clients/PollingStations/LocationNode.cs b/utils/SubmissionsFaker/Clients/PollingStations/PollingStationNode.cs similarity index 91% rename from utils/SubmissionsFaker/Clients/PollingStations/LocationNode.cs rename to utils/SubmissionsFaker/Clients/PollingStations/PollingStationNode.cs index 8238df580..572236051 100644 --- a/utils/SubmissionsFaker/Clients/PollingStations/LocationNode.cs +++ b/utils/SubmissionsFaker/Clients/PollingStations/PollingStationNode.cs @@ -1,6 +1,6 @@ namespace SubmissionsFaker.Clients.PollingStations; -public class LocationNode +public class PollingStationNode { public int Id { get; set; } public string Name { get; set; } diff --git a/utils/SubmissionsFaker/Consts.cs b/utils/SubmissionsFaker/Consts.cs index 6a838bf3a..509eb4f61 100644 --- a/utils/SubmissionsFaker/Consts.cs +++ b/utils/SubmissionsFaker/Consts.cs @@ -14,7 +14,9 @@ public class Consts public const int NUMBER_OF_NOTES = (int)(NUMBER_OF_OBSERVERS * 0.2) + 50; public const int NUMBER_OF_ATTACHMENTS = (int)(NUMBER_OF_OBSERVERS * 0.2) + 20; - public const int NUMBER_OF_CITIZEN_REPORTS = 230; + public const int NUMBER_OF_LOCATIONS_TO_VISIT = 200; // should be greater than NUMBER_OF_CITIZEN_REPORTS + + public const int NUMBER_OF_CITIZEN_REPORTS = 150; public const int NUMBER_OF_CITIZEN_REPORTS_NOTES = (int)(NUMBER_OF_CITIZEN_REPORTS * 0.2) + 50; public const int NUMBER_OF_CITIZEN_REPORTS_ATTACHMENTS = (int)(NUMBER_OF_CITIZEN_REPORTS * 0.2) + 20; } \ No newline at end of file diff --git a/utils/SubmissionsFaker/Fakers/CitizenReportsFaker.cs b/utils/SubmissionsFaker/Fakers/CitizenReportsFaker.cs index 58f3ca29d..ffd8c64d1 100644 --- a/utils/SubmissionsFaker/Fakers/CitizenReportsFaker.cs +++ b/utils/SubmissionsFaker/Fakers/CitizenReportsFaker.cs @@ -1,5 +1,6 @@ using Bogus; using SubmissionsFaker.Clients.Citizen.Models; +using SubmissionsFaker.Clients.Locations; using SubmissionsFaker.Clients.MonitoringObserver.Models; using SubmissionsFaker.Clients.NgoAdmin.Models; @@ -7,13 +8,16 @@ namespace SubmissionsFaker.Fakers; public sealed class CitizenReportsFaker : Faker { - public CitizenReportsFaker(List forms) + public CitizenReportsFaker(List forms, List locations) { Rules((f, x) => { var form = f.PickRandom(forms); + x.CitizenReportId = f.Random.Guid().ToString(); x.FormId = form.Id; + x.LocationId = f.PickRandom(locations).LocationId!.Value; + x.Answers = f.PickRandom(form.Questions, f.Random.Int(0, form.Questions.Count)) .Select(Answers.GetFakeAnswer).ToList(); }); diff --git a/utils/SubmissionsFaker/Fakers/QuickReportFaker.cs b/utils/SubmissionsFaker/Fakers/QuickReportFaker.cs index 9587fa443..c700258ed 100644 --- a/utils/SubmissionsFaker/Fakers/QuickReportFaker.cs +++ b/utils/SubmissionsFaker/Fakers/QuickReportFaker.cs @@ -7,7 +7,7 @@ namespace SubmissionsFaker.Fakers; public sealed class QuickReportFaker : Faker { - public QuickReportFaker(List pollingStations, List observers) + public QuickReportFaker(List pollingStations, List observers) { RuleFor(x => x.PollingStationId, f => f.PickRandom(pollingStations).PollingStationId!); RuleFor(x => x.Id, f => f.Random.Guid()); diff --git a/utils/SubmissionsFaker/Fakers/SubmissionFaker.cs b/utils/SubmissionsFaker/Fakers/SubmissionFaker.cs index 651e7dc11..7d7ab6a8a 100644 --- a/utils/SubmissionsFaker/Fakers/SubmissionFaker.cs +++ b/utils/SubmissionsFaker/Fakers/SubmissionFaker.cs @@ -8,7 +8,7 @@ namespace SubmissionsFaker.Fakers; public sealed class SubmissionFaker : Faker { - public SubmissionFaker(List forms, List pollingStations, + public SubmissionFaker(List forms, List pollingStations, List observers) { RuleFor(x => x.PollingStationId, f => f.PickRandom(pollingStations).PollingStationId!); diff --git a/utils/SubmissionsFaker/Program.cs b/utils/SubmissionsFaker/Program.cs index ed37cff62..f7e89c984 100644 --- a/utils/SubmissionsFaker/Program.cs +++ b/utils/SubmissionsFaker/Program.cs @@ -3,6 +3,7 @@ using Spectre.Console; using SubmissionsFaker; using SubmissionsFaker.Clients.Citizen; +using SubmissionsFaker.Clients.Locations; using SubmissionsFaker.Clients.Models; using SubmissionsFaker.Clients.MonitoringObserver; using SubmissionsFaker.Clients.NgoAdmin; @@ -16,10 +17,11 @@ using SubmissionsFaker.Seeders; using Credentials = SubmissionsFaker.Clients.Token.Credentials; -ProgressColumn[] progressColumns = [ - new TaskDescriptionColumn(), // Task description - new ProgressBarColumn(), // Progress bar - new PercentageColumn(), // Percentage +ProgressColumn[] progressColumns = +[ + new TaskDescriptionColumn(), // Task description + new ProgressBarColumn(), // Progress bar + new PercentageColumn(), // Percentage new SpinnerColumn() // Spinner ]; @@ -31,6 +33,7 @@ var faker = new Faker(); #region constants + const string platformAdminUsername = "john.doe@example.com"; const string platformAdminPassword = "password123"; @@ -53,6 +56,7 @@ #endregion #region setup clients + var client = new HttpClient { BaseAddress = new Uri("https://localhost:7123") @@ -61,20 +65,25 @@ var tokenApi = RestService.For(client); var platformAdminApi = RestService.For(client); var pollingStationsApi = RestService.For(client); +var locationsApi = RestService.For(client); var ngoAdminApi = RestService.For(client); var observerApi = RestService.For(client); var citizenReportApi = RestService.For(client); + #endregion #region authorize platform admin + var platformAdminToken = await tokenApi.GetToken(new Credentials(platformAdminUsername, platformAdminPassword)); + #endregion CreateResponse electionRound = default!; CreateResponse ngo = default!; CreateResponse monitoringNgo = default!; LoginResponse ngoAdminToken = default!; -List pollingStations = []; +List pollingStations = []; +List locations = []; List forms = []; List citizenReportingForms = []; List observersTokens = []; @@ -88,9 +97,10 @@ await AnsiConsole.Progress() .Columns(progressColumns) .StartAsync(async ctx => { - var setupTask = ctx.AddTask("[green]Setup election round and NGO [/]", maxValue: 8); + var setupTask = ctx.AddTask("[green]Setup election round and NGO [/]", maxValue: 9); - electionRound = await platformAdminApi.CreateElectionRound(new ElectionRoundFaker().Generate(), platformAdminToken.Token); + electionRound = + await platformAdminApi.CreateElectionRound(new ElectionRoundFaker().Generate(), platformAdminToken.Token); setupTask.Increment(1); await platformAdminApi.CreatePSIForm(electionRound.Id, PSIFormData.PSIForm, platformAdminToken.Token); @@ -99,10 +109,12 @@ await AnsiConsole.Progress() ngo = await platformAdminApi.CreateNgo(new NgoFaker().Generate(), platformAdminToken.Token); setupTask.Increment(1); - monitoringNgo = await platformAdminApi.AssignNgoToElectionRound(electionRound.Id, new AssignNgoRequest(ngo.Id), platformAdminToken.Token); + monitoringNgo = await platformAdminApi.AssignNgoToElectionRound(electionRound.Id, new AssignNgoRequest(ngo.Id), + platformAdminToken.Token); setupTask.Increment(1); - - await platformAdminApi.EnableCitizenReporting(electionRound.Id, new EnableCitizenReportingRequest(ngo.Id), platformAdminToken.Token); + + await platformAdminApi.EnableCitizenReporting(electionRound.Id, new EnableCitizenReportingRequest(ngo.Id), + platformAdminToken.Token); setupTask.Increment(1); var ngoAdmin = new ApplicationUserFaker(ngoAdminUsername, ngoAdminPassword).Generate(); @@ -112,15 +124,37 @@ await AnsiConsole.Progress() ngoAdminToken = await tokenApi.GetToken(new Credentials(ngoAdminUsername, ngoAdminPassword)); setupTask.Increment(1); + #region import polling stations + using var pollingStationsStream = File.OpenRead("polling-stations.csv"); - await platformAdminApi.CreatePollingStations(electionRound.Id, new StreamPart(pollingStationsStream, "polling-stations.csv", "text/csv"), platformAdminToken.Token); + await platformAdminApi.ImportPollingStations(electionRound.Id, + new StreamPart(pollingStationsStream, "polling-stations.csv", "text/csv"), platformAdminToken.Token); - var pollingStationNodes = await pollingStationsApi.GetAllPollingStations(electionRound.Id, platformAdminToken.Token); + var pollingStationNodes = + await pollingStationsApi.GetAllPollingStations(electionRound.Id, platformAdminToken.Token); pollingStations = faker - .PickRandom(pollingStationNodes.Nodes.Where(x => x.PollingStationId.HasValue).ToList(), Consts.NUMBER_OF_POLLING_STATIONS_TO_VISIT) + .PickRandom(pollingStationNodes.Nodes.Where(x => x.PollingStationId.HasValue).ToList(), + Consts.NUMBER_OF_POLLING_STATIONS_TO_VISIT) + .ToList(); + + setupTask.Increment(1); + + #endregion + + #region import locations + + using var locationsStream = File.OpenRead("locations.csv"); + await platformAdminApi.ImportLocations(electionRound.Id, new StreamPart(locationsStream, "locations.csv", "text/csv"), platformAdminToken.Token); + + var locationsNodes = await locationsApi.GetAllLocations(electionRound.Id, platformAdminToken.Token); + locations = faker + .PickRandom(locationsNodes.Nodes.Where(x => x.LocationId.HasValue).ToList(), + Consts.NUMBER_OF_LOCATIONS_TO_VISIT) .ToList(); setupTask.Increment(1); + + #endregion }); await AnsiConsole.Progress() @@ -142,7 +176,8 @@ await AnsiConsole.Progress() .StartAsync(async ctx => { var formsTask = ctx.AddTask("[green]Creating citizen reporting forms[/]", autoStart: false); - citizenReportingForms = await CitizenReportingFormSeeder.Seed(ngoAdminApi, ngoAdminToken, electionRound.Id, formsTask); + citizenReportingForms = + await CitizenReportingFormSeeder.Seed(ngoAdminApi, ngoAdminToken, electionRound.Id, formsTask); }); await AnsiConsole.Progress() @@ -152,7 +187,8 @@ await AnsiConsole.Progress() .Columns(progressColumns) .StartAsync(async ctx => { - var observersTask = ctx.AddTask("[green]Seeding observers[/]", maxValue: Consts.NUMBER_OF_OBSERVERS, autoStart: false); + var observersTask = ctx.AddTask("[green]Seeding observers[/]", maxValue: Consts.NUMBER_OF_OBSERVERS, + autoStart: false); await ObserversSeeder.Seed(platformAdminApi, platformAdminToken, observers, electionRound.Id, monitoringNgo.Id, observersTask); @@ -186,9 +222,11 @@ await AnsiConsole.Progress() .GenerateUnique(Consts.NUMBER_OF_SUBMISSIONS); var psiRequests = - submissionRequests.Select(x => new PISSubmissionFaker(PSIFormData.PSIForm, x.PollingStationId, x.ObserverToken).Generate()).ToList(); + submissionRequests + .Select(x => new PISSubmissionFaker(PSIFormData.PSIForm, x.PollingStationId, x.ObserverToken).Generate()) + .ToList(); -var noteRequests = new NoteFaker(submissionRequests.Where(x=>x.Answers.Any()).ToList()) +var noteRequests = new NoteFaker(submissionRequests.Where(x => x.Answers.Any()).ToList()) .Generate(Consts.NUMBER_OF_NOTES); var attachmentRequests = new AttachmentFaker(submissionRequests.Where(x => x.Answers.Any()).ToList()) @@ -200,15 +238,32 @@ await AnsiConsole.Progress() var quickReportAttachmentRequests = new QuickReportAttachmentFaker(quickReportRequests) .GenerateUnique(Consts.NUMBER_OF_QUICK_REPORTS_ATTACHMENTS); -var citizenReportRequests = new CitizenReportsFaker(citizenReportingForms) +var citizenReportRequests = new CitizenReportsFaker(citizenReportingForms, locations) .GenerateUnique(Consts.NUMBER_OF_CITIZEN_REPORTS); -var citizenReportNoteRequests = new CitizenReportNoteFaker(citizenReportRequests.Where(x=>x.Answers.Any()).ToList()) +var citizenReportNoteRequests = new CitizenReportNoteFaker(citizenReportRequests.Where(x => x.Answers.Any()).ToList()) .Generate(Consts.NUMBER_OF_CITIZEN_REPORTS_NOTES); -var citizenReportAttachmentRequests = new CitizenReportAttachmentFaker(citizenReportRequests.Where(x => x.Answers.Any()).ToList()) - .Generate(Consts.NUMBER_OF_CITIZEN_REPORTS_ATTACHMENTS); +var citizenReportAttachmentRequests = + new CitizenReportAttachmentFaker(citizenReportRequests.Where(x => x.Answers.Any()).ToList()) + .Generate(Consts.NUMBER_OF_CITIZEN_REPORTS_ATTACHMENTS); +await AnsiConsole.Progress() + .AutoRefresh(true) + .AutoClear(false) + .HideCompleted(false) + .Columns(progressColumns) + .StartAsync(async ctx => + { + var progressTask = ctx.AddTask("[green]Faking PSI submissions [/]", maxValue: Consts.NUMBER_OF_SUBMISSIONS); + foreach (var submissionRequestChunk in psiRequests.Chunk(Consts.CHUNK_SIZE)) + { + var tasks = submissionRequestChunk.Select(sr => observerApi.SubmitPSIForm(electionRound.Id, sr.PollingStationId, sr, sr.ObserverToken)); + + await Task.WhenAll(tasks); + progressTask.Increment(Consts.CHUNK_SIZE); + } + }); await AnsiConsole.Progress() .AutoRefresh(true) @@ -220,7 +275,8 @@ await AnsiConsole.Progress() var progressTask = ctx.AddTask("[green]Faking submissions [/]", maxValue: Consts.NUMBER_OF_SUBMISSIONS); foreach (var submissionRequestChunk in submissionRequests.Chunk(Consts.CHUNK_SIZE)) { - var tasks = submissionRequestChunk.Select(sr => observerApi.SubmitForm(electionRound.Id, sr, sr.ObserverToken)); + var tasks = submissionRequestChunk.Select(sr => + observerApi.SubmitForm(electionRound.Id, sr, sr.ObserverToken)); await Task.WhenAll(tasks); progressTask.Increment(Consts.CHUNK_SIZE); @@ -294,7 +350,8 @@ await AnsiConsole.Progress() .Columns(progressColumns) .StartAsync(async ctx => { - var progressTask = ctx.AddTask("[green]Faking citizen reports notes[/]", maxValue: Consts.NUMBER_OF_CITIZEN_REPORTS_NOTES); + var progressTask = ctx.AddTask("[green]Faking citizen reports notes[/]", + maxValue: Consts.NUMBER_OF_CITIZEN_REPORTS_NOTES); foreach (var notesChunk in citizenReportNoteRequests.Chunk(Consts.CHUNK_SIZE)) { @@ -304,7 +361,6 @@ await AnsiConsole.Progress() } }); - await AnsiConsole.Progress() .AutoRefresh(true) .AutoClear(false) @@ -316,7 +372,8 @@ await AnsiConsole.Progress() foreach (var quickReportChunk in quickReportRequests.Chunk(Consts.CHUNK_SIZE)) { - var tasks = quickReportChunk.Select(qr => observerApi.SubmitQuickReport(electionRound.Id, qr, qr.ObserverToken)); + var tasks = quickReportChunk.Select(qr => + observerApi.SubmitQuickReport(electionRound.Id, qr, qr.ObserverToken)); await Task.WhenAll(tasks); progressTask.Increment(Consts.CHUNK_SIZE); } @@ -329,17 +386,19 @@ await AnsiConsole.Progress() .Columns(progressColumns) .StartAsync(async ctx => { - var progressTask = ctx.AddTask("[green]Faking quick report attachments[/]", maxValue: Consts.NUMBER_OF_QUICK_REPORTS_ATTACHMENTS); + var progressTask = ctx.AddTask("[green]Faking quick report attachments[/]", + maxValue: Consts.NUMBER_OF_QUICK_REPORTS_ATTACHMENTS); foreach (var qar in quickReportAttachmentRequests) { var fileName = faker.PickRandom(images); await using var fs = File.OpenRead(Path.Combine("Attachments", fileName)); - await observerApi.SubmitQuickReportAttachment(electionRound.Id, qar.QuickReportId.ToString(), qar.Id.ToString(), new StreamPart(fs, fileName, "image/jpeg"), qar.ObserverToken); + await observerApi.SubmitQuickReportAttachment(electionRound.Id, qar.QuickReportId.ToString(), + qar.Id.ToString(), new StreamPart(fs, fileName, "image/jpeg"), qar.ObserverToken); progressTask.Increment(1); } }); var rule = new Rule("[red]Finished[/]"); -AnsiConsole.Write(rule); +AnsiConsole.Write(rule); \ No newline at end of file diff --git a/utils/SubmissionsFaker/SubmissionsFaker.csproj b/utils/SubmissionsFaker/SubmissionsFaker.csproj index aaaed1510..08c997908 100644 --- a/utils/SubmissionsFaker/SubmissionsFaker.csproj +++ b/utils/SubmissionsFaker/SubmissionsFaker.csproj @@ -49,6 +49,9 @@ Always + + Always + diff --git a/utils/SubmissionsFaker/locations.csv b/utils/SubmissionsFaker/locations.csv new file mode 100644 index 000000000..90a406ac0 --- /dev/null +++ b/utils/SubmissionsFaker/locations.csv @@ -0,0 +1,2594 @@ +Level1,Level2,Level3,Level4,Level5,DisplayOrder +Polonia,dolnośląskie,bolesławiecki,m. Bolesławiec,,1 +Polonia,dolnośląskie,bolesławiecki,gm. Bolesławiec,,2 +Polonia,dolnośląskie,bolesławiecki,gm. Gromadka,,3 +Polonia,dolnośląskie,bolesławiecki,gm. Nowogrodziec,,4 +Polonia,dolnośląskie,bolesławiecki,gm. Osiecznica,,5 +Polonia,dolnośląskie,bolesławiecki,gm. Warta Bolesławiecka,,6 +Polonia,dolnośląskie,dzierżoniowski,m. Bielawa,,7 +Polonia,dolnośląskie,dzierżoniowski,m. Dzierżoniów,,8 +Polonia,dolnośląskie,dzierżoniowski,gm. Pieszyce,,9 +Polonia,dolnośląskie,dzierżoniowski,m. Piława Górna,,10 +Polonia,dolnośląskie,dzierżoniowski,gm. Dzierżoniów,,11 +Polonia,dolnośląskie,dzierżoniowski,gm. Łagiewniki,,12 +Polonia,dolnośląskie,dzierżoniowski,gm. Niemcza,,13 +Polonia,dolnośląskie,głogowski,m. Głogów,,14 +Polonia,dolnośląskie,głogowski,gm. Głogów,,15 +Polonia,dolnośląskie,głogowski,gm. Jerzmanowa,,16 +Polonia,dolnośląskie,głogowski,gm. Kotla,,17 +Polonia,dolnośląskie,głogowski,gm. Pęcław,,18 +Polonia,dolnośląskie,głogowski,gm. Żukowice,,19 +Polonia,dolnośląskie,górowski,gm. Góra,,20 +Polonia,dolnośląskie,górowski,gm. Jemielno,,21 +Polonia,dolnośląskie,górowski,gm. Niechlów,,22 +Polonia,dolnośląskie,górowski,gm. Wąsosz,,23 +Polonia,dolnośląskie,jaworski,m. Jawor,,24 +Polonia,dolnośląskie,jaworski,gm. Bolków,,25 +Polonia,dolnośląskie,jaworski,gm. Męcinka,,26 +Polonia,dolnośląskie,jaworski,gm. Mściwojów,,27 +Polonia,dolnośląskie,jaworski,gm. Paszowice,,28 +Polonia,dolnośląskie,jaworski,gm. Wądroże Wielkie,,29 +Polonia,dolnośląskie,karkonoski,m. Karpacz,,30 +Polonia,dolnośląskie,karkonoski,m. Kowary,,31 +Polonia,dolnośląskie,karkonoski,m. Piechowice,,32 +Polonia,dolnośląskie,karkonoski,m. Szklarska Poręba,,33 +Polonia,dolnośląskie,karkonoski,gm. Janowice Wielkie,,34 +Polonia,dolnośląskie,karkonoski,gm. Jeżów Sudecki,,35 +Polonia,dolnośląskie,karkonoski,gm. Mysłakowice,,36 +Polonia,dolnośląskie,karkonoski,gm. Podgórzyn,,37 +Polonia,dolnośląskie,karkonoski,gm. Stara Kamienica,,38 +Polonia,dolnośląskie,kamiennogórski,m. Kamienna Góra,,39 +Polonia,dolnośląskie,kamiennogórski,gm. Kamienna Góra,,40 +Polonia,dolnośląskie,kamiennogórski,gm. Lubawka,,41 +Polonia,dolnośląskie,kamiennogórski,gm. Marciszów,,42 +Polonia,dolnośląskie,kłodzki,m. Duszniki-Zdrój,,43 +Polonia,dolnośląskie,kłodzki,m. Kłodzko,,44 +Polonia,dolnośląskie,kłodzki,m. Kudowa-Zdrój,,45 +Polonia,dolnośląskie,kłodzki,m. Nowa Ruda,,46 +Polonia,dolnośląskie,kłodzki,m. Polanica-Zdrój,,47 +Polonia,dolnośląskie,kłodzki,gm. Bystrzyca Kłodzka,,48 +Polonia,dolnośląskie,kłodzki,gm. Kłodzko,,49 +Polonia,dolnośląskie,kłodzki,gm. Lądek-Zdrój,,50 +Polonia,dolnośląskie,kłodzki,gm. Lewin Kłodzki,,51 +Polonia,dolnośląskie,kłodzki,gm. Międzylesie,,52 +Polonia,dolnośląskie,kłodzki,gm. Nowa Ruda,,53 +Polonia,dolnośląskie,kłodzki,gm. Radków,,54 +Polonia,dolnośląskie,kłodzki,gm. Stronie Śląskie,,55 +Polonia,dolnośląskie,kłodzki,gm. Szczytna,,56 +Polonia,dolnośląskie,legnicki,m. Chojnów,,57 +Polonia,dolnośląskie,legnicki,gm. Chojnów,,58 +Polonia,dolnośląskie,legnicki,gm. Krotoszyce,,59 +Polonia,dolnośląskie,legnicki,gm. Kunice,,60 +Polonia,dolnośląskie,legnicki,gm. Legnickie Pole,,61 +Polonia,dolnośląskie,legnicki,gm. Miłkowice,,62 +Polonia,dolnośląskie,legnicki,gm. Prochowice,,63 +Polonia,dolnośląskie,legnicki,gm. Ruja,,64 +Polonia,dolnośląskie,lubański,m. Lubań,,65 +Polonia,dolnośląskie,lubański,m. Świeradów-Zdrój,,66 +Polonia,dolnośląskie,lubański,gm. Leśna,,67 +Polonia,dolnośląskie,lubański,gm. Lubań,,68 +Polonia,dolnośląskie,lubański,gm. Olszyna,,69 +Polonia,dolnośląskie,lubański,gm. Platerówka,,70 +Polonia,dolnośląskie,lubański,gm. Siekierczyn,,71 +Polonia,dolnośląskie,lubiński,m. Lubin,,72 +Polonia,dolnośląskie,lubiński,gm. Lubin,,73 +Polonia,dolnośląskie,lubiński,gm. Rudna,,74 +Polonia,dolnośląskie,lubiński,gm. Ścinawa,,75 +Polonia,dolnośląskie,lwówecki,gm. Gryfów Śląski,,76 +Polonia,dolnośląskie,lwówecki,gm. Lubomierz,,77 +Polonia,dolnośląskie,lwówecki,gm. Lwówek Śląski,,78 +Polonia,dolnośląskie,lwówecki,gm. Mirsk,,79 +Polonia,dolnośląskie,lwówecki,gm. Wleń,,80 +Polonia,dolnośląskie,milicki,gm. Cieszków,,81 +Polonia,dolnośląskie,milicki,gm. Krośnice,,82 +Polonia,dolnośląskie,milicki,gm. Milicz,,83 +Polonia,dolnośląskie,oleśnicki,m. Oleśnica,,84 +Polonia,dolnośląskie,oleśnicki,gm. Bierutów,,85 +Polonia,dolnośląskie,oleśnicki,gm. Dobroszyce,,86 +Polonia,dolnośląskie,oleśnicki,gm. Dziadowa Kłoda,,87 +Polonia,dolnośląskie,oleśnicki,gm. Międzybórz,,88 +Polonia,dolnośląskie,oleśnicki,gm. Oleśnica,,89 +Polonia,dolnośląskie,oleśnicki,gm. Syców,,90 +Polonia,dolnośląskie,oleśnicki,gm. Twardogóra,,91 +Polonia,dolnośląskie,oławski,m. Oława,,92 +Polonia,dolnośląskie,oławski,gm. Domaniów,,93 +Polonia,dolnośląskie,oławski,gm. Jelcz-Laskowice,,94 +Polonia,dolnośląskie,oławski,gm. Oława,,95 +Polonia,dolnośląskie,polkowicki,gm. Chocianów,,96 +Polonia,dolnośląskie,polkowicki,gm. Gaworzyce,,97 +Polonia,dolnośląskie,polkowicki,gm. Grębocice,,98 +Polonia,dolnośląskie,polkowicki,gm. Polkowice,,99 +Polonia,dolnośląskie,polkowicki,gm. Przemków,,100 +Polonia,dolnośląskie,polkowicki,gm. Radwanice,,101 +Polonia,dolnośląskie,strzeliński,gm. Borów,,102 +Polonia,dolnośląskie,strzeliński,gm. Kondratowice,,103 +Polonia,dolnośląskie,strzeliński,gm. Przeworno,,104 +Polonia,dolnośląskie,strzeliński,gm. Strzelin,,105 +Polonia,dolnośląskie,strzeliński,gm. Wiązów,,106 +Polonia,dolnośląskie,średzki,gm. Kostomłoty,,107 +Polonia,dolnośląskie,średzki,gm. Malczyce,,108 +Polonia,dolnośląskie,średzki,gm. Miękinia,,109 +Polonia,dolnośląskie,średzki,gm. Środa Śląska,,110 +Polonia,dolnośląskie,średzki,gm. Udanin,,111 +Polonia,dolnośląskie,świdnicki,m. Świdnica,,112 +Polonia,dolnośląskie,świdnicki,m. Świebodzice,,113 +Polonia,dolnośląskie,świdnicki,gm. Dobromierz,,114 +Polonia,dolnośląskie,świdnicki,gm. Jaworzyna Śląska,,115 +Polonia,dolnośląskie,świdnicki,gm. Marcinowice,,116 +Polonia,dolnośląskie,świdnicki,gm. Strzegom,,117 +Polonia,dolnośląskie,świdnicki,gm. Świdnica,,118 +Polonia,dolnośląskie,świdnicki,gm. Żarów,,119 +Polonia,dolnośląskie,trzebnicki,gm. Oborniki Śląskie,,120 +Polonia,dolnośląskie,trzebnicki,gm. Prusice,,121 +Polonia,dolnośląskie,trzebnicki,gm. Trzebnica,,122 +Polonia,dolnośląskie,trzebnicki,gm. Wisznia Mała,,123 +Polonia,dolnośląskie,trzebnicki,gm. Zawonia,,124 +Polonia,dolnośląskie,trzebnicki,gm. Żmigród,,125 +Polonia,dolnośląskie,wałbrzyski,m. Boguszów-Gorce,,126 +Polonia,dolnośląskie,wałbrzyski,m. Jedlina-Zdrój,,127 +Polonia,dolnośląskie,wałbrzyski,m. Szczawno-Zdrój,,128 +Polonia,dolnośląskie,wałbrzyski,gm. Czarny Bór,,129 +Polonia,dolnośląskie,wałbrzyski,gm. Głuszyca,,130 +Polonia,dolnośląskie,wałbrzyski,gm. Mieroszów,,131 +Polonia,dolnośląskie,wałbrzyski,gm. Stare Bogaczowice,,132 +Polonia,dolnośląskie,wałbrzyski,gm. Walim,,133 +Polonia,dolnośląskie,wołowski,gm. Brzeg Dolny,,134 +Polonia,dolnośląskie,wołowski,gm. Wińsko,,135 +Polonia,dolnośląskie,wołowski,gm. Wołów,,136 +Polonia,dolnośląskie,wrocławski,gm. Czernica,,137 +Polonia,dolnośląskie,wrocławski,gm. Długołęka,,138 +Polonia,dolnośląskie,wrocławski,gm. Jordanów Śląski,,139 +Polonia,dolnośląskie,wrocławski,gm. Kąty Wrocławskie,,140 +Polonia,dolnośląskie,wrocławski,gm. Kobierzyce,,141 +Polonia,dolnośląskie,wrocławski,gm. Mietków,,142 +Polonia,dolnośląskie,wrocławski,gm. Sobótka,,143 +Polonia,dolnośląskie,wrocławski,gm. Siechnice,,144 +Polonia,dolnośląskie,wrocławski,gm. Żórawina,,145 +Polonia,dolnośląskie,ząbkowicki,gm. Bardo,,146 +Polonia,dolnośląskie,ząbkowicki,gm. Ciepłowody,,147 +Polonia,dolnośląskie,ząbkowicki,gm. Kamieniec Ząbkowicki,,148 +Polonia,dolnośląskie,ząbkowicki,gm. Stoszowice,,149 +Polonia,dolnośląskie,ząbkowicki,gm. Ząbkowice Śląskie,,150 +Polonia,dolnośląskie,ząbkowicki,gm. Ziębice,,151 +Polonia,dolnośląskie,ząbkowicki,gm. Złoty Stok,,152 +Polonia,dolnośląskie,zgorzelecki,m. Zawidów,,153 +Polonia,dolnośląskie,zgorzelecki,m. Zgorzelec,,154 +Polonia,dolnośląskie,zgorzelecki,gm. Bogatynia,,155 +Polonia,dolnośląskie,zgorzelecki,gm. Pieńsk,,156 +Polonia,dolnośląskie,zgorzelecki,gm. Sulików,,157 +Polonia,dolnośląskie,zgorzelecki,gm. Węgliniec,,158 +Polonia,dolnośląskie,zgorzelecki,gm. Zgorzelec,,159 +Polonia,dolnośląskie,złotoryjski,m. Wojcieszów,,160 +Polonia,dolnośląskie,złotoryjski,m. Złotoryja,,161 +Polonia,dolnośląskie,złotoryjski,gm. Pielgrzymka,,162 +Polonia,dolnośląskie,złotoryjski,gm. Świerzawa,,163 +Polonia,dolnośląskie,złotoryjski,gm. Zagrodno,,164 +Polonia,dolnośląskie,złotoryjski,gm. Złotoryja,,165 +Polonia,dolnośląskie,Jelenia Góra,m. Jelenia Góra,,166 +Polonia,dolnośląskie,Legnica,m. Legnica,,167 +Polonia,dolnośląskie,Wrocław,m. Wrocław,,168 +Polonia,dolnośląskie,Wałbrzych,m. Wałbrzych,,169 +Polonia,kujawsko-pomorskie,aleksandrowski,m. Aleksandrów Kujawski,,170 +Polonia,kujawsko-pomorskie,aleksandrowski,m. Ciechocinek,,171 +Polonia,kujawsko-pomorskie,aleksandrowski,m. Nieszawa,,172 +Polonia,kujawsko-pomorskie,aleksandrowski,gm. Aleksandrów Kujawski,,173 +Polonia,kujawsko-pomorskie,aleksandrowski,gm. Bądkowo,,174 +Polonia,kujawsko-pomorskie,aleksandrowski,gm. Koneck,,175 +Polonia,kujawsko-pomorskie,aleksandrowski,gm. Raciążek,,176 +Polonia,kujawsko-pomorskie,aleksandrowski,gm. Waganiec,,177 +Polonia,kujawsko-pomorskie,aleksandrowski,gm. Zakrzewo,,178 +Polonia,kujawsko-pomorskie,brodnicki,m. Brodnica,,179 +Polonia,kujawsko-pomorskie,brodnicki,gm. Bobrowo,,180 +Polonia,kujawsko-pomorskie,brodnicki,gm. Brodnica,,181 +Polonia,kujawsko-pomorskie,brodnicki,gm. Brzozie,,182 +Polonia,kujawsko-pomorskie,brodnicki,gm. Górzno,,183 +Polonia,kujawsko-pomorskie,brodnicki,gm. Bartniczka,,184 +Polonia,kujawsko-pomorskie,brodnicki,gm. Jabłonowo Pomorskie,,185 +Polonia,kujawsko-pomorskie,brodnicki,gm. Osiek,,186 +Polonia,kujawsko-pomorskie,brodnicki,gm. Świedziebnia,,187 +Polonia,kujawsko-pomorskie,brodnicki,gm. Zbiczno,,188 +Polonia,kujawsko-pomorskie,bydgoski,gm. Białe Błota,,189 +Polonia,kujawsko-pomorskie,bydgoski,gm. Dąbrowa Chełmińska,,190 +Polonia,kujawsko-pomorskie,bydgoski,gm. Dobrcz,,191 +Polonia,kujawsko-pomorskie,bydgoski,gm. Koronowo,,192 +Polonia,kujawsko-pomorskie,bydgoski,gm. Nowa Wieś Wielka,,193 +Polonia,kujawsko-pomorskie,bydgoski,gm. Osielsko,,194 +Polonia,kujawsko-pomorskie,bydgoski,gm. Sicienko,,195 +Polonia,kujawsko-pomorskie,bydgoski,gm. Solec Kujawski,,196 +Polonia,kujawsko-pomorskie,chełmiński,m. Chełmno,,197 +Polonia,kujawsko-pomorskie,chełmiński,gm. Chełmno,,198 +Polonia,kujawsko-pomorskie,chełmiński,gm. Kijewo Królewskie,,199 +Polonia,kujawsko-pomorskie,chełmiński,gm. Lisewo,,200 +Polonia,kujawsko-pomorskie,chełmiński,gm. Papowo Biskupie,,201 +Polonia,kujawsko-pomorskie,chełmiński,gm. Stolno,,202 +Polonia,kujawsko-pomorskie,chełmiński,gm. Unisław,,203 +Polonia,kujawsko-pomorskie,golubsko-dobrzyński,m. Golub-Dobrzyń,,204 +Polonia,kujawsko-pomorskie,golubsko-dobrzyński,gm. Ciechocin,,205 +Polonia,kujawsko-pomorskie,golubsko-dobrzyński,gm. Golub-Dobrzyń,,206 +Polonia,kujawsko-pomorskie,golubsko-dobrzyński,gm. Kowalewo Pomorskie,,207 +Polonia,kujawsko-pomorskie,golubsko-dobrzyński,gm. Radomin,,208 +Polonia,kujawsko-pomorskie,golubsko-dobrzyński,gm. Zbójno,,209 +Polonia,kujawsko-pomorskie,grudziądzki,gm. Grudziądz,,210 +Polonia,kujawsko-pomorskie,grudziądzki,gm. Gruta,,211 +Polonia,kujawsko-pomorskie,grudziądzki,gm. Łasin,,212 +Polonia,kujawsko-pomorskie,grudziądzki,gm. Radzyń Chełmiński,,213 +Polonia,kujawsko-pomorskie,grudziądzki,gm. Rogóźno,,214 +Polonia,kujawsko-pomorskie,grudziądzki,gm. Świecie nad Osą,,215 +Polonia,kujawsko-pomorskie,inowrocławski,m. Inowrocław,,216 +Polonia,kujawsko-pomorskie,inowrocławski,gm. Dąbrowa Biskupia,,217 +Polonia,kujawsko-pomorskie,inowrocławski,gm. Gniewkowo,,218 +Polonia,kujawsko-pomorskie,inowrocławski,gm. Inowrocław,,219 +Polonia,kujawsko-pomorskie,inowrocławski,gm. Janikowo,,220 +Polonia,kujawsko-pomorskie,inowrocławski,gm. Kruszwica,,221 +Polonia,kujawsko-pomorskie,inowrocławski,gm. Pakość,,222 +Polonia,kujawsko-pomorskie,inowrocławski,gm. Rojewo,,223 +Polonia,kujawsko-pomorskie,inowrocławski,gm. Złotniki Kujawskie,,224 +Polonia,kujawsko-pomorskie,lipnowski,m. Lipno,,225 +Polonia,kujawsko-pomorskie,lipnowski,gm. Bobrowniki,,226 +Polonia,kujawsko-pomorskie,lipnowski,gm. Chrostkowo,,227 +Polonia,kujawsko-pomorskie,lipnowski,gm. Dobrzyń nad Wisłą,,228 +Polonia,kujawsko-pomorskie,lipnowski,gm. Kikół,,229 +Polonia,kujawsko-pomorskie,lipnowski,gm. Lipno,,230 +Polonia,kujawsko-pomorskie,lipnowski,gm. Skępe,,231 +Polonia,kujawsko-pomorskie,lipnowski,gm. Tłuchowo,,232 +Polonia,kujawsko-pomorskie,lipnowski,gm. Wielgie,,233 +Polonia,kujawsko-pomorskie,mogileński,gm. Dąbrowa,,234 +Polonia,kujawsko-pomorskie,mogileński,gm. Jeziora Wielkie,,235 +Polonia,kujawsko-pomorskie,mogileński,gm. Mogilno,,236 +Polonia,kujawsko-pomorskie,mogileński,gm. Strzelno,,237 +Polonia,kujawsko-pomorskie,nakielski,gm. Kcynia,,238 +Polonia,kujawsko-pomorskie,nakielski,gm. Mrocza,,239 +Polonia,kujawsko-pomorskie,nakielski,gm. Nakło nad Notecią,,240 +Polonia,kujawsko-pomorskie,nakielski,gm. Sadki,,241 +Polonia,kujawsko-pomorskie,nakielski,gm. Szubin,,242 +Polonia,kujawsko-pomorskie,radziejowski,m. Radziejów,,243 +Polonia,kujawsko-pomorskie,radziejowski,gm. Bytoń,,244 +Polonia,kujawsko-pomorskie,radziejowski,gm. Dobre,,245 +Polonia,kujawsko-pomorskie,radziejowski,gm. Osięciny,,246 +Polonia,kujawsko-pomorskie,radziejowski,gm. Piotrków Kujawski,,247 +Polonia,kujawsko-pomorskie,radziejowski,gm. Radziejów,,248 +Polonia,kujawsko-pomorskie,radziejowski,gm. Topólka,,249 +Polonia,kujawsko-pomorskie,rypiński,m. Rypin,,250 +Polonia,kujawsko-pomorskie,rypiński,gm. Brzuze,,251 +Polonia,kujawsko-pomorskie,rypiński,gm. Rogowo,,252 +Polonia,kujawsko-pomorskie,rypiński,gm. Rypin,,253 +Polonia,kujawsko-pomorskie,rypiński,gm. Skrwilno,,254 +Polonia,kujawsko-pomorskie,rypiński,gm. Wąpielsk,,255 +Polonia,kujawsko-pomorskie,sępoleński,gm. Kamień Krajeński,,256 +Polonia,kujawsko-pomorskie,sępoleński,gm. Sępólno Krajeńskie,,257 +Polonia,kujawsko-pomorskie,sępoleński,gm. Sośno,,258 +Polonia,kujawsko-pomorskie,sępoleński,gm. Więcbork,,259 +Polonia,kujawsko-pomorskie,świecki,gm. Bukowiec,,260 +Polonia,kujawsko-pomorskie,świecki,gm. Dragacz,,261 +Polonia,kujawsko-pomorskie,świecki,gm. Drzycim,,262 +Polonia,kujawsko-pomorskie,świecki,gm. Jeżewo,,263 +Polonia,kujawsko-pomorskie,świecki,gm. Lniano,,264 +Polonia,kujawsko-pomorskie,świecki,gm. Nowe,,265 +Polonia,kujawsko-pomorskie,świecki,gm. Osie,,266 +Polonia,kujawsko-pomorskie,świecki,gm. Pruszcz,,267 +Polonia,kujawsko-pomorskie,świecki,gm. Świecie,,268 +Polonia,kujawsko-pomorskie,świecki,gm. Świekatowo,,269 +Polonia,kujawsko-pomorskie,świecki,gm. Warlubie,,270 +Polonia,kujawsko-pomorskie,toruński,m. Chełmża,,271 +Polonia,kujawsko-pomorskie,toruński,gm. Chełmża,,272 +Polonia,kujawsko-pomorskie,toruński,gm. Czernikowo,,273 +Polonia,kujawsko-pomorskie,toruński,gm. Lubicz,,274 +Polonia,kujawsko-pomorskie,toruński,gm. Łubianka,,275 +Polonia,kujawsko-pomorskie,toruński,gm. Łysomice,,276 +Polonia,kujawsko-pomorskie,toruński,gm. Obrowo,,277 +Polonia,kujawsko-pomorskie,toruński,gm. Wielka Nieszawka,,278 +Polonia,kujawsko-pomorskie,toruński,gm. Zławieś Wielka,,279 +Polonia,kujawsko-pomorskie,tucholski,gm. Cekcyn,,280 +Polonia,kujawsko-pomorskie,tucholski,gm. Gostycyn,,281 +Polonia,kujawsko-pomorskie,tucholski,gm. Kęsowo,,282 +Polonia,kujawsko-pomorskie,tucholski,gm. Lubiewo,,283 +Polonia,kujawsko-pomorskie,tucholski,gm. Śliwice,,284 +Polonia,kujawsko-pomorskie,tucholski,gm. Tuchola,,285 +Polonia,kujawsko-pomorskie,wąbrzeski,m. Wąbrzeźno,,286 +Polonia,kujawsko-pomorskie,wąbrzeski,gm. Dębowa Łąka,,287 +Polonia,kujawsko-pomorskie,wąbrzeski,gm. Książki,,288 +Polonia,kujawsko-pomorskie,wąbrzeski,gm. Płużnica,,289 +Polonia,kujawsko-pomorskie,wąbrzeski,gm. Ryńsk,,290 +Polonia,kujawsko-pomorskie,włocławski,m. Kowal,,291 +Polonia,kujawsko-pomorskie,włocławski,gm. Baruchowo,,292 +Polonia,kujawsko-pomorskie,włocławski,gm. Boniewo,,293 +Polonia,kujawsko-pomorskie,włocławski,gm. Brześć Kujawski,,294 +Polonia,kujawsko-pomorskie,włocławski,gm. Choceń,,295 +Polonia,kujawsko-pomorskie,włocławski,gm. Chodecz,,296 +Polonia,kujawsko-pomorskie,włocławski,gm. Fabianki,,297 +Polonia,kujawsko-pomorskie,włocławski,gm. Izbica Kujawska,,298 +Polonia,kujawsko-pomorskie,włocławski,gm. Kowal,,299 +Polonia,kujawsko-pomorskie,włocławski,gm. Lubanie,,300 +Polonia,kujawsko-pomorskie,włocławski,gm. Lubień Kujawski,,301 +Polonia,kujawsko-pomorskie,włocławski,gm. Lubraniec,,302 +Polonia,kujawsko-pomorskie,włocławski,gm. Włocławek,,303 +Polonia,kujawsko-pomorskie,żniński,gm. Barcin,,304 +Polonia,kujawsko-pomorskie,żniński,gm. Gąsawa,,305 +Polonia,kujawsko-pomorskie,żniński,gm. Janowiec Wielkopolski,,306 +Polonia,kujawsko-pomorskie,żniński,gm. Łabiszyn,,307 +Polonia,kujawsko-pomorskie,żniński,gm. Rogowo,,308 +Polonia,kujawsko-pomorskie,żniński,gm. Żnin,,309 +Polonia,kujawsko-pomorskie,Bydgoszcz,m. Bydgoszcz,,310 +Polonia,kujawsko-pomorskie,Grudziądz,m. Grudziądz,,311 +Polonia,kujawsko-pomorskie,Toruń,m. Toruń,,312 +Polonia,kujawsko-pomorskie,Włocławek,m. Włocławek,,313 +Polonia,lubelskie,bialski,m. Międzyrzec Podlaski,,314 +Polonia,lubelskie,bialski,m. Terespol,,315 +Polonia,lubelskie,bialski,gm. Biała Podlaska,,316 +Polonia,lubelskie,bialski,gm. Drelów,,317 +Polonia,lubelskie,bialski,gm. Janów Podlaski,,318 +Polonia,lubelskie,bialski,gm. Kodeń,,319 +Polonia,lubelskie,bialski,gm. Konstantynów,,320 +Polonia,lubelskie,bialski,gm. Leśna Podlaska,,321 +Polonia,lubelskie,bialski,gm. Łomazy,,322 +Polonia,lubelskie,bialski,gm. Międzyrzec Podlaski,,323 +Polonia,lubelskie,bialski,gm. Piszczac,,324 +Polonia,lubelskie,bialski,gm. Rokitno,,325 +Polonia,lubelskie,bialski,gm. Rossosz,,326 +Polonia,lubelskie,bialski,gm. Sławatycze,,327 +Polonia,lubelskie,bialski,gm. Sosnówka,,328 +Polonia,lubelskie,bialski,gm. Terespol,,329 +Polonia,lubelskie,bialski,gm. Tuczna,,330 +Polonia,lubelskie,bialski,gm. Wisznice,,331 +Polonia,lubelskie,bialski,gm. Zalesie,,332 +Polonia,lubelskie,biłgorajski,m. Biłgoraj,,333 +Polonia,lubelskie,biłgorajski,gm. Aleksandrów,,334 +Polonia,lubelskie,biłgorajski,gm. Biłgoraj,,335 +Polonia,lubelskie,biłgorajski,gm. Biszcza,,336 +Polonia,lubelskie,biłgorajski,gm. Frampol,,337 +Polonia,lubelskie,biłgorajski,gm. Goraj,,338 +Polonia,lubelskie,biłgorajski,gm. Józefów,,339 +Polonia,lubelskie,biłgorajski,gm. Księżpol,,340 +Polonia,lubelskie,biłgorajski,gm. Łukowa,,341 +Polonia,lubelskie,biłgorajski,gm. Obsza,,342 +Polonia,lubelskie,biłgorajski,gm. Potok Górny,,343 +Polonia,lubelskie,biłgorajski,gm. Tarnogród,,344 +Polonia,lubelskie,biłgorajski,gm. Tereszpol,,345 +Polonia,lubelskie,biłgorajski,gm. Turobin,,346 +Polonia,lubelskie,chełmski,m. Rejowiec Fabryczny,,347 +Polonia,lubelskie,chełmski,gm. Białopole,,348 +Polonia,lubelskie,chełmski,gm. Chełm,,349 +Polonia,lubelskie,chełmski,gm. Dorohusk,,350 +Polonia,lubelskie,chełmski,gm. Dubienka,,351 +Polonia,lubelskie,chełmski,gm. Kamień,,352 +Polonia,lubelskie,chełmski,gm. Leśniowice,,353 +Polonia,lubelskie,chełmski,gm. Rejowiec Fabryczny,,354 +Polonia,lubelskie,chełmski,gm. Ruda-Huta,,355 +Polonia,lubelskie,chełmski,gm. Sawin,,356 +Polonia,lubelskie,chełmski,gm. Siedliszcze,,357 +Polonia,lubelskie,chełmski,gm. Wierzbica,,358 +Polonia,lubelskie,chełmski,gm. Wojsławice,,359 +Polonia,lubelskie,chełmski,gm. Żmudź,,360 +Polonia,lubelskie,chełmski,gm. Rejowiec,,361 +Polonia,lubelskie,hrubieszowski,m. Hrubieszów,,362 +Polonia,lubelskie,hrubieszowski,gm. Dołhobyczów,,363 +Polonia,lubelskie,hrubieszowski,gm. Horodło,,364 +Polonia,lubelskie,hrubieszowski,gm. Hrubieszów,,365 +Polonia,lubelskie,hrubieszowski,gm. Mircze,,366 +Polonia,lubelskie,hrubieszowski,gm. Trzeszczany,,367 +Polonia,lubelskie,hrubieszowski,gm. Uchanie,,368 +Polonia,lubelskie,hrubieszowski,gm. Werbkowice,,369 +Polonia,lubelskie,janowski,gm. Batorz,,370 +Polonia,lubelskie,janowski,gm. Chrzanów,,371 +Polonia,lubelskie,janowski,gm. Dzwola,,372 +Polonia,lubelskie,janowski,gm. Godziszów,,373 +Polonia,lubelskie,janowski,gm. Janów Lubelski,,374 +Polonia,lubelskie,janowski,gm. Modliborzyce,,375 +Polonia,lubelskie,janowski,gm. Potok Wielki,,376 +Polonia,lubelskie,krasnostawski,m. Krasnystaw,,377 +Polonia,lubelskie,krasnostawski,gm. Fajsławice,,378 +Polonia,lubelskie,krasnostawski,gm. Gorzków,,379 +Polonia,lubelskie,krasnostawski,gm. Izbica,,380 +Polonia,lubelskie,krasnostawski,gm. Krasnystaw,,381 +Polonia,lubelskie,krasnostawski,gm. Kraśniczyn,,382 +Polonia,lubelskie,krasnostawski,gm. Łopiennik Górny,,383 +Polonia,lubelskie,krasnostawski,gm. Rudnik,,384 +Polonia,lubelskie,krasnostawski,gm. Siennica Różana,,385 +Polonia,lubelskie,krasnostawski,gm. Żółkiewka,,386 +Polonia,lubelskie,kraśnicki,m. Kraśnik,,387 +Polonia,lubelskie,kraśnicki,gm. Annopol,,388 +Polonia,lubelskie,kraśnicki,gm. Dzierzkowice,,389 +Polonia,lubelskie,kraśnicki,gm. Gościeradów,,390 +Polonia,lubelskie,kraśnicki,gm. Kraśnik,,391 +Polonia,lubelskie,kraśnicki,gm. Szastarka,,392 +Polonia,lubelskie,kraśnicki,gm. Trzydnik Duży,,393 +Polonia,lubelskie,kraśnicki,gm. Urzędów,,394 +Polonia,lubelskie,kraśnicki,gm. Wilkołaz,,395 +Polonia,lubelskie,kraśnicki,gm. Zakrzówek,,396 +Polonia,lubelskie,lubartowski,m. Lubartów,,397 +Polonia,lubelskie,lubartowski,gm. Abramów,,398 +Polonia,lubelskie,lubartowski,gm. Firlej,,399 +Polonia,lubelskie,lubartowski,gm. Jeziorzany,,400 +Polonia,lubelskie,lubartowski,gm. Kamionka,,401 +Polonia,lubelskie,lubartowski,gm. Kock,,402 +Polonia,lubelskie,lubartowski,gm. Lubartów,,403 +Polonia,lubelskie,lubartowski,gm. Michów,,404 +Polonia,lubelskie,lubartowski,gm. Niedźwiada,,405 +Polonia,lubelskie,lubartowski,gm. Ostrów Lubelski,,406 +Polonia,lubelskie,lubartowski,gm. Ostrówek,,407 +Polonia,lubelskie,lubartowski,gm. Serniki,,408 +Polonia,lubelskie,lubartowski,gm. Uścimów,,409 +Polonia,lubelskie,lubelski,gm. Bełżyce,,410 +Polonia,lubelskie,lubelski,gm. Borzechów,,411 +Polonia,lubelskie,lubelski,gm. Bychawa,,412 +Polonia,lubelskie,lubelski,gm. Garbów,,413 +Polonia,lubelskie,lubelski,gm. Głusk,,414 +Polonia,lubelskie,lubelski,gm. Jabłonna,,415 +Polonia,lubelskie,lubelski,gm. Jastków,,416 +Polonia,lubelskie,lubelski,gm. Konopnica,,417 +Polonia,lubelskie,lubelski,gm. Krzczonów,,418 +Polonia,lubelskie,lubelski,gm. Niedrzwica Duża,,419 +Polonia,lubelskie,lubelski,gm. Niemce,,420 +Polonia,lubelskie,lubelski,gm. Strzyżewice,,421 +Polonia,lubelskie,lubelski,gm. Wojciechów,,422 +Polonia,lubelskie,lubelski,gm. Wólka,,423 +Polonia,lubelskie,lubelski,gm. Wysokie,,424 +Polonia,lubelskie,lubelski,gm. Zakrzew,,425 +Polonia,lubelskie,łęczyński,gm. Cyców,,426 +Polonia,lubelskie,łęczyński,gm. Ludwin,,427 +Polonia,lubelskie,łęczyński,gm. Łęczna,,428 +Polonia,lubelskie,łęczyński,gm. Milejów,,429 +Polonia,lubelskie,łęczyński,gm. Puchaczów,,430 +Polonia,lubelskie,łęczyński,gm. Spiczyn,,431 +Polonia,lubelskie,łukowski,m. Łuków,,432 +Polonia,lubelskie,łukowski,m. Stoczek Łukowski,,433 +Polonia,lubelskie,łukowski,gm. Adamów,,434 +Polonia,lubelskie,łukowski,gm. Krzywda,,435 +Polonia,lubelskie,łukowski,gm. Łuków,,436 +Polonia,lubelskie,łukowski,gm. Serokomla,,437 +Polonia,lubelskie,łukowski,gm. Stanin,,438 +Polonia,lubelskie,łukowski,gm. Stoczek Łukowski,,439 +Polonia,lubelskie,łukowski,gm. Trzebieszów,,440 +Polonia,lubelskie,łukowski,gm. Wojcieszków,,441 +Polonia,lubelskie,łukowski,gm. Wola Mysłowska,,442 +Polonia,lubelskie,opolski,gm. Chodel,,443 +Polonia,lubelskie,opolski,gm. Józefów nad Wisłą,,444 +Polonia,lubelskie,opolski,gm. Karczmiska,,445 +Polonia,lubelskie,opolski,gm. Łaziska,,446 +Polonia,lubelskie,opolski,gm. Opole Lubelskie,,447 +Polonia,lubelskie,opolski,gm. Poniatowa,,448 +Polonia,lubelskie,opolski,gm. Wilków,,449 +Polonia,lubelskie,parczewski,gm. Dębowa Kłoda,,450 +Polonia,lubelskie,parczewski,gm. Jabłoń,,451 +Polonia,lubelskie,parczewski,gm. Milanów,,452 +Polonia,lubelskie,parczewski,gm. Parczew,,453 +Polonia,lubelskie,parczewski,gm. Podedwórze,,454 +Polonia,lubelskie,parczewski,gm. Siemień,,455 +Polonia,lubelskie,parczewski,gm. Sosnowica,,456 +Polonia,lubelskie,puławski,m. Puławy,,457 +Polonia,lubelskie,puławski,gm. Baranów,,458 +Polonia,lubelskie,puławski,gm. Janowiec,,459 +Polonia,lubelskie,puławski,gm. Kazimierz Dolny,,460 +Polonia,lubelskie,puławski,gm. Końskowola,,461 +Polonia,lubelskie,puławski,gm. Kurów,,462 +Polonia,lubelskie,puławski,gm. Markuszów,,463 +Polonia,lubelskie,puławski,gm. Nałęczów,,464 +Polonia,lubelskie,puławski,gm. Puławy,,465 +Polonia,lubelskie,puławski,gm. Wąwolnica,,466 +Polonia,lubelskie,puławski,gm. Żyrzyn,,467 +Polonia,lubelskie,radzyński,m. Radzyń Podlaski,,468 +Polonia,lubelskie,radzyński,gm. Borki,,469 +Polonia,lubelskie,radzyński,gm. Czemierniki,,470 +Polonia,lubelskie,radzyński,gm. Kąkolewnica,,471 +Polonia,lubelskie,radzyński,gm. Komarówka Podlaska,,472 +Polonia,lubelskie,radzyński,gm. Radzyń Podlaski,,473 +Polonia,lubelskie,radzyński,gm. Ulan-Majorat,,474 +Polonia,lubelskie,radzyński,gm. Wohyń,,475 +Polonia,lubelskie,rycki,m. Dęblin,,476 +Polonia,lubelskie,rycki,gm. Kłoczew,,477 +Polonia,lubelskie,rycki,gm. Nowodwór,,478 +Polonia,lubelskie,rycki,gm. Ryki,,479 +Polonia,lubelskie,rycki,gm. Stężyca,,480 +Polonia,lubelskie,rycki,gm. Ułęż,,481 +Polonia,lubelskie,świdnicki,m. Świdnik,,482 +Polonia,lubelskie,świdnicki,gm. Mełgiew,,483 +Polonia,lubelskie,świdnicki,gm. Piaski,,484 +Polonia,lubelskie,świdnicki,gm. Rybczewice,,485 +Polonia,lubelskie,świdnicki,gm. Trawniki,,486 +Polonia,lubelskie,tomaszowski,m. Tomaszów Lubelski,,487 +Polonia,lubelskie,tomaszowski,gm. Bełżec,,488 +Polonia,lubelskie,tomaszowski,gm. Jarczów,,489 +Polonia,lubelskie,tomaszowski,gm. Krynice,,490 +Polonia,lubelskie,tomaszowski,gm. Lubycza Królewska,,491 +Polonia,lubelskie,tomaszowski,gm. Łaszczów,,492 +Polonia,lubelskie,tomaszowski,gm. Rachanie,,493 +Polonia,lubelskie,tomaszowski,gm. Susiec,,494 +Polonia,lubelskie,tomaszowski,gm. Tarnawatka,,495 +Polonia,lubelskie,tomaszowski,gm. Telatyn,,496 +Polonia,lubelskie,tomaszowski,gm. Tomaszów Lubelski,,497 +Polonia,lubelskie,tomaszowski,gm. Tyszowce,,498 +Polonia,lubelskie,tomaszowski,gm. Ulhówek,,499 +Polonia,lubelskie,włodawski,m. Włodawa,,500 +Polonia,lubelskie,włodawski,gm. Hanna,,501 +Polonia,lubelskie,włodawski,gm. Hańsk,,502 +Polonia,lubelskie,włodawski,gm. Stary Brus,,503 +Polonia,lubelskie,włodawski,gm. Urszulin,,504 +Polonia,lubelskie,włodawski,gm. Włodawa,,505 +Polonia,lubelskie,włodawski,gm. Wola Uhruska,,506 +Polonia,lubelskie,włodawski,gm. Wyryki,,507 +Polonia,lubelskie,zamojski,gm. Adamów,,508 +Polonia,lubelskie,zamojski,gm. Grabowiec,,509 +Polonia,lubelskie,zamojski,gm. Komarów-Osada,,510 +Polonia,lubelskie,zamojski,gm. Krasnobród,,511 +Polonia,lubelskie,zamojski,gm. Łabunie,,512 +Polonia,lubelskie,zamojski,gm. Miączyn,,513 +Polonia,lubelskie,zamojski,gm. Nielisz,,514 +Polonia,lubelskie,zamojski,gm. Radecznica,,515 +Polonia,lubelskie,zamojski,gm. Sitno,,516 +Polonia,lubelskie,zamojski,gm. Skierbieszów,,517 +Polonia,lubelskie,zamojski,gm. Stary Zamość,,518 +Polonia,lubelskie,zamojski,gm. Sułów,,519 +Polonia,lubelskie,zamojski,gm. Szczebrzeszyn,,520 +Polonia,lubelskie,zamojski,gm. Zamość,,521 +Polonia,lubelskie,zamojski,gm. Zwierzyniec,,522 +Polonia,lubelskie,Biała Podlaska,m. Biała Podlaska,,523 +Polonia,lubelskie,Chełm,m. Chełm,,524 +Polonia,lubelskie,Lublin,m. Lublin,,525 +Polonia,lubelskie,Zamość,m. Zamość,,526 +Polonia,lubuskie,gorzowski,m. Kostrzyn nad Odrą,,527 +Polonia,lubuskie,gorzowski,gm. Bogdaniec,,528 +Polonia,lubuskie,gorzowski,gm. Deszczno,,529 +Polonia,lubuskie,gorzowski,gm. Kłodawa,,530 +Polonia,lubuskie,gorzowski,gm. Lubiszyn,,531 +Polonia,lubuskie,gorzowski,gm. Santok,,532 +Polonia,lubuskie,gorzowski,gm. Witnica,,533 +Polonia,lubuskie,krośnieński,m. Gubin,,534 +Polonia,lubuskie,krośnieński,gm. Bobrowice,,535 +Polonia,lubuskie,krośnieński,gm. Bytnica,,536 +Polonia,lubuskie,krośnieński,gm. Dąbie,,537 +Polonia,lubuskie,krośnieński,gm. Gubin,,538 +Polonia,lubuskie,krośnieński,gm. Krosno Odrzańskie,,539 +Polonia,lubuskie,krośnieński,gm. Maszewo,,540 +Polonia,lubuskie,międzyrzecki,gm. Bledzew,,541 +Polonia,lubuskie,międzyrzecki,gm. Międzyrzecz,,542 +Polonia,lubuskie,międzyrzecki,gm. Przytoczna,,543 +Polonia,lubuskie,międzyrzecki,gm. Pszczew,,544 +Polonia,lubuskie,międzyrzecki,gm. Skwierzyna,,545 +Polonia,lubuskie,międzyrzecki,gm. Trzciel,,546 +Polonia,lubuskie,nowosolski,m. Nowa Sól,,547 +Polonia,lubuskie,nowosolski,gm. Bytom Odrzański,,548 +Polonia,lubuskie,nowosolski,gm. Kolsko,,549 +Polonia,lubuskie,nowosolski,gm. Kożuchów,,550 +Polonia,lubuskie,nowosolski,gm. Nowa Sól,,551 +Polonia,lubuskie,nowosolski,gm. Nowe Miasteczko,,552 +Polonia,lubuskie,nowosolski,gm. Otyń,,553 +Polonia,lubuskie,nowosolski,gm. Siedlisko,,554 +Polonia,lubuskie,słubicki,gm. Cybinka,,555 +Polonia,lubuskie,słubicki,gm. Górzyca,,556 +Polonia,lubuskie,słubicki,gm. Ośno Lubuskie,,557 +Polonia,lubuskie,słubicki,gm. Rzepin,,558 +Polonia,lubuskie,słubicki,gm. Słubice,,559 +Polonia,lubuskie,strzelecko-drezdenecki,gm. Dobiegniew,,560 +Polonia,lubuskie,strzelecko-drezdenecki,gm. Drezdenko,,561 +Polonia,lubuskie,strzelecko-drezdenecki,gm. Stare Kurowo,,562 +Polonia,lubuskie,strzelecko-drezdenecki,gm. Strzelce Krajeńskie,,563 +Polonia,lubuskie,strzelecko-drezdenecki,gm. Zwierzyn,,564 +Polonia,lubuskie,sulęciński,gm. Krzeszyce,,565 +Polonia,lubuskie,sulęciński,gm. Lubniewice,,566 +Polonia,lubuskie,sulęciński,gm. Słońsk,,567 +Polonia,lubuskie,sulęciński,gm. Sulęcin,,568 +Polonia,lubuskie,sulęciński,gm. Torzym,,569 +Polonia,lubuskie,świebodziński,gm. Lubrza,,570 +Polonia,lubuskie,świebodziński,gm. Łagów,,571 +Polonia,lubuskie,świebodziński,gm. Skąpe,,572 +Polonia,lubuskie,świebodziński,gm. Szczaniec,,573 +Polonia,lubuskie,świebodziński,gm. Świebodzin,,574 +Polonia,lubuskie,świebodziński,gm. Zbąszynek,,575 +Polonia,lubuskie,zielonogórski,gm. Babimost,,576 +Polonia,lubuskie,zielonogórski,gm. Bojadła,,577 +Polonia,lubuskie,zielonogórski,gm. Czerwieńsk,,578 +Polonia,lubuskie,zielonogórski,gm. Kargowa,,579 +Polonia,lubuskie,zielonogórski,gm. Nowogród Bobrzański,,580 +Polonia,lubuskie,zielonogórski,gm. Sulechów,,581 +Polonia,lubuskie,zielonogórski,gm. Świdnica,,582 +Polonia,lubuskie,zielonogórski,gm. Trzebiechów,,583 +Polonia,lubuskie,zielonogórski,gm. Zabór,,584 +Polonia,lubuskie,żagański,m. Gozdnica,,585 +Polonia,lubuskie,żagański,m. Żagań,,586 +Polonia,lubuskie,żagański,gm. Brzeźnica,,587 +Polonia,lubuskie,żagański,gm. Iłowa,,588 +Polonia,lubuskie,żagański,gm. Małomice,,589 +Polonia,lubuskie,żagański,gm. Niegosławice,,590 +Polonia,lubuskie,żagański,gm. Szprotawa,,591 +Polonia,lubuskie,żagański,gm. Wymiarki,,592 +Polonia,lubuskie,żagański,gm. Żagań,,593 +Polonia,lubuskie,żarski,m. Łęknica,,594 +Polonia,lubuskie,żarski,m. Żary,,595 +Polonia,lubuskie,żarski,gm. Brody,,596 +Polonia,lubuskie,żarski,gm. Jasień,,597 +Polonia,lubuskie,żarski,gm. Lipinki Łużyckie,,598 +Polonia,lubuskie,żarski,gm. Lubsko,,599 +Polonia,lubuskie,żarski,gm. Przewóz,,600 +Polonia,lubuskie,żarski,gm. Trzebiel,,601 +Polonia,lubuskie,żarski,gm. Tuplice,,602 +Polonia,lubuskie,żarski,gm. Żary,,603 +Polonia,lubuskie,wschowski,gm. Sława,,604 +Polonia,lubuskie,wschowski,gm. Szlichtyngowa,,605 +Polonia,lubuskie,wschowski,gm. Wschowa,,606 +Polonia,lubuskie,Gorzów Wielkopolski,m. Gorzów Wielkopolski,,607 +Polonia,lubuskie,Zielona Góra,m. Zielona Góra,,608 +Polonia,łódzkie,bełchatowski,m. Bełchatów,,609 +Polonia,łódzkie,bełchatowski,gm. Bełchatów,,610 +Polonia,łódzkie,bełchatowski,gm. Drużbice,,611 +Polonia,łódzkie,bełchatowski,gm. Kleszczów,,612 +Polonia,łódzkie,bełchatowski,gm. Kluki,,613 +Polonia,łódzkie,bełchatowski,gm. Rusiec,,614 +Polonia,łódzkie,bełchatowski,gm. Szczerców,,615 +Polonia,łódzkie,bełchatowski,gm. Zelów,,616 +Polonia,łódzkie,kutnowski,m. Kutno,,617 +Polonia,łódzkie,kutnowski,gm. Bedlno,,618 +Polonia,łódzkie,kutnowski,gm. Dąbrowice,,619 +Polonia,łódzkie,kutnowski,gm. Krośniewice,,620 +Polonia,łódzkie,kutnowski,gm. Krzyżanów,,621 +Polonia,łódzkie,kutnowski,gm. Kutno,,622 +Polonia,łódzkie,kutnowski,gm. Łanięta,,623 +Polonia,łódzkie,kutnowski,gm. Nowe Ostrowy,,624 +Polonia,łódzkie,kutnowski,gm. Oporów,,625 +Polonia,łódzkie,kutnowski,gm. Strzelce,,626 +Polonia,łódzkie,kutnowski,gm. Żychlin,,627 +Polonia,łódzkie,łaski,gm. Buczek,,628 +Polonia,łódzkie,łaski,gm. Łask,,629 +Polonia,łódzkie,łaski,gm. Sędziejowice,,630 +Polonia,łódzkie,łaski,gm. Widawa,,631 +Polonia,łódzkie,łaski,gm. Wodzierady,,632 +Polonia,łódzkie,łęczycki,m. Łęczyca,,633 +Polonia,łódzkie,łęczycki,gm. Daszyna,,634 +Polonia,łódzkie,łęczycki,gm. Góra Świętej Małgorzaty,,635 +Polonia,łódzkie,łęczycki,gm. Grabów,,636 +Polonia,łódzkie,łęczycki,gm. Łęczyca,,637 +Polonia,łódzkie,łęczycki,gm. Piątek,,638 +Polonia,łódzkie,łęczycki,gm. Świnice Warckie,,639 +Polonia,łódzkie,łęczycki,gm. Witonia,,640 +Polonia,łódzkie,łowicki,m. Łowicz,,641 +Polonia,łódzkie,łowicki,gm. Bielawy,,642 +Polonia,łódzkie,łowicki,gm. Chąśno,,643 +Polonia,łódzkie,łowicki,gm. Domaniewice,,644 +Polonia,łódzkie,łowicki,gm. Kiernozia,,645 +Polonia,łódzkie,łowicki,gm. Kocierzew Południowy,,646 +Polonia,łódzkie,łowicki,gm. Łowicz,,647 +Polonia,łódzkie,łowicki,gm. Łyszkowice,,648 +Polonia,łódzkie,łowicki,gm. Nieborów,,649 +Polonia,łódzkie,łowicki,gm. Zduny,,650 +Polonia,łódzkie,łódzki wschodni,gm. Andrespol,,651 +Polonia,łódzkie,łódzki wschodni,gm. Brójce,,652 +Polonia,łódzkie,łódzki wschodni,gm. Koluszki,,653 +Polonia,łódzkie,łódzki wschodni,gm. Nowosolna,,654 +Polonia,łódzkie,łódzki wschodni,gm. Rzgów,,655 +Polonia,łódzkie,łódzki wschodni,gm. Tuszyn,,656 +Polonia,łódzkie,opoczyński,gm. Białaczów,,657 +Polonia,łódzkie,opoczyński,gm. Drzewica,,658 +Polonia,łódzkie,opoczyński,gm. Mniszków,,659 +Polonia,łódzkie,opoczyński,gm. Opoczno,,660 +Polonia,łódzkie,opoczyński,gm. Paradyż,,661 +Polonia,łódzkie,opoczyński,gm. Poświętne,,662 +Polonia,łódzkie,opoczyński,gm. Sławno,,663 +Polonia,łódzkie,opoczyński,gm. Żarnów,,664 +Polonia,łódzkie,pabianicki,m. Konstantynów Łódzki,,665 +Polonia,łódzkie,pabianicki,m. Pabianice,,666 +Polonia,łódzkie,pabianicki,gm. Dłutów,,667 +Polonia,łódzkie,pabianicki,gm. Dobroń,,668 +Polonia,łódzkie,pabianicki,gm. Ksawerów,,669 +Polonia,łódzkie,pabianicki,gm. Lutomiersk,,670 +Polonia,łódzkie,pabianicki,gm. Pabianice,,671 +Polonia,łódzkie,pajęczański,gm. Działoszyn,,672 +Polonia,łódzkie,pajęczański,gm. Kiełczygłów,,673 +Polonia,łódzkie,pajęczański,gm. Nowa Brzeźnica,,674 +Polonia,łódzkie,pajęczański,gm. Pajęczno,,675 +Polonia,łódzkie,pajęczański,gm. Rząśnia,,676 +Polonia,łódzkie,pajęczański,gm. Siemkowice,,677 +Polonia,łódzkie,pajęczański,gm. Strzelce Wielkie,,678 +Polonia,łódzkie,pajęczański,gm. Sulmierzyce,,679 +Polonia,łódzkie,piotrkowski,gm. Aleksandrów,,680 +Polonia,łódzkie,piotrkowski,gm. Czarnocin,,681 +Polonia,łódzkie,piotrkowski,gm. Gorzkowice,,682 +Polonia,łódzkie,piotrkowski,gm. Grabica,,683 +Polonia,łódzkie,piotrkowski,gm. Łęki Szlacheckie,,684 +Polonia,łódzkie,piotrkowski,gm. Moszczenica,,685 +Polonia,łódzkie,piotrkowski,gm. Ręczno,,686 +Polonia,łódzkie,piotrkowski,gm. Rozprza,,687 +Polonia,łódzkie,piotrkowski,gm. Sulejów,,688 +Polonia,łódzkie,piotrkowski,gm. Wola Krzysztoporska,,689 +Polonia,łódzkie,piotrkowski,gm. Wolbórz,,690 +Polonia,łódzkie,poddębicki,gm. Dalików,,691 +Polonia,łódzkie,poddębicki,gm. Pęczniew,,692 +Polonia,łódzkie,poddębicki,gm. Poddębice,,693 +Polonia,łódzkie,poddębicki,gm. Uniejów,,694 +Polonia,łódzkie,poddębicki,gm. Wartkowice,,695 +Polonia,łódzkie,poddębicki,gm. Zadzim,,696 +Polonia,łódzkie,radomszczański,m. Radomsko,,697 +Polonia,łódzkie,radomszczański,gm. Dobryszyce,,698 +Polonia,łódzkie,radomszczański,gm. Gidle,,699 +Polonia,łódzkie,radomszczański,gm. Gomunice,,700 +Polonia,łódzkie,radomszczański,gm. Kamieńsk,,701 +Polonia,łódzkie,radomszczański,gm. Kobiele Wielkie,,702 +Polonia,łódzkie,radomszczański,gm. Kodrąb,,703 +Polonia,łódzkie,radomszczański,gm. Lgota Wielka,,704 +Polonia,łódzkie,radomszczański,gm. Ładzice,,705 +Polonia,łódzkie,radomszczański,gm. Masłowice,,706 +Polonia,łódzkie,radomszczański,gm. Przedbórz,,707 +Polonia,łódzkie,radomszczański,gm. Radomsko,,708 +Polonia,łódzkie,radomszczański,gm. Wielgomłyny,,709 +Polonia,łódzkie,radomszczański,gm. Żytno,,710 +Polonia,łódzkie,rawski,m. Rawa Mazowiecka,,711 +Polonia,łódzkie,rawski,gm. Biała Rawska,,712 +Polonia,łódzkie,rawski,gm. Cielądz,,713 +Polonia,łódzkie,rawski,gm. Rawa Mazowiecka,,714 +Polonia,łódzkie,rawski,gm. Regnów,,715 +Polonia,łódzkie,rawski,gm. Sadkowice,,716 +Polonia,łódzkie,sieradzki,m. Sieradz,,717 +Polonia,łódzkie,sieradzki,gm. Błaszki,,718 +Polonia,łódzkie,sieradzki,gm. Brąszewice,,719 +Polonia,łódzkie,sieradzki,gm. Brzeźnio,,720 +Polonia,łódzkie,sieradzki,gm. Burzenin,,721 +Polonia,łódzkie,sieradzki,gm. Goszczanów,,722 +Polonia,łódzkie,sieradzki,gm. Klonowa,,723 +Polonia,łódzkie,sieradzki,gm. Sieradz,,724 +Polonia,łódzkie,sieradzki,gm. Warta,,725 +Polonia,łódzkie,sieradzki,gm. Wróblew,,726 +Polonia,łódzkie,sieradzki,gm. Złoczew,,727 +Polonia,łódzkie,skierniewicki,gm. Bolimów,,728 +Polonia,łódzkie,skierniewicki,gm. Głuchów,,729 +Polonia,łódzkie,skierniewicki,gm. Godzianów,,730 +Polonia,łódzkie,skierniewicki,gm. Kowiesy,,731 +Polonia,łódzkie,skierniewicki,gm. Lipce Reymontowskie,,732 +Polonia,łódzkie,skierniewicki,gm. Maków,,733 +Polonia,łódzkie,skierniewicki,gm. Nowy Kawęczyn,,734 +Polonia,łódzkie,skierniewicki,gm. Skierniewice,,735 +Polonia,łódzkie,skierniewicki,gm. Słupia,,736 +Polonia,łódzkie,tomaszowski,m. Tomaszów Mazowiecki,,737 +Polonia,łódzkie,tomaszowski,gm. Będków,,738 +Polonia,łódzkie,tomaszowski,gm. Budziszewice,,739 +Polonia,łódzkie,tomaszowski,gm. Czerniewice,,740 +Polonia,łódzkie,tomaszowski,gm. Inowłódz,,741 +Polonia,łódzkie,tomaszowski,gm. Lubochnia,,742 +Polonia,łódzkie,tomaszowski,gm. Rokiciny,,743 +Polonia,łódzkie,tomaszowski,gm. Rzeczyca,,744 +Polonia,łódzkie,tomaszowski,gm. Tomaszów Mazowiecki,,745 +Polonia,łódzkie,tomaszowski,gm. Ujazd,,746 +Polonia,łódzkie,tomaszowski,gm. Żelechlinek,,747 +Polonia,łódzkie,wieluński,gm. Biała,,748 +Polonia,łódzkie,wieluński,gm. Czarnożyły,,749 +Polonia,łódzkie,wieluński,gm. Konopnica,,750 +Polonia,łódzkie,wieluński,gm. Mokrsko,,751 +Polonia,łódzkie,wieluński,gm. Osjaków,,752 +Polonia,łódzkie,wieluński,gm. Ostrówek,,753 +Polonia,łódzkie,wieluński,gm. Pątnów,,754 +Polonia,łódzkie,wieluński,gm. Skomlin,,755 +Polonia,łódzkie,wieluński,gm. Wieluń,,756 +Polonia,łódzkie,wieluński,gm. Wierzchlas,,757 +Polonia,łódzkie,wieruszowski,gm. Bolesławiec,,758 +Polonia,łódzkie,wieruszowski,gm. Czastary,,759 +Polonia,łódzkie,wieruszowski,gm. Galewice,,760 +Polonia,łódzkie,wieruszowski,gm. Lututów,,761 +Polonia,łódzkie,wieruszowski,gm. Łubnice,,762 +Polonia,łódzkie,wieruszowski,gm. Sokolniki,,763 +Polonia,łódzkie,wieruszowski,gm. Wieruszów,,764 +Polonia,łódzkie,zduńskowolski,m. Zduńska Wola,,765 +Polonia,łódzkie,zduńskowolski,gm. Szadek,,766 +Polonia,łódzkie,zduńskowolski,gm. Zapolice,,767 +Polonia,łódzkie,zduńskowolski,gm. Zduńska Wola,,768 +Polonia,łódzkie,zgierski,m. Głowno,,769 +Polonia,łódzkie,zgierski,m. Ozorków,,770 +Polonia,łódzkie,zgierski,m. Zgierz,,771 +Polonia,łódzkie,zgierski,gm. Aleksandrów Łódzki,,772 +Polonia,łódzkie,zgierski,gm. Głowno,,773 +Polonia,łódzkie,zgierski,gm. Ozorków,,774 +Polonia,łódzkie,zgierski,gm. Parzęczew,,775 +Polonia,łódzkie,zgierski,gm. Stryków,,776 +Polonia,łódzkie,zgierski,gm. Zgierz,,777 +Polonia,łódzkie,brzeziński,m. Brzeziny,,778 +Polonia,łódzkie,brzeziński,gm. Brzeziny,,779 +Polonia,łódzkie,brzeziński,gm. Dmosin,,780 +Polonia,łódzkie,brzeziński,gm. Jeżów,,781 +Polonia,łódzkie,brzeziński,gm. Rogów,,782 +Polonia,łódzkie,Łódź,m. Łódź,,783 +Polonia,łódzkie,Piotrków Trybunalski,m. Piotrków Trybunalski,,784 +Polonia,łódzkie,Skierniewice,m. Skierniewice,,785 +Polonia,małopolskie,bocheński,m. Bochnia,,786 +Polonia,małopolskie,bocheński,gm. Bochnia,,787 +Polonia,małopolskie,bocheński,gm. Drwinia,,788 +Polonia,małopolskie,bocheński,gm. Lipnica Murowana,,789 +Polonia,małopolskie,bocheński,gm. Łapanów,,790 +Polonia,małopolskie,bocheński,gm. Nowy Wiśnicz,,791 +Polonia,małopolskie,bocheński,gm. Rzezawa,,792 +Polonia,małopolskie,bocheński,gm. Trzciana,,793 +Polonia,małopolskie,bocheński,gm. Żegocina,,794 +Polonia,małopolskie,brzeski,gm. Borzęcin,,795 +Polonia,małopolskie,brzeski,gm. Brzesko,,796 +Polonia,małopolskie,brzeski,gm. Czchów,,797 +Polonia,małopolskie,brzeski,gm. Dębno,,798 +Polonia,małopolskie,brzeski,gm. Gnojnik,,799 +Polonia,małopolskie,brzeski,gm. Iwkowa,,800 +Polonia,małopolskie,brzeski,gm. Szczurowa,,801 +Polonia,małopolskie,chrzanowski,gm. Alwernia,,802 +Polonia,małopolskie,chrzanowski,gm. Babice,,803 +Polonia,małopolskie,chrzanowski,gm. Chrzanów,,804 +Polonia,małopolskie,chrzanowski,gm. Libiąż,,805 +Polonia,małopolskie,chrzanowski,gm. Trzebinia,,806 +Polonia,małopolskie,dąbrowski,gm. Bolesław,,807 +Polonia,małopolskie,dąbrowski,gm. Dąbrowa Tarnowska,,808 +Polonia,małopolskie,dąbrowski,gm. Gręboszów,,809 +Polonia,małopolskie,dąbrowski,gm. Mędrzechów,,810 +Polonia,małopolskie,dąbrowski,gm. Olesno,,811 +Polonia,małopolskie,dąbrowski,gm. Radgoszcz,,812 +Polonia,małopolskie,dąbrowski,gm. Szczucin,,813 +Polonia,małopolskie,gorlicki,m. Gorlice,,814 +Polonia,małopolskie,gorlicki,gm. Biecz,,815 +Polonia,małopolskie,gorlicki,gm. Bobowa,,816 +Polonia,małopolskie,gorlicki,gm. Gorlice,,817 +Polonia,małopolskie,gorlicki,gm. Lipinki,,818 +Polonia,małopolskie,gorlicki,gm. Łużna,,819 +Polonia,małopolskie,gorlicki,gm. Moszczenica,,820 +Polonia,małopolskie,gorlicki,gm. Ropa,,821 +Polonia,małopolskie,gorlicki,gm. Sękowa,,822 +Polonia,małopolskie,gorlicki,gm. Uście Gorlickie,,823 +Polonia,małopolskie,krakowski,gm. Czernichów,,824 +Polonia,małopolskie,krakowski,gm. Igołomia-Wawrzeńczyce,,825 +Polonia,małopolskie,krakowski,gm. Iwanowice,,826 +Polonia,małopolskie,krakowski,gm. Jerzmanowice-Przeginia,,827 +Polonia,małopolskie,krakowski,gm. Kocmyrzów-Luborzyca,,828 +Polonia,małopolskie,krakowski,gm. Krzeszowice,,829 +Polonia,małopolskie,krakowski,gm. Liszki,,830 +Polonia,małopolskie,krakowski,gm. Michałowice,,831 +Polonia,małopolskie,krakowski,gm. Mogilany,,832 +Polonia,małopolskie,krakowski,gm. Skała,,833 +Polonia,małopolskie,krakowski,gm. Skawina,,834 +Polonia,małopolskie,krakowski,gm. Słomniki,,835 +Polonia,małopolskie,krakowski,gm. Sułoszowa,,836 +Polonia,małopolskie,krakowski,gm. Świątniki Górne,,837 +Polonia,małopolskie,krakowski,gm. Wielka Wieś,,838 +Polonia,małopolskie,krakowski,gm. Zabierzów,,839 +Polonia,małopolskie,krakowski,gm. Zielonki,,840 +Polonia,małopolskie,limanowski,m. Limanowa,,841 +Polonia,małopolskie,limanowski,m. Mszana Dolna,,842 +Polonia,małopolskie,limanowski,gm. Dobra,,843 +Polonia,małopolskie,limanowski,gm. Jodłownik,,844 +Polonia,małopolskie,limanowski,gm. Kamienica,,845 +Polonia,małopolskie,limanowski,gm. Laskowa,,846 +Polonia,małopolskie,limanowski,gm. Limanowa,,847 +Polonia,małopolskie,limanowski,gm. Łukowica,,848 +Polonia,małopolskie,limanowski,gm. Mszana Dolna,,849 +Polonia,małopolskie,limanowski,gm. Niedźwiedź,,850 +Polonia,małopolskie,limanowski,gm. Słopnice,,851 +Polonia,małopolskie,limanowski,gm. Tymbark,,852 +Polonia,małopolskie,miechowski,gm. Charsznica,,853 +Polonia,małopolskie,miechowski,gm. Gołcza,,854 +Polonia,małopolskie,miechowski,gm. Kozłów,,855 +Polonia,małopolskie,miechowski,gm. Książ Wielki,,856 +Polonia,małopolskie,miechowski,gm. Miechów,,857 +Polonia,małopolskie,miechowski,gm. Racławice,,858 +Polonia,małopolskie,miechowski,gm. Słaboszów,,859 +Polonia,małopolskie,myślenicki,gm. Dobczyce,,860 +Polonia,małopolskie,myślenicki,gm. Lubień,,861 +Polonia,małopolskie,myślenicki,gm. Myślenice,,862 +Polonia,małopolskie,myślenicki,gm. Pcim,,863 +Polonia,małopolskie,myślenicki,gm. Raciechowice,,864 +Polonia,małopolskie,myślenicki,gm. Siepraw,,865 +Polonia,małopolskie,myślenicki,gm. Sułkowice,,866 +Polonia,małopolskie,myślenicki,gm. Tokarnia,,867 +Polonia,małopolskie,myślenicki,gm. Wiśniowa,,868 +Polonia,małopolskie,nowosądecki,m. Grybów,,869 +Polonia,małopolskie,nowosądecki,gm. Chełmiec,,870 +Polonia,małopolskie,nowosądecki,gm. Gródek nad Dunajcem,,871 +Polonia,małopolskie,nowosądecki,gm. Grybów,,872 +Polonia,małopolskie,nowosądecki,gm. Kamionka Wielka,,873 +Polonia,małopolskie,nowosądecki,gm. Korzenna,,874 +Polonia,małopolskie,nowosądecki,gm. Krynica-Zdrój,,875 +Polonia,małopolskie,nowosądecki,gm. Łabowa,,876 +Polonia,małopolskie,nowosądecki,gm. Łącko,,877 +Polonia,małopolskie,nowosądecki,gm. Łososina Dolna,,878 +Polonia,małopolskie,nowosądecki,gm. Muszyna,,879 +Polonia,małopolskie,nowosądecki,gm. Nawojowa,,880 +Polonia,małopolskie,nowosądecki,gm. Piwniczna-Zdrój,,881 +Polonia,małopolskie,nowosądecki,gm. Podegrodzie,,882 +Polonia,małopolskie,nowosądecki,gm. Rytro,,883 +Polonia,małopolskie,nowosądecki,gm. Stary Sącz,,884 +Polonia,małopolskie,nowotarski,m. Nowy Targ,,885 +Polonia,małopolskie,nowotarski,gm. Szczawnica,,886 +Polonia,małopolskie,nowotarski,gm. Czarny Dunajec,,887 +Polonia,małopolskie,nowotarski,gm. Czorsztyn,,888 +Polonia,małopolskie,nowotarski,gm. Jabłonka,,889 +Polonia,małopolskie,nowotarski,gm. Krościenko nad Dunajcem,,890 +Polonia,małopolskie,nowotarski,gm. Lipnica Wielka,,891 +Polonia,małopolskie,nowotarski,gm. Łapsze Niżne,,892 +Polonia,małopolskie,nowotarski,gm. Nowy Targ,,893 +Polonia,małopolskie,nowotarski,gm. Ochotnica Dolna,,894 +Polonia,małopolskie,nowotarski,gm. Raba Wyżna,,895 +Polonia,małopolskie,nowotarski,gm. Rabka-Zdrój,,896 +Polonia,małopolskie,nowotarski,gm. Spytkowice,,897 +Polonia,małopolskie,nowotarski,gm. Szaflary,,898 +Polonia,małopolskie,olkuski,m. Bukowno,,899 +Polonia,małopolskie,olkuski,gm. Bolesław,,900 +Polonia,małopolskie,olkuski,gm. Klucze,,901 +Polonia,małopolskie,olkuski,gm. Olkusz,,902 +Polonia,małopolskie,olkuski,gm. Trzyciąż,,903 +Polonia,małopolskie,olkuski,gm. Wolbrom,,904 +Polonia,małopolskie,oświęcimski,m. Oświęcim,,905 +Polonia,małopolskie,oświęcimski,gm. Brzeszcze,,906 +Polonia,małopolskie,oświęcimski,gm. Chełmek,,907 +Polonia,małopolskie,oświęcimski,gm. Kęty,,908 +Polonia,małopolskie,oświęcimski,gm. Osiek,,909 +Polonia,małopolskie,oświęcimski,gm. Oświęcim,,910 +Polonia,małopolskie,oświęcimski,gm. Polanka Wielka,,911 +Polonia,małopolskie,oświęcimski,gm. Przeciszów,,912 +Polonia,małopolskie,oświęcimski,gm. Zator,,913 +Polonia,małopolskie,proszowicki,gm. Koniusza,,914 +Polonia,małopolskie,proszowicki,gm. Koszyce,,915 +Polonia,małopolskie,proszowicki,gm. Nowe Brzesko,,916 +Polonia,małopolskie,proszowicki,gm. Pałecznica,,917 +Polonia,małopolskie,proszowicki,gm. Proszowice,,918 +Polonia,małopolskie,proszowicki,gm. Radziemice,,919 +Polonia,małopolskie,suski,m. Jordanów,,920 +Polonia,małopolskie,suski,m. Sucha Beskidzka,,921 +Polonia,małopolskie,suski,gm. Budzów,,922 +Polonia,małopolskie,suski,gm. Bystra-Sidzina,,923 +Polonia,małopolskie,suski,gm. Jordanów,,924 +Polonia,małopolskie,suski,gm. Maków Podhalański,,925 +Polonia,małopolskie,suski,gm. Stryszawa,,926 +Polonia,małopolskie,suski,gm. Zawoja,,927 +Polonia,małopolskie,suski,gm. Zembrzyce,,928 +Polonia,małopolskie,tarnowski,gm. Ciężkowice,,929 +Polonia,małopolskie,tarnowski,gm. Gromnik,,930 +Polonia,małopolskie,tarnowski,gm. Lisia Góra,,931 +Polonia,małopolskie,tarnowski,gm. Pleśna,,932 +Polonia,małopolskie,tarnowski,gm. Radłów,,933 +Polonia,małopolskie,tarnowski,gm. Ryglice,,934 +Polonia,małopolskie,tarnowski,gm. Rzepiennik Strzyżewski,,935 +Polonia,małopolskie,tarnowski,gm. Skrzyszów,,936 +Polonia,małopolskie,tarnowski,gm. Tarnów,,937 +Polonia,małopolskie,tarnowski,gm. Tuchów,,938 +Polonia,małopolskie,tarnowski,gm. Wierzchosławice,,939 +Polonia,małopolskie,tarnowski,gm. Wietrzychowice,,940 +Polonia,małopolskie,tarnowski,gm. Wojnicz,,941 +Polonia,małopolskie,tarnowski,gm. Zakliczyn,,942 +Polonia,małopolskie,tarnowski,gm. Żabno,,943 +Polonia,małopolskie,tarnowski,gm. Szerzyny,,944 +Polonia,małopolskie,tatrzański,m. Zakopane,,945 +Polonia,małopolskie,tatrzański,gm. Biały Dunajec,,946 +Polonia,małopolskie,tatrzański,gm. Bukowina Tatrzańska,,947 +Polonia,małopolskie,tatrzański,gm. Kościelisko,,948 +Polonia,małopolskie,tatrzański,gm. Poronin,,949 +Polonia,małopolskie,wadowicki,gm. Andrychów,,950 +Polonia,małopolskie,wadowicki,gm. Brzeźnica,,951 +Polonia,małopolskie,wadowicki,gm. Kalwaria Zebrzydowska,,952 +Polonia,małopolskie,wadowicki,gm. Lanckorona,,953 +Polonia,małopolskie,wadowicki,gm. Mucharz,,954 +Polonia,małopolskie,wadowicki,gm. Spytkowice,,955 +Polonia,małopolskie,wadowicki,gm. Stryszów,,956 +Polonia,małopolskie,wadowicki,gm. Tomice,,957 +Polonia,małopolskie,wadowicki,gm. Wadowice,,958 +Polonia,małopolskie,wadowicki,gm. Wieprz,,959 +Polonia,małopolskie,wielicki,gm. Biskupice,,960 +Polonia,małopolskie,wielicki,gm. Gdów,,961 +Polonia,małopolskie,wielicki,gm. Kłaj,,962 +Polonia,małopolskie,wielicki,gm. Niepołomice,,963 +Polonia,małopolskie,wielicki,gm. Wieliczka,,964 +Polonia,małopolskie,Kraków,m. Kraków,,965 +Polonia,małopolskie,Nowy Sącz,m. Nowy Sącz,,966 +Polonia,małopolskie,Tarnów,m. Tarnów,,967 +Polonia,mazowieckie,białobrzeski,gm. Białobrzegi,,968 +Polonia,mazowieckie,białobrzeski,gm. Promna,,969 +Polonia,mazowieckie,białobrzeski,gm. Radzanów,,970 +Polonia,mazowieckie,białobrzeski,gm. Stara Błotnica,,971 +Polonia,mazowieckie,białobrzeski,gm. Stromiec,,972 +Polonia,mazowieckie,białobrzeski,gm. Wyśmierzyce,,973 +Polonia,mazowieckie,ciechanowski,m. Ciechanów,,974 +Polonia,mazowieckie,ciechanowski,gm. Ciechanów,,975 +Polonia,mazowieckie,ciechanowski,gm. Glinojeck,,976 +Polonia,mazowieckie,ciechanowski,gm. Gołymin-Ośrodek,,977 +Polonia,mazowieckie,ciechanowski,gm. Grudusk,,978 +Polonia,mazowieckie,ciechanowski,gm. Ojrzeń,,979 +Polonia,mazowieckie,ciechanowski,gm. Opinogóra Górna,,980 +Polonia,mazowieckie,ciechanowski,gm. Regimin,,981 +Polonia,mazowieckie,ciechanowski,gm. Sońsk,,982 +Polonia,mazowieckie,garwoliński,m. Garwolin,,983 +Polonia,mazowieckie,garwoliński,m. Łaskarzew,,984 +Polonia,mazowieckie,garwoliński,gm. Borowie,,985 +Polonia,mazowieckie,garwoliński,gm. Garwolin,,986 +Polonia,mazowieckie,garwoliński,gm. Górzno,,987 +Polonia,mazowieckie,garwoliński,gm. Łaskarzew,,988 +Polonia,mazowieckie,garwoliński,gm. Maciejowice,,989 +Polonia,mazowieckie,garwoliński,gm. Miastków Kościelny,,990 +Polonia,mazowieckie,garwoliński,gm. Parysów,,991 +Polonia,mazowieckie,garwoliński,gm. Pilawa,,992 +Polonia,mazowieckie,garwoliński,gm. Sobolew,,993 +Polonia,mazowieckie,garwoliński,gm. Trojanów,,994 +Polonia,mazowieckie,garwoliński,gm. Wilga,,995 +Polonia,mazowieckie,garwoliński,gm. Żelechów,,996 +Polonia,mazowieckie,gostyniński,m. Gostynin,,997 +Polonia,mazowieckie,gostyniński,gm. Gostynin,,998 +Polonia,mazowieckie,gostyniński,gm. Pacyna,,999 +Polonia,mazowieckie,gostyniński,gm. Sanniki,,1000 +Polonia,mazowieckie,gostyniński,gm. Szczawin Kośc.,,1001 +Polonia,mazowieckie,grodziski,m. Milanówek,,1002 +Polonia,mazowieckie,grodziski,m. Podkowa Leśna,,1003 +Polonia,mazowieckie,grodziski,gm. Baranów,,1004 +Polonia,mazowieckie,grodziski,gm. Grodzisk Mazowiecki,,1005 +Polonia,mazowieckie,grodziski,gm. Jaktorów,,1006 +Polonia,mazowieckie,grodziski,gm. Żabia Wola,,1007 +Polonia,mazowieckie,grójecki,gm. Belsk Duży,,1008 +Polonia,mazowieckie,grójecki,gm. Błędów,,1009 +Polonia,mazowieckie,grójecki,gm. Chynów,,1010 +Polonia,mazowieckie,grójecki,gm. Goszczyn,,1011 +Polonia,mazowieckie,grójecki,gm. Grójec,,1012 +Polonia,mazowieckie,grójecki,gm. Jasieniec,,1013 +Polonia,mazowieckie,grójecki,gm. Mogielnica,,1014 +Polonia,mazowieckie,grójecki,gm. Nowe Miasto nad Pilicą,,1015 +Polonia,mazowieckie,grójecki,gm. Pniewy,,1016 +Polonia,mazowieckie,grójecki,gm. Warka,,1017 +Polonia,mazowieckie,kozienicki,gm. Garbatka-Letnisko,,1018 +Polonia,mazowieckie,kozienicki,gm. Głowaczów,,1019 +Polonia,mazowieckie,kozienicki,gm. Gniewoszów,,1020 +Polonia,mazowieckie,kozienicki,gm. Grabów nad Pilicą,,1021 +Polonia,mazowieckie,kozienicki,gm. Kozienice,,1022 +Polonia,mazowieckie,kozienicki,gm. Magnuszew,,1023 +Polonia,mazowieckie,kozienicki,gm. Sieciechów,,1024 +Polonia,mazowieckie,legionowski,m. Legionowo,,1025 +Polonia,mazowieckie,legionowski,gm. Jabłonna,,1026 +Polonia,mazowieckie,legionowski,gm. Nieporęt,,1027 +Polonia,mazowieckie,legionowski,gm. Serock,,1028 +Polonia,mazowieckie,legionowski,gm. Wieliszew,,1029 +Polonia,mazowieckie,lipski,gm. Chotcza,,1030 +Polonia,mazowieckie,lipski,gm. Ciepielów,,1031 +Polonia,mazowieckie,lipski,gm. Lipsko,,1032 +Polonia,mazowieckie,lipski,gm. Rzeczniów,,1033 +Polonia,mazowieckie,lipski,gm. Sienno,,1034 +Polonia,mazowieckie,lipski,gm. Solec nad Wisłą,,1035 +Polonia,mazowieckie,łosicki,gm. Huszlew,,1036 +Polonia,mazowieckie,łosicki,gm. Łosice,,1037 +Polonia,mazowieckie,łosicki,gm. Olszanka,,1038 +Polonia,mazowieckie,łosicki,gm. Platerów,,1039 +Polonia,mazowieckie,łosicki,gm. Sarnaki,,1040 +Polonia,mazowieckie,łosicki,gm. Stara Kornica,,1041 +Polonia,mazowieckie,makowski,m. Maków Mazowiecki,,1042 +Polonia,mazowieckie,makowski,gm. Czerwonka,,1043 +Polonia,mazowieckie,makowski,gm. Karniewo,,1044 +Polonia,mazowieckie,makowski,gm. Krasnosielc,,1045 +Polonia,mazowieckie,makowski,gm. Młynarze,,1046 +Polonia,mazowieckie,makowski,gm. Płoniawy-Bramura,,1047 +Polonia,mazowieckie,makowski,gm. Różan,,1048 +Polonia,mazowieckie,makowski,gm. Rzewnie,,1049 +Polonia,mazowieckie,makowski,gm. Sypniewo,,1050 +Polonia,mazowieckie,makowski,gm. Szelków,,1051 +Polonia,mazowieckie,miński,m. Mińsk Mazowiecki,,1052 +Polonia,mazowieckie,miński,gm. Cegłów,,1053 +Polonia,mazowieckie,miński,gm. Dębe Wielkie,,1054 +Polonia,mazowieckie,miński,gm. Dobre,,1055 +Polonia,mazowieckie,miński,gm. Halinów,,1056 +Polonia,mazowieckie,miński,gm. Jakubów,,1057 +Polonia,mazowieckie,miński,gm. Kałuszyn,,1058 +Polonia,mazowieckie,miński,gm. Latowicz,,1059 +Polonia,mazowieckie,miński,gm. Mińsk Mazowiecki,,1060 +Polonia,mazowieckie,miński,gm. Mrozy,,1061 +Polonia,mazowieckie,miński,gm. Siennica,,1062 +Polonia,mazowieckie,miński,gm. Stanisławów,,1063 +Polonia,mazowieckie,miński,m. Sulejówek,,1064 +Polonia,mazowieckie,mławski,m. Mława,,1065 +Polonia,mazowieckie,mławski,gm. Dzierzgowo,,1066 +Polonia,mazowieckie,mławski,gm. Lipowiec Kościelny,,1067 +Polonia,mazowieckie,mławski,gm. Radzanów,,1068 +Polonia,mazowieckie,mławski,gm. Strzegowo,,1069 +Polonia,mazowieckie,mławski,gm. Stupsk,,1070 +Polonia,mazowieckie,mławski,gm. Szreńsk,,1071 +Polonia,mazowieckie,mławski,gm. Szydłowo,,1072 +Polonia,mazowieckie,mławski,gm. Wieczfnia Kościelna,,1073 +Polonia,mazowieckie,mławski,gm. Wiśniewo,,1074 +Polonia,mazowieckie,nowodworski,m. Nowy Dwór Mazowiecki,,1075 +Polonia,mazowieckie,nowodworski,gm. Czosnów,,1076 +Polonia,mazowieckie,nowodworski,gm. Leoncin,,1077 +Polonia,mazowieckie,nowodworski,gm. Nasielsk,,1078 +Polonia,mazowieckie,nowodworski,gm. Pomiechówek,,1079 +Polonia,mazowieckie,nowodworski,gm. Zakroczym,,1080 +Polonia,mazowieckie,ostrołęcki,gm. Baranowo,,1081 +Polonia,mazowieckie,ostrołęcki,gm. Czarnia,,1082 +Polonia,mazowieckie,ostrołęcki,gm. Czerwin,,1083 +Polonia,mazowieckie,ostrołęcki,gm. Goworowo,,1084 +Polonia,mazowieckie,ostrołęcki,gm. Kadzidło,,1085 +Polonia,mazowieckie,ostrołęcki,gm. Lelis,,1086 +Polonia,mazowieckie,ostrołęcki,gm. Łyse,,1087 +Polonia,mazowieckie,ostrołęcki,gm. Myszyniec,,1088 +Polonia,mazowieckie,ostrołęcki,gm. Olszewo-Borki,,1089 +Polonia,mazowieckie,ostrołęcki,gm. Rzekuń,,1090 +Polonia,mazowieckie,ostrołęcki,gm. Troszyn,,1091 +Polonia,mazowieckie,ostrowski,m. Ostrów Mazowiecka,,1092 +Polonia,mazowieckie,ostrowski,gm. Andrzejewo,,1093 +Polonia,mazowieckie,ostrowski,gm. Boguty-Pianki,,1094 +Polonia,mazowieckie,ostrowski,gm. Brok,,1095 +Polonia,mazowieckie,ostrowski,gm. Małkinia Górna,,1096 +Polonia,mazowieckie,ostrowski,gm. Nur,,1097 +Polonia,mazowieckie,ostrowski,gm. Ostrów Mazowiecka,,1098 +Polonia,mazowieckie,ostrowski,gm. Stary Lubotyń,,1099 +Polonia,mazowieckie,ostrowski,gm. Szulborze Wielkie,,1100 +Polonia,mazowieckie,ostrowski,gm. Wąsewo,,1101 +Polonia,mazowieckie,ostrowski,gm. Zaręby Kościelne,,1102 +Polonia,mazowieckie,otwocki,m. Józefów,,1103 +Polonia,mazowieckie,otwocki,m. Otwock,,1104 +Polonia,mazowieckie,otwocki,gm. Celestynów,,1105 +Polonia,mazowieckie,otwocki,gm. Karczew,,1106 +Polonia,mazowieckie,otwocki,gm. Kołbiel,,1107 +Polonia,mazowieckie,otwocki,gm. Osieck,,1108 +Polonia,mazowieckie,otwocki,gm. Sobienie-Jeziory,,1109 +Polonia,mazowieckie,otwocki,gm. Wiązowna,,1110 +Polonia,mazowieckie,piaseczyński,gm. Góra Kalwaria,,1111 +Polonia,mazowieckie,piaseczyński,gm. Konstancin-Jeziorna,,1112 +Polonia,mazowieckie,piaseczyński,gm. Lesznowola,,1113 +Polonia,mazowieckie,piaseczyński,gm. Piaseczno,,1114 +Polonia,mazowieckie,piaseczyński,gm. Prażmów,,1115 +Polonia,mazowieckie,piaseczyński,gm. Tarczyn,,1116 +Polonia,mazowieckie,płocki,gm. Bielsk,,1117 +Polonia,mazowieckie,płocki,gm. Bodzanów,,1118 +Polonia,mazowieckie,płocki,gm. Brudzeń Duży,,1119 +Polonia,mazowieckie,płocki,gm. Bulkowo,,1120 +Polonia,mazowieckie,płocki,gm. Drobin,,1121 +Polonia,mazowieckie,płocki,gm. Gąbin,,1122 +Polonia,mazowieckie,płocki,gm. Łąck,,1123 +Polonia,mazowieckie,płocki,gm. Mała Wieś,,1124 +Polonia,mazowieckie,płocki,gm. Nowy Duninów,,1125 +Polonia,mazowieckie,płocki,gm. Radzanowo,,1126 +Polonia,mazowieckie,płocki,gm. Słubice,,1127 +Polonia,mazowieckie,płocki,gm. Słupno,,1128 +Polonia,mazowieckie,płocki,gm. Stara Biała,,1129 +Polonia,mazowieckie,płocki,gm. Staroźreby,,1130 +Polonia,mazowieckie,płocki,gm. Wyszogród,,1131 +Polonia,mazowieckie,płoński,m. Płońsk,,1132 +Polonia,mazowieckie,płoński,m. Raciąż,,1133 +Polonia,mazowieckie,płoński,gm. Baboszewo,,1134 +Polonia,mazowieckie,płoński,gm. Czerwińsk nad Wisłą,,1135 +Polonia,mazowieckie,płoński,gm. Dzierzążnia,,1136 +Polonia,mazowieckie,płoński,gm. Joniec,,1137 +Polonia,mazowieckie,płoński,gm. Naruszewo,,1138 +Polonia,mazowieckie,płoński,gm. Nowe Miasto,,1139 +Polonia,mazowieckie,płoński,gm. Płońsk,,1140 +Polonia,mazowieckie,płoński,gm. Raciąż,,1141 +Polonia,mazowieckie,płoński,gm. Sochocin,,1142 +Polonia,mazowieckie,płoński,gm. Załuski,,1143 +Polonia,mazowieckie,pruszkowski,m. Piastów,,1144 +Polonia,mazowieckie,pruszkowski,m. Pruszków,,1145 +Polonia,mazowieckie,pruszkowski,gm. Brwinów,,1146 +Polonia,mazowieckie,pruszkowski,gm. Michałowice,,1147 +Polonia,mazowieckie,pruszkowski,gm. Nadarzyn,,1148 +Polonia,mazowieckie,pruszkowski,gm. Raszyn,,1149 +Polonia,mazowieckie,przasnyski,m. Przasnysz,,1150 +Polonia,mazowieckie,przasnyski,gm. Chorzele,,1151 +Polonia,mazowieckie,przasnyski,gm. Czernice Borowe,,1152 +Polonia,mazowieckie,przasnyski,gm. Jednorożec,,1153 +Polonia,mazowieckie,przasnyski,gm. Krasne,,1154 +Polonia,mazowieckie,przasnyski,gm. Krzynowłoga Mała,,1155 +Polonia,mazowieckie,przasnyski,gm. Przasnysz,,1156 +Polonia,mazowieckie,przysuski,gm. Borkowice,,1157 +Polonia,mazowieckie,przysuski,gm. Gielniów,,1158 +Polonia,mazowieckie,przysuski,gm. Klwów,,1159 +Polonia,mazowieckie,przysuski,gm. Odrzywół,,1160 +Polonia,mazowieckie,przysuski,gm. Potworów,,1161 +Polonia,mazowieckie,przysuski,gm. Przysucha,,1162 +Polonia,mazowieckie,przysuski,gm. Rusinów,,1163 +Polonia,mazowieckie,przysuski,gm. Wieniawa,,1164 +Polonia,mazowieckie,pułtuski,gm. Gzy,,1165 +Polonia,mazowieckie,pułtuski,gm. Obryte,,1166 +Polonia,mazowieckie,pułtuski,gm. Pokrzywnica,,1167 +Polonia,mazowieckie,pułtuski,gm. Pułtusk,,1168 +Polonia,mazowieckie,pułtuski,gm. Świercze,,1169 +Polonia,mazowieckie,pułtuski,gm. Winnica,,1170 +Polonia,mazowieckie,pułtuski,gm. Zatory,,1171 +Polonia,mazowieckie,radomski,m. Pionki,,1172 +Polonia,mazowieckie,radomski,gm. Gózd,,1173 +Polonia,mazowieckie,radomski,gm. Iłża,,1174 +Polonia,mazowieckie,radomski,gm. Jastrzębia,,1175 +Polonia,mazowieckie,radomski,gm. Jedlińsk,,1176 +Polonia,mazowieckie,radomski,gm. Jedlnia-Letnisko,,1177 +Polonia,mazowieckie,radomski,gm. Kowala,,1178 +Polonia,mazowieckie,radomski,gm. Pionki,,1179 +Polonia,mazowieckie,radomski,gm. Przytyk,,1180 +Polonia,mazowieckie,radomski,gm. Skaryszew,,1181 +Polonia,mazowieckie,radomski,gm. Wierzbica,,1182 +Polonia,mazowieckie,radomski,gm. Wolanów,,1183 +Polonia,mazowieckie,radomski,gm. Zakrzew,,1184 +Polonia,mazowieckie,siedlecki,gm. Domanice,,1185 +Polonia,mazowieckie,siedlecki,gm. Korczew,,1186 +Polonia,mazowieckie,siedlecki,gm. Kotuń,,1187 +Polonia,mazowieckie,siedlecki,gm. Mokobody,,1188 +Polonia,mazowieckie,siedlecki,gm. Mordy,,1189 +Polonia,mazowieckie,siedlecki,gm. Paprotnia,,1190 +Polonia,mazowieckie,siedlecki,gm. Przesmyki,,1191 +Polonia,mazowieckie,siedlecki,gm. Siedlce,,1192 +Polonia,mazowieckie,siedlecki,gm. Skórzec,,1193 +Polonia,mazowieckie,siedlecki,gm. Suchożebry,,1194 +Polonia,mazowieckie,siedlecki,gm. Wiśniew,,1195 +Polonia,mazowieckie,siedlecki,gm. Wodynie,,1196 +Polonia,mazowieckie,siedlecki,gm. Zbuczyn,,1197 +Polonia,mazowieckie,sierpecki,m. Sierpc,,1198 +Polonia,mazowieckie,sierpecki,gm. Gozdowo,,1199 +Polonia,mazowieckie,sierpecki,gm. Mochowo,,1200 +Polonia,mazowieckie,sierpecki,gm. Rościszewo,,1201 +Polonia,mazowieckie,sierpecki,gm. Sierpc,,1202 +Polonia,mazowieckie,sierpecki,gm. Szczutowo,,1203 +Polonia,mazowieckie,sierpecki,gm. Zawidz,,1204 +Polonia,mazowieckie,sochaczewski,m. Sochaczew,,1205 +Polonia,mazowieckie,sochaczewski,gm. Brochów,,1206 +Polonia,mazowieckie,sochaczewski,gm. Iłów,,1207 +Polonia,mazowieckie,sochaczewski,gm. Młodzieszyn,,1208 +Polonia,mazowieckie,sochaczewski,gm. Nowa Sucha,,1209 +Polonia,mazowieckie,sochaczewski,gm. Rybno,,1210 +Polonia,mazowieckie,sochaczewski,gm. Sochaczew,,1211 +Polonia,mazowieckie,sochaczewski,gm. Teresin,,1212 +Polonia,mazowieckie,sokołowski,m. Sokołów Podlaski,,1213 +Polonia,mazowieckie,sokołowski,gm. Bielany,,1214 +Polonia,mazowieckie,sokołowski,gm. Ceranów,,1215 +Polonia,mazowieckie,sokołowski,gm. Jabłonna Lacka,,1216 +Polonia,mazowieckie,sokołowski,gm. Kosów Lacki,,1217 +Polonia,mazowieckie,sokołowski,gm. Repki,,1218 +Polonia,mazowieckie,sokołowski,gm. Sabnie,,1219 +Polonia,mazowieckie,sokołowski,gm. Sokołów Podlaski,,1220 +Polonia,mazowieckie,sokołowski,gm. Sterdyń,,1221 +Polonia,mazowieckie,szydłowiecki,gm. Chlewiska,,1222 +Polonia,mazowieckie,szydłowiecki,gm. Jastrząb,,1223 +Polonia,mazowieckie,szydłowiecki,gm. Mirów,,1224 +Polonia,mazowieckie,szydłowiecki,gm. Orońsko,,1225 +Polonia,mazowieckie,szydłowiecki,gm. Szydłowiec,,1226 +Polonia,mazowieckie,warszawski zachodni,gm. Błonie,,1227 +Polonia,mazowieckie,warszawski zachodni,gm. Izabelin,,1228 +Polonia,mazowieckie,warszawski zachodni,gm. Kampinos,,1229 +Polonia,mazowieckie,warszawski zachodni,gm. Leszno,,1230 +Polonia,mazowieckie,warszawski zachodni,gm. Łomianki,,1231 +Polonia,mazowieckie,warszawski zachodni,gm. Ożarów Mazowiecki,,1232 +Polonia,mazowieckie,warszawski zachodni,gm. Stare Babice,,1233 +Polonia,mazowieckie,węgrowski,m. Węgrów,,1234 +Polonia,mazowieckie,węgrowski,gm. Grębków,,1235 +Polonia,mazowieckie,węgrowski,gm. Korytnica,,1236 +Polonia,mazowieckie,węgrowski,gm. Liw,,1237 +Polonia,mazowieckie,węgrowski,gm. Łochów,,1238 +Polonia,mazowieckie,węgrowski,gm. Miedzna,,1239 +Polonia,mazowieckie,węgrowski,gm. Sadowne,,1240 +Polonia,mazowieckie,węgrowski,gm. Stoczek,,1241 +Polonia,mazowieckie,węgrowski,gm. Wierzbno,,1242 +Polonia,mazowieckie,wołomiński,m. Kobyłka,,1243 +Polonia,mazowieckie,wołomiński,m. Marki,,1244 +Polonia,mazowieckie,wołomiński,m. Ząbki,,1245 +Polonia,mazowieckie,wołomiński,m. Zielonka,,1246 +Polonia,mazowieckie,wołomiński,gm. Dąbrówka,,1247 +Polonia,mazowieckie,wołomiński,gm. Jadów,,1248 +Polonia,mazowieckie,wołomiński,gm. Klembów,,1249 +Polonia,mazowieckie,wołomiński,gm. Poświętne,,1250 +Polonia,mazowieckie,wołomiński,gm. Radzymin,,1251 +Polonia,mazowieckie,wołomiński,gm. Strachówka,,1252 +Polonia,mazowieckie,wołomiński,gm. Tłuszcz,,1253 +Polonia,mazowieckie,wołomiński,gm. Wołomin,,1254 +Polonia,mazowieckie,wyszkowski,gm. Brańszczyk,,1255 +Polonia,mazowieckie,wyszkowski,gm. Długosiodło,,1256 +Polonia,mazowieckie,wyszkowski,gm. Rząśnik,,1257 +Polonia,mazowieckie,wyszkowski,gm. Somianka,,1258 +Polonia,mazowieckie,wyszkowski,gm. Wyszków,,1259 +Polonia,mazowieckie,wyszkowski,gm. Zabrodzie,,1260 +Polonia,mazowieckie,zwoleński,gm. Kazanów,,1261 +Polonia,mazowieckie,zwoleński,gm. Policzna,,1262 +Polonia,mazowieckie,zwoleński,gm. Przyłęk,,1263 +Polonia,mazowieckie,zwoleński,gm. Tczów,,1264 +Polonia,mazowieckie,zwoleński,gm. Zwoleń,,1265 +Polonia,mazowieckie,żuromiński,gm. Bieżuń,,1266 +Polonia,mazowieckie,żuromiński,gm. Kuczbork-Osada,,1267 +Polonia,mazowieckie,żuromiński,gm. Lubowidz,,1268 +Polonia,mazowieckie,żuromiński,gm. Lutocin,,1269 +Polonia,mazowieckie,żuromiński,gm. Siemiątkowo,,1270 +Polonia,mazowieckie,żuromiński,gm. Żuromin,,1271 +Polonia,mazowieckie,żyrardowski,m. Żyrardów,,1272 +Polonia,mazowieckie,żyrardowski,gm. Mszczonów,,1273 +Polonia,mazowieckie,żyrardowski,gm. Puszcza Mariańska,,1274 +Polonia,mazowieckie,żyrardowski,gm. Radziejowice,,1275 +Polonia,mazowieckie,żyrardowski,gm. Wiskitki,,1276 +Polonia,mazowieckie,Ostrołęka,m. Ostrołęka,,1277 +Polonia,mazowieckie,Płock,m. Płock,,1278 +Polonia,mazowieckie,Radom,m. Radom,,1279 +Polonia,mazowieckie,Siedlce,m. Siedlce,,1280 +Polonia,mazowieckie,Warszawa,Bemowo,,1281 +Polonia,mazowieckie,Warszawa,Białołęka,,1282 +Polonia,mazowieckie,Warszawa,Bielany,,1283 +Polonia,mazowieckie,Warszawa,Mokotów,,1284 +Polonia,mazowieckie,Warszawa,Ochota,,1285 +Polonia,mazowieckie,Warszawa,Praga-Południe,,1286 +Polonia,mazowieckie,Warszawa,Praga-Północ,,1287 +Polonia,mazowieckie,Warszawa,Rembertów,,1288 +Polonia,mazowieckie,Warszawa,Śródmieście,,1289 +Polonia,mazowieckie,Warszawa,Targówek,,1290 +Polonia,mazowieckie,Warszawa,Ursus,,1291 +Polonia,mazowieckie,Warszawa,Ursynów,,1292 +Polonia,mazowieckie,Warszawa,Wawer,,1293 +Polonia,mazowieckie,Warszawa,Wesoła,,1294 +Polonia,mazowieckie,Warszawa,Wilanów,,1295 +Polonia,mazowieckie,Warszawa,Włochy,,1296 +Polonia,mazowieckie,Warszawa,Wola,,1297 +Polonia,mazowieckie,Warszawa,Żoliborz,,1298 +Polonia,opolskie,brzeski,m. Brzeg,,1299 +Polonia,opolskie,brzeski,gm. Skarbimierz,,1300 +Polonia,opolskie,brzeski,gm. Grodków,,1301 +Polonia,opolskie,brzeski,gm. Lewin Brzeski,,1302 +Polonia,opolskie,brzeski,gm. Lubsza,,1303 +Polonia,opolskie,brzeski,gm. Olszanka,,1304 +Polonia,opolskie,głubczycki,gm. Baborów,,1305 +Polonia,opolskie,głubczycki,gm. Branice,,1306 +Polonia,opolskie,głubczycki,gm. Głubczyce,,1307 +Polonia,opolskie,głubczycki,gm. Kietrz,,1308 +Polonia,opolskie,kędzierzyńsko-kozielski,m. Kędzierzyn-Koźle,,1309 +Polonia,opolskie,kędzierzyńsko-kozielski,gm. Bierawa,,1310 +Polonia,opolskie,kędzierzyńsko-kozielski,gm. Cisek,,1311 +Polonia,opolskie,kędzierzyńsko-kozielski,gm. Pawłowiczki,,1312 +Polonia,opolskie,kędzierzyńsko-kozielski,gm. Polska Cerekiew,,1313 +Polonia,opolskie,kędzierzyńsko-kozielski,gm. Reńska Wieś,,1314 +Polonia,opolskie,kluczborski,gm. Byczyna,,1315 +Polonia,opolskie,kluczborski,gm. Kluczbork,,1316 +Polonia,opolskie,kluczborski,gm. Lasowice Wielkie,,1317 +Polonia,opolskie,kluczborski,gm. Wołczyn,,1318 +Polonia,opolskie,krapkowicki,gm. Gogolin,,1319 +Polonia,opolskie,krapkowicki,gm. Krapkowice,,1320 +Polonia,opolskie,krapkowicki,gm. Strzeleczki,,1321 +Polonia,opolskie,krapkowicki,gm. Walce,,1322 +Polonia,opolskie,krapkowicki,gm. Zdzieszowice,,1323 +Polonia,opolskie,namysłowski,gm. Domaszowice,,1324 +Polonia,opolskie,namysłowski,gm. Namysłów,,1325 +Polonia,opolskie,namysłowski,gm. Pokój,,1326 +Polonia,opolskie,namysłowski,gm. Świerczów,,1327 +Polonia,opolskie,namysłowski,gm. Wilków,,1328 +Polonia,opolskie,nyski,gm. Głuchołazy,,1329 +Polonia,opolskie,nyski,gm. Kamiennik,,1330 +Polonia,opolskie,nyski,gm. Korfantów,,1331 +Polonia,opolskie,nyski,gm. Łambinowice,,1332 +Polonia,opolskie,nyski,gm. Nysa,,1333 +Polonia,opolskie,nyski,gm. Otmuchów,,1334 +Polonia,opolskie,nyski,gm. Paczków,,1335 +Polonia,opolskie,nyski,gm. Pakosławice,,1336 +Polonia,opolskie,nyski,gm. Skoroszyce,,1337 +Polonia,opolskie,oleski,gm. Dobrodzień,,1338 +Polonia,opolskie,oleski,gm. Gorzów Śląski,,1339 +Polonia,opolskie,oleski,gm. Olesno,,1340 +Polonia,opolskie,oleski,gm. Praszka,,1341 +Polonia,opolskie,oleski,gm. Radłów,,1342 +Polonia,opolskie,oleski,gm. Rudniki,,1343 +Polonia,opolskie,oleski,gm. Zębowice,,1344 +Polonia,opolskie,opolski,gm. Chrząstowice,,1345 +Polonia,opolskie,opolski,gm. Dąbrowa,,1346 +Polonia,opolskie,opolski,gm. Dobrzeń Wielki,,1347 +Polonia,opolskie,opolski,gm. Komprachcice,,1348 +Polonia,opolskie,opolski,gm. Łubniany,,1349 +Polonia,opolskie,opolski,gm. Murów,,1350 +Polonia,opolskie,opolski,gm. Niemodlin,,1351 +Polonia,opolskie,opolski,gm. Ozimek,,1352 +Polonia,opolskie,opolski,gm. Popielów,,1353 +Polonia,opolskie,opolski,gm. Prószków,,1354 +Polonia,opolskie,opolski,gm. Tarnów Opolski,,1355 +Polonia,opolskie,opolski,gm. Tułowice,,1356 +Polonia,opolskie,opolski,gm. Turawa,,1357 +Polonia,opolskie,prudnicki,gm. Biała,,1358 +Polonia,opolskie,prudnicki,gm. Głogówek,,1359 +Polonia,opolskie,prudnicki,gm. Lubrza,,1360 +Polonia,opolskie,prudnicki,gm. Prudnik,,1361 +Polonia,opolskie,strzelecki,gm. Izbicko,,1362 +Polonia,opolskie,strzelecki,gm. Jemielnica,,1363 +Polonia,opolskie,strzelecki,gm. Kolonowskie,,1364 +Polonia,opolskie,strzelecki,gm. Leśnica,,1365 +Polonia,opolskie,strzelecki,gm. Strzelce Opolskie,,1366 +Polonia,opolskie,strzelecki,gm. Ujazd,,1367 +Polonia,opolskie,strzelecki,gm. Zawadzkie,,1368 +Polonia,opolskie,Opole,m. Opole,,1369 +Polonia,podkarpackie,bieszczadzki,gm. Czarna,,1370 +Polonia,podkarpackie,bieszczadzki,gm. Lutowiska,,1371 +Polonia,podkarpackie,bieszczadzki,gm. Ustrzyki Dolne,,1372 +Polonia,podkarpackie,brzozowski,gm. Brzozów,,1373 +Polonia,podkarpackie,brzozowski,gm. Domaradz,,1374 +Polonia,podkarpackie,brzozowski,gm. Dydnia,,1375 +Polonia,podkarpackie,brzozowski,gm. Haczów,,1376 +Polonia,podkarpackie,brzozowski,gm. Jasienica Rosielna,,1377 +Polonia,podkarpackie,brzozowski,gm. Nozdrzec,,1378 +Polonia,podkarpackie,dębicki,m. Dębica,,1379 +Polonia,podkarpackie,dębicki,gm. Brzostek,,1380 +Polonia,podkarpackie,dębicki,gm. Czarna,,1381 +Polonia,podkarpackie,dębicki,gm. Dębica,,1382 +Polonia,podkarpackie,dębicki,gm. Jodłowa,,1383 +Polonia,podkarpackie,dębicki,gm. Pilzno,,1384 +Polonia,podkarpackie,dębicki,gm. Żyraków,,1385 +Polonia,podkarpackie,jarosławski,m. Jarosław,,1386 +Polonia,podkarpackie,jarosławski,m. Radymno,,1387 +Polonia,podkarpackie,jarosławski,gm. Chłopice,,1388 +Polonia,podkarpackie,jarosławski,gm. Jarosław,,1389 +Polonia,podkarpackie,jarosławski,gm. Laszki,,1390 +Polonia,podkarpackie,jarosławski,gm. Pawłosiów,,1391 +Polonia,podkarpackie,jarosławski,gm. Pruchnik,,1392 +Polonia,podkarpackie,jarosławski,gm. Radymno,,1393 +Polonia,podkarpackie,jarosławski,gm. Rokietnica,,1394 +Polonia,podkarpackie,jarosławski,gm. Roźwienica,,1395 +Polonia,podkarpackie,jarosławski,gm. Wiązownica,,1396 +Polonia,podkarpackie,jasielski,m. Jasło,,1397 +Polonia,podkarpackie,jasielski,gm. Brzyska,,1398 +Polonia,podkarpackie,jasielski,gm. Dębowiec,,1399 +Polonia,podkarpackie,jasielski,gm. Jasło,,1400 +Polonia,podkarpackie,jasielski,gm. Kołaczyce,,1401 +Polonia,podkarpackie,jasielski,gm. Krempna,,1402 +Polonia,podkarpackie,jasielski,gm. Nowy Żmigród,,1403 +Polonia,podkarpackie,jasielski,gm. Osiek Jasielski,,1404 +Polonia,podkarpackie,jasielski,gm. Skołyszyn,,1405 +Polonia,podkarpackie,jasielski,gm. Tarnowiec,,1406 +Polonia,podkarpackie,kolbuszowski,gm. Cmolas,,1407 +Polonia,podkarpackie,kolbuszowski,gm. Kolbuszowa,,1408 +Polonia,podkarpackie,kolbuszowski,gm. Majdan Królewski,,1409 +Polonia,podkarpackie,kolbuszowski,gm. Niwiska,,1410 +Polonia,podkarpackie,kolbuszowski,gm. Raniżów,,1411 +Polonia,podkarpackie,kolbuszowski,gm. Dzikowiec,,1412 +Polonia,podkarpackie,krośnieński,gm. Chorkówka,,1413 +Polonia,podkarpackie,krośnieński,gm. Dukla,,1414 +Polonia,podkarpackie,krośnieński,gm. Iwonicz-Zdrój,,1415 +Polonia,podkarpackie,krośnieński,gm. Jedlicze,,1416 +Polonia,podkarpackie,krośnieński,gm. Korczyna,,1417 +Polonia,podkarpackie,krośnieński,gm. Krościenko Wyżne,,1418 +Polonia,podkarpackie,krośnieński,gm. Miejsce Piastowe,,1419 +Polonia,podkarpackie,krośnieński,gm. Rymanów,,1420 +Polonia,podkarpackie,krośnieński,gm. Wojaszówka,,1421 +Polonia,podkarpackie,krośnieński,gm. Jaśliska,,1422 +Polonia,podkarpackie,leżajski,m. Leżajsk,,1423 +Polonia,podkarpackie,leżajski,gm. Grodzisko Dolne,,1424 +Polonia,podkarpackie,leżajski,gm. Kuryłówka,,1425 +Polonia,podkarpackie,leżajski,gm. Leżajsk,,1426 +Polonia,podkarpackie,leżajski,gm. Nowa Sarzyna,,1427 +Polonia,podkarpackie,lubaczowski,m. Lubaczów,,1428 +Polonia,podkarpackie,lubaczowski,gm. Cieszanów,,1429 +Polonia,podkarpackie,lubaczowski,gm. Horyniec-Zdrój,,1430 +Polonia,podkarpackie,lubaczowski,gm. Lubaczów,,1431 +Polonia,podkarpackie,lubaczowski,gm. Narol,,1432 +Polonia,podkarpackie,lubaczowski,gm. Oleszyce,,1433 +Polonia,podkarpackie,lubaczowski,gm. Stary Dzików,,1434 +Polonia,podkarpackie,lubaczowski,gm. Wielkie Oczy,,1435 +Polonia,podkarpackie,łańcucki,m. Łańcut,,1436 +Polonia,podkarpackie,łańcucki,gm. Białobrzegi,,1437 +Polonia,podkarpackie,łańcucki,gm. Czarna,,1438 +Polonia,podkarpackie,łańcucki,gm. Łańcut,,1439 +Polonia,podkarpackie,łańcucki,gm. Markowa,,1440 +Polonia,podkarpackie,łańcucki,gm. Rakszawa,,1441 +Polonia,podkarpackie,łańcucki,gm. Żołynia,,1442 +Polonia,podkarpackie,mielecki,m. Mielec,,1443 +Polonia,podkarpackie,mielecki,gm. Borowa,,1444 +Polonia,podkarpackie,mielecki,gm. Czermin,,1445 +Polonia,podkarpackie,mielecki,gm. Gawłuszowice,,1446 +Polonia,podkarpackie,mielecki,gm. Mielec,,1447 +Polonia,podkarpackie,mielecki,gm. Padew Narodowa,,1448 +Polonia,podkarpackie,mielecki,gm. Przecław,,1449 +Polonia,podkarpackie,mielecki,gm. Radomyśl Wielki,,1450 +Polonia,podkarpackie,mielecki,gm. Tuszów Narodowy,,1451 +Polonia,podkarpackie,mielecki,gm. Wadowice Górne,,1452 +Polonia,podkarpackie,niżański,gm. Harasiuki,,1453 +Polonia,podkarpackie,niżański,gm. Jarocin,,1454 +Polonia,podkarpackie,niżański,gm. Jeżowe,,1455 +Polonia,podkarpackie,niżański,gm. Krzeszów,,1456 +Polonia,podkarpackie,niżański,gm. Nisko,,1457 +Polonia,podkarpackie,niżański,gm. Rudnik nad Sanem,,1458 +Polonia,podkarpackie,niżański,gm. Ulanów,,1459 +Polonia,podkarpackie,przemyski,gm. Bircza,,1460 +Polonia,podkarpackie,przemyski,gm. Dubiecko,,1461 +Polonia,podkarpackie,przemyski,gm. Fredropol,,1462 +Polonia,podkarpackie,przemyski,gm. Krasiczyn,,1463 +Polonia,podkarpackie,przemyski,gm. Krzywcza,,1464 +Polonia,podkarpackie,przemyski,gm. Medyka,,1465 +Polonia,podkarpackie,przemyski,gm. Orły,,1466 +Polonia,podkarpackie,przemyski,gm. Przemyśl,,1467 +Polonia,podkarpackie,przemyski,gm. Stubno,,1468 +Polonia,podkarpackie,przemyski,gm. Żurawica,,1469 +Polonia,podkarpackie,przeworski,m. Przeworsk,,1470 +Polonia,podkarpackie,przeworski,gm. Adamówka,,1471 +Polonia,podkarpackie,przeworski,gm. Gać,,1472 +Polonia,podkarpackie,przeworski,gm. Jawornik Polski,,1473 +Polonia,podkarpackie,przeworski,gm. Kańczuga,,1474 +Polonia,podkarpackie,przeworski,gm. Przeworsk,,1475 +Polonia,podkarpackie,przeworski,gm. Sieniawa,,1476 +Polonia,podkarpackie,przeworski,gm. Tryńcza,,1477 +Polonia,podkarpackie,przeworski,gm. Zarzecze,,1478 +Polonia,podkarpackie,ropczycko-sędziszowski,gm. Iwierzyce,,1479 +Polonia,podkarpackie,ropczycko-sędziszowski,gm. Ostrów,,1480 +Polonia,podkarpackie,ropczycko-sędziszowski,gm. Ropczyce,,1481 +Polonia,podkarpackie,ropczycko-sędziszowski,gm. Sędziszów Małopolski,,1482 +Polonia,podkarpackie,ropczycko-sędziszowski,gm. Wielopole Skrzyńskie,,1483 +Polonia,podkarpackie,rzeszowski,m. Dynów,,1484 +Polonia,podkarpackie,rzeszowski,gm. Błażowa,,1485 +Polonia,podkarpackie,rzeszowski,gm. Boguchwała,,1486 +Polonia,podkarpackie,rzeszowski,gm. Chmielnik,,1487 +Polonia,podkarpackie,rzeszowski,gm. Dynów,,1488 +Polonia,podkarpackie,rzeszowski,gm. Głogów Małopolski,,1489 +Polonia,podkarpackie,rzeszowski,gm. Hyżne,,1490 +Polonia,podkarpackie,rzeszowski,gm. Kamień,,1491 +Polonia,podkarpackie,rzeszowski,gm. Krasne,,1492 +Polonia,podkarpackie,rzeszowski,gm. Lubenia,,1493 +Polonia,podkarpackie,rzeszowski,gm. Sokołów Małopolski,,1494 +Polonia,podkarpackie,rzeszowski,gm. Świlcza,,1495 +Polonia,podkarpackie,rzeszowski,gm. Trzebownisko,,1496 +Polonia,podkarpackie,rzeszowski,gm. Tyczyn,,1497 +Polonia,podkarpackie,sanocki,m. Sanok,,1498 +Polonia,podkarpackie,sanocki,gm. Besko,,1499 +Polonia,podkarpackie,sanocki,gm. Bukowsko,,1500 +Polonia,podkarpackie,sanocki,gm. Komańcza,,1501 +Polonia,podkarpackie,sanocki,gm. Sanok,,1502 +Polonia,podkarpackie,sanocki,gm. Tyrawa Wołoska,,1503 +Polonia,podkarpackie,sanocki,gm. Zagórz,,1504 +Polonia,podkarpackie,sanocki,gm. Zarszyn,,1505 +Polonia,podkarpackie,stalowowolski,m. Stalowa Wola,,1506 +Polonia,podkarpackie,stalowowolski,gm. Bojanów,,1507 +Polonia,podkarpackie,stalowowolski,gm. Pysznica,,1508 +Polonia,podkarpackie,stalowowolski,gm. Radomyśl nad Sanem,,1509 +Polonia,podkarpackie,stalowowolski,gm. Zaklików,,1510 +Polonia,podkarpackie,stalowowolski,gm. Zaleszany,,1511 +Polonia,podkarpackie,strzyżowski,gm. Czudec,,1512 +Polonia,podkarpackie,strzyżowski,gm. Frysztak,,1513 +Polonia,podkarpackie,strzyżowski,gm. Niebylec,,1514 +Polonia,podkarpackie,strzyżowski,gm. Strzyżów,,1515 +Polonia,podkarpackie,strzyżowski,gm. Wiśniowa,,1516 +Polonia,podkarpackie,tarnobrzeski,gm. Baranów Sandomierski,,1517 +Polonia,podkarpackie,tarnobrzeski,gm. Gorzyce,,1518 +Polonia,podkarpackie,tarnobrzeski,gm. Grębów,,1519 +Polonia,podkarpackie,tarnobrzeski,gm. Nowa Dęba,,1520 +Polonia,podkarpackie,leski,gm. Baligród,,1521 +Polonia,podkarpackie,leski,gm. Cisna,,1522 +Polonia,podkarpackie,leski,gm. Lesko,,1523 +Polonia,podkarpackie,leski,gm. Olszanica,,1524 +Polonia,podkarpackie,leski,gm. Solina,,1525 +Polonia,podkarpackie,Krosno,m. Krosno,,1526 +Polonia,podkarpackie,Przemyśl,m. Przemyśl,,1527 +Polonia,podkarpackie,Rzeszów,m. Rzeszów,,1528 +Polonia,podkarpackie,Tarnobrzeg,m. Tarnobrzeg,,1529 +Polonia,podlaskie,augustowski,m. Augustów,,1530 +Polonia,podlaskie,augustowski,gm. Augustów,,1531 +Polonia,podlaskie,augustowski,gm. Bargłów Kościelny,,1532 +Polonia,podlaskie,augustowski,gm. Lipsk,,1533 +Polonia,podlaskie,augustowski,gm. Nowinka,,1534 +Polonia,podlaskie,augustowski,gm. Płaska,,1535 +Polonia,podlaskie,augustowski,gm. Sztabin,,1536 +Polonia,podlaskie,białostocki,gm. Choroszcz,,1537 +Polonia,podlaskie,białostocki,gm. Czarna Białostocka,,1538 +Polonia,podlaskie,białostocki,gm. Dobrzyniewo Duże,,1539 +Polonia,podlaskie,białostocki,gm. Gródek,,1540 +Polonia,podlaskie,białostocki,gm. Juchnowiec Kościelny,,1541 +Polonia,podlaskie,białostocki,gm. Łapy,,1542 +Polonia,podlaskie,białostocki,gm. Michałowo,,1543 +Polonia,podlaskie,białostocki,gm. Poświętne,,1544 +Polonia,podlaskie,białostocki,gm. Supraśl,,1545 +Polonia,podlaskie,białostocki,gm. Suraż,,1546 +Polonia,podlaskie,białostocki,gm. Turośń Kościelna,,1547 +Polonia,podlaskie,białostocki,gm. Tykocin,,1548 +Polonia,podlaskie,białostocki,gm. Wasilków,,1549 +Polonia,podlaskie,białostocki,gm. Zabłudów,,1550 +Polonia,podlaskie,białostocki,gm. Zawady,,1551 +Polonia,podlaskie,bielski,m. Bielsk Podlaski,,1552 +Polonia,podlaskie,bielski,m. Brańsk,,1553 +Polonia,podlaskie,bielski,gm. Bielsk Podlaski,,1554 +Polonia,podlaskie,bielski,gm. Boćki,,1555 +Polonia,podlaskie,bielski,gm. Brańsk,,1556 +Polonia,podlaskie,bielski,gm. Orla,,1557 +Polonia,podlaskie,bielski,gm. Rudka,,1558 +Polonia,podlaskie,bielski,gm. Wyszki,,1559 +Polonia,podlaskie,grajewski,m. Grajewo,,1560 +Polonia,podlaskie,grajewski,gm. Grajewo,,1561 +Polonia,podlaskie,grajewski,gm. Radziłów,,1562 +Polonia,podlaskie,grajewski,gm. Rajgród,,1563 +Polonia,podlaskie,grajewski,gm. Szczuczyn,,1564 +Polonia,podlaskie,grajewski,gm. Wąsosz,,1565 +Polonia,podlaskie,hajnowski,m. Hajnówka,,1566 +Polonia,podlaskie,hajnowski,gm. Białowieża,,1567 +Polonia,podlaskie,hajnowski,gm. Czeremcha,,1568 +Polonia,podlaskie,hajnowski,gm. Czyże,,1569 +Polonia,podlaskie,hajnowski,gm. Dubicze Cerkiewne,,1570 +Polonia,podlaskie,hajnowski,gm. Hajnówka,,1571 +Polonia,podlaskie,hajnowski,gm. Kleszczele,,1572 +Polonia,podlaskie,hajnowski,gm. Narew,,1573 +Polonia,podlaskie,hajnowski,gm. Narewka,,1574 +Polonia,podlaskie,kolneński,m. Kolno,,1575 +Polonia,podlaskie,kolneński,gm. Grabowo,,1576 +Polonia,podlaskie,kolneński,gm. Kolno,,1577 +Polonia,podlaskie,kolneński,gm. Mały Płock,,1578 +Polonia,podlaskie,kolneński,gm. Stawiski,,1579 +Polonia,podlaskie,kolneński,gm. Turośl,,1580 +Polonia,podlaskie,łomżyński,gm. Jedwabne,,1581 +Polonia,podlaskie,łomżyński,gm. Łomża,,1582 +Polonia,podlaskie,łomżyński,gm. Miastkowo,,1583 +Polonia,podlaskie,łomżyński,gm. Nowogród,,1584 +Polonia,podlaskie,łomżyński,gm. Piątnica,,1585 +Polonia,podlaskie,łomżyński,gm. Przytuły,,1586 +Polonia,podlaskie,łomżyński,gm. Śniadowo,,1587 +Polonia,podlaskie,łomżyński,gm. Wizna,,1588 +Polonia,podlaskie,łomżyński,gm. Zbójna,,1589 +Polonia,podlaskie,moniecki,gm. Goniądz,,1590 +Polonia,podlaskie,moniecki,gm. Jasionówka,,1591 +Polonia,podlaskie,moniecki,gm. Jaświły,,1592 +Polonia,podlaskie,moniecki,gm. Knyszyn,,1593 +Polonia,podlaskie,moniecki,gm. Krypno,,1594 +Polonia,podlaskie,moniecki,gm. Mońki,,1595 +Polonia,podlaskie,moniecki,gm. Trzcianne,,1596 +Polonia,podlaskie,sejneński,m. Sejny,,1597 +Polonia,podlaskie,sejneński,gm. Giby,,1598 +Polonia,podlaskie,sejneński,gm. Krasnopol,,1599 +Polonia,podlaskie,sejneński,gm. Puńsk,,1600 +Polonia,podlaskie,sejneński,gm. Sejny,,1601 +Polonia,podlaskie,siemiatycki,m. Siemiatycze,,1602 +Polonia,podlaskie,siemiatycki,gm. Drohiczyn,,1603 +Polonia,podlaskie,siemiatycki,gm. Dziadkowice,,1604 +Polonia,podlaskie,siemiatycki,gm. Grodzisk,,1605 +Polonia,podlaskie,siemiatycki,gm. Mielnik,,1606 +Polonia,podlaskie,siemiatycki,gm. Milejczyce,,1607 +Polonia,podlaskie,siemiatycki,gm. Nurzec-Stacja,,1608 +Polonia,podlaskie,siemiatycki,gm. Perlejewo,,1609 +Polonia,podlaskie,siemiatycki,gm. Siemiatycze,,1610 +Polonia,podlaskie,sokólski,gm. Dąbrowa Białostocka,,1611 +Polonia,podlaskie,sokólski,gm. Janów,,1612 +Polonia,podlaskie,sokólski,gm. Korycin,,1613 +Polonia,podlaskie,sokólski,gm. Krynki,,1614 +Polonia,podlaskie,sokólski,gm. Kuźnica,,1615 +Polonia,podlaskie,sokólski,gm. Nowy Dwór,,1616 +Polonia,podlaskie,sokólski,gm. Sidra,,1617 +Polonia,podlaskie,sokólski,gm. Sokółka,,1618 +Polonia,podlaskie,sokólski,gm. Suchowola,,1619 +Polonia,podlaskie,sokólski,gm. Szudziałowo,,1620 +Polonia,podlaskie,suwalski,gm. Bakałarzewo,,1621 +Polonia,podlaskie,suwalski,gm. Filipów,,1622 +Polonia,podlaskie,suwalski,gm. Jeleniewo,,1623 +Polonia,podlaskie,suwalski,gm. Przerośl,,1624 +Polonia,podlaskie,suwalski,gm. Raczki,,1625 +Polonia,podlaskie,suwalski,gm. Rutka-Tartak,,1626 +Polonia,podlaskie,suwalski,gm. Suwałki,,1627 +Polonia,podlaskie,suwalski,gm. Szypliszki,,1628 +Polonia,podlaskie,suwalski,gm. Wiżajny,,1629 +Polonia,podlaskie,wysokomazowiecki,m. Wysokie Mazowieckie,,1630 +Polonia,podlaskie,wysokomazowiecki,gm. Ciechanowiec,,1631 +Polonia,podlaskie,wysokomazowiecki,gm. Czyżew,,1632 +Polonia,podlaskie,wysokomazowiecki,gm. Klukowo,,1633 +Polonia,podlaskie,wysokomazowiecki,gm. Kobylin-Borzymy,,1634 +Polonia,podlaskie,wysokomazowiecki,gm. Kulesze Kościelne,,1635 +Polonia,podlaskie,wysokomazowiecki,gm. Nowe Piekuty,,1636 +Polonia,podlaskie,wysokomazowiecki,gm. Sokoły,,1637 +Polonia,podlaskie,wysokomazowiecki,gm. Szepietowo,,1638 +Polonia,podlaskie,wysokomazowiecki,gm. Wysokie Mazowieckie,,1639 +Polonia,podlaskie,zambrowski,m. Zambrów,,1640 +Polonia,podlaskie,zambrowski,gm. Kołaki Kościelne,,1641 +Polonia,podlaskie,zambrowski,gm. Rutki,,1642 +Polonia,podlaskie,zambrowski,gm. Szumowo,,1643 +Polonia,podlaskie,zambrowski,gm. Zambrów,,1644 +Polonia,podlaskie,Białystok,m. Białystok,,1645 +Polonia,podlaskie,Łomża,m. Łomża,,1646 +Polonia,podlaskie,Suwałki,m. Suwałki,,1647 +Polonia,pomorskie,bytowski,gm. Borzytuchom,,1648 +Polonia,pomorskie,bytowski,gm. Bytów,,1649 +Polonia,pomorskie,bytowski,gm. Czarna Dąbrówka,,1650 +Polonia,pomorskie,bytowski,gm. Kołczygłowy,,1651 +Polonia,pomorskie,bytowski,gm. Lipnica,,1652 +Polonia,pomorskie,bytowski,gm. Miastko,,1653 +Polonia,pomorskie,bytowski,gm. Parchowo,,1654 +Polonia,pomorskie,bytowski,gm. Studzienice,,1655 +Polonia,pomorskie,bytowski,gm. Trzebielino,,1656 +Polonia,pomorskie,bytowski,gm. Tuchomie,,1657 +Polonia,pomorskie,chojnicki,m. Chojnice,,1658 +Polonia,pomorskie,chojnicki,gm. Brusy,,1659 +Polonia,pomorskie,chojnicki,gm. Chojnice,,1660 +Polonia,pomorskie,chojnicki,gm. Czersk,,1661 +Polonia,pomorskie,chojnicki,gm. Konarzyny,,1662 +Polonia,pomorskie,człuchowski,m. Człuchów,,1663 +Polonia,pomorskie,człuchowski,gm. Czarne,,1664 +Polonia,pomorskie,człuchowski,gm. Człuchów,,1665 +Polonia,pomorskie,człuchowski,gm. Debrzno,,1666 +Polonia,pomorskie,człuchowski,gm. Koczała,,1667 +Polonia,pomorskie,człuchowski,gm. Przechlewo,,1668 +Polonia,pomorskie,człuchowski,gm. Rzeczenica,,1669 +Polonia,pomorskie,gdański,m. Pruszcz Gdański,,1670 +Polonia,pomorskie,gdański,gm. Cedry Wielkie,,1671 +Polonia,pomorskie,gdański,gm. Kolbudy,,1672 +Polonia,pomorskie,gdański,gm. Pruszcz Gdański,,1673 +Polonia,pomorskie,gdański,gm. Przywidz,,1674 +Polonia,pomorskie,gdański,gm. Pszczółki,,1675 +Polonia,pomorskie,gdański,gm. Suchy Dąb,,1676 +Polonia,pomorskie,gdański,gm. Trąbki Wielkie,,1677 +Polonia,pomorskie,kartuski,gm. Chmielno,,1678 +Polonia,pomorskie,kartuski,gm. Kartuzy,,1679 +Polonia,pomorskie,kartuski,gm. Przodkowo,,1680 +Polonia,pomorskie,kartuski,gm. Sierakowice,,1681 +Polonia,pomorskie,kartuski,gm. Somonino,,1682 +Polonia,pomorskie,kartuski,gm. Stężyca,,1683 +Polonia,pomorskie,kartuski,gm. Sulęczyno,,1684 +Polonia,pomorskie,kartuski,gm. Żukowo,,1685 +Polonia,pomorskie,kościerski,m. Kościerzyna,,1686 +Polonia,pomorskie,kościerski,gm. Dziemiany,,1687 +Polonia,pomorskie,kościerski,gm. Karsin,,1688 +Polonia,pomorskie,kościerski,gm. Kościerzyna,,1689 +Polonia,pomorskie,kościerski,gm. Liniewo,,1690 +Polonia,pomorskie,kościerski,gm. Lipusz,,1691 +Polonia,pomorskie,kościerski,gm. Nowa Karczma,,1692 +Polonia,pomorskie,kościerski,gm. Stara Kiszewa,,1693 +Polonia,pomorskie,kwidzyński,m. Kwidzyn,,1694 +Polonia,pomorskie,kwidzyński,gm. Gardeja,,1695 +Polonia,pomorskie,kwidzyński,gm. Kwidzyn,,1696 +Polonia,pomorskie,kwidzyński,gm. Prabuty,,1697 +Polonia,pomorskie,kwidzyński,gm. Ryjewo,,1698 +Polonia,pomorskie,kwidzyński,gm. Sadlinki,,1699 +Polonia,pomorskie,lęborski,m. Lębork,,1700 +Polonia,pomorskie,lęborski,m. Łeba,,1701 +Polonia,pomorskie,lęborski,gm. Cewice,,1702 +Polonia,pomorskie,lęborski,gm. Nowa Wieś Lęborska,,1703 +Polonia,pomorskie,lęborski,gm. Wicko,,1704 +Polonia,pomorskie,malborski,m. Malbork,,1705 +Polonia,pomorskie,malborski,gm. Lichnowy,,1706 +Polonia,pomorskie,malborski,gm. Malbork,,1707 +Polonia,pomorskie,malborski,gm. Miłoradz,,1708 +Polonia,pomorskie,malborski,gm. Nowy Staw,,1709 +Polonia,pomorskie,malborski,gm. Stare Pole,,1710 +Polonia,pomorskie,nowodworski,m. Krynica Morska,,1711 +Polonia,pomorskie,nowodworski,gm. Nowy Dwór Gdański,,1712 +Polonia,pomorskie,nowodworski,gm. Ostaszewo,,1713 +Polonia,pomorskie,nowodworski,gm. Stegna,,1714 +Polonia,pomorskie,nowodworski,gm. Sztutowo,,1715 +Polonia,pomorskie,pucki,m. Hel,,1716 +Polonia,pomorskie,pucki,gm. Jastarnia,,1717 +Polonia,pomorskie,pucki,m. Puck,,1718 +Polonia,pomorskie,pucki,gm. Władysławowo,,1719 +Polonia,pomorskie,pucki,gm. Kosakowo,,1720 +Polonia,pomorskie,pucki,gm. Krokowa,,1721 +Polonia,pomorskie,pucki,gm. Puck,,1722 +Polonia,pomorskie,słupski,m. Ustka,,1723 +Polonia,pomorskie,słupski,gm. Damnica,,1724 +Polonia,pomorskie,słupski,gm. Dębnica Kaszubska,,1725 +Polonia,pomorskie,słupski,gm. Główczyce,,1726 +Polonia,pomorskie,słupski,gm. Kępice,,1727 +Polonia,pomorskie,słupski,gm. Kobylnica,,1728 +Polonia,pomorskie,słupski,gm. Potęgowo,,1729 +Polonia,pomorskie,słupski,gm. Słupsk,,1730 +Polonia,pomorskie,słupski,gm. Smołdzino,,1731 +Polonia,pomorskie,słupski,gm. Ustka,,1732 +Polonia,pomorskie,starogardzki,gm. Czarna Woda,,1733 +Polonia,pomorskie,starogardzki,m. Skórcz,,1734 +Polonia,pomorskie,starogardzki,m. Starogard Gdański,,1735 +Polonia,pomorskie,starogardzki,gm. Bobowo,,1736 +Polonia,pomorskie,starogardzki,gm. Kaliska,,1737 +Polonia,pomorskie,starogardzki,gm. Lubichowo,,1738 +Polonia,pomorskie,starogardzki,gm. Osieczna,,1739 +Polonia,pomorskie,starogardzki,gm. Osiek,,1740 +Polonia,pomorskie,starogardzki,gm. Skarszewy,,1741 +Polonia,pomorskie,starogardzki,gm. Skórcz,,1742 +Polonia,pomorskie,starogardzki,gm. Smętowo Graniczne,,1743 +Polonia,pomorskie,starogardzki,gm. Starogard Gdański,,1744 +Polonia,pomorskie,starogardzki,gm. Zblewo,,1745 +Polonia,pomorskie,tczewski,m. Tczew,,1746 +Polonia,pomorskie,tczewski,gm. Gniew,,1747 +Polonia,pomorskie,tczewski,gm. Morzeszczyn,,1748 +Polonia,pomorskie,tczewski,gm. Pelplin,,1749 +Polonia,pomorskie,tczewski,gm. Subkowy,,1750 +Polonia,pomorskie,tczewski,gm. Tczew,,1751 +Polonia,pomorskie,wejherowski,m. Reda,,1752 +Polonia,pomorskie,wejherowski,m. Rumia,,1753 +Polonia,pomorskie,wejherowski,m. Wejherowo,,1754 +Polonia,pomorskie,wejherowski,gm. Choczewo,,1755 +Polonia,pomorskie,wejherowski,gm. Gniewino,,1756 +Polonia,pomorskie,wejherowski,gm. Linia,,1757 +Polonia,pomorskie,wejherowski,gm. Luzino,,1758 +Polonia,pomorskie,wejherowski,gm. Łęczyce,,1759 +Polonia,pomorskie,wejherowski,gm. Szemud,,1760 +Polonia,pomorskie,wejherowski,gm. Wejherowo,,1761 +Polonia,pomorskie,sztumski,gm. Dzierzgoń,,1762 +Polonia,pomorskie,sztumski,gm. Mikołajki Pomorskie,,1763 +Polonia,pomorskie,sztumski,gm. Stary Dzierzgoń,,1764 +Polonia,pomorskie,sztumski,gm. Stary Targ,,1765 +Polonia,pomorskie,sztumski,gm. Sztum,,1766 +Polonia,pomorskie,Gdańsk,m. Gdańsk,,1767 +Polonia,pomorskie,Gdynia,m. Gdynia,,1768 +Polonia,pomorskie,Słupsk,m. Słupsk,,1769 +Polonia,pomorskie,Sopot,m. Sopot,,1770 +Polonia,śląskie,będziński,m. Będzin,,1771 +Polonia,śląskie,będziński,m. Czeladź,,1772 +Polonia,śląskie,będziński,m. Wojkowice,,1773 +Polonia,śląskie,będziński,gm. Bobrowniki,,1774 +Polonia,śląskie,będziński,gm. Mierzęcice,,1775 +Polonia,śląskie,będziński,gm. Psary,,1776 +Polonia,śląskie,będziński,gm. Siewierz,,1777 +Polonia,śląskie,będziński,m. Sławków,,1778 +Polonia,śląskie,bielski,m. Szczyrk,,1779 +Polonia,śląskie,bielski,gm. Bestwina,,1780 +Polonia,śląskie,bielski,gm. Buczkowice,,1781 +Polonia,śląskie,bielski,gm. Czechowice-Dziedzice,,1782 +Polonia,śląskie,bielski,gm. Jasienica,,1783 +Polonia,śląskie,bielski,gm. Jaworze,,1784 +Polonia,śląskie,bielski,gm. Kozy,,1785 +Polonia,śląskie,bielski,gm. Porąbka,,1786 +Polonia,śląskie,bielski,gm. Wilamowice,,1787 +Polonia,śląskie,bielski,gm. Wilkowice,,1788 +Polonia,śląskie,cieszyński,m. Cieszyn,,1789 +Polonia,śląskie,cieszyński,m. Ustroń,,1790 +Polonia,śląskie,cieszyński,m. Wisła,,1791 +Polonia,śląskie,cieszyński,gm. Brenna,,1792 +Polonia,śląskie,cieszyński,gm. Chybie,,1793 +Polonia,śląskie,cieszyński,gm. Dębowiec,,1794 +Polonia,śląskie,cieszyński,gm. Goleszów,,1795 +Polonia,śląskie,cieszyński,gm. Hażlach,,1796 +Polonia,śląskie,cieszyński,gm. Istebna,,1797 +Polonia,śląskie,cieszyński,gm. Skoczów,,1798 +Polonia,śląskie,cieszyński,gm. Strumień,,1799 +Polonia,śląskie,cieszyński,gm. Zebrzydowice,,1800 +Polonia,śląskie,częstochowski,gm. Blachownia,,1801 +Polonia,śląskie,częstochowski,gm. Dąbrowa Zielona,,1802 +Polonia,śląskie,częstochowski,gm. Janów,,1803 +Polonia,śląskie,częstochowski,gm. Kamienica Polska,,1804 +Polonia,śląskie,częstochowski,gm. Kłomnice,,1805 +Polonia,śląskie,częstochowski,gm. Koniecpol,,1806 +Polonia,śląskie,częstochowski,gm. Konopiska,,1807 +Polonia,śląskie,częstochowski,gm. Kruszyna,,1808 +Polonia,śląskie,częstochowski,gm. Lelów,,1809 +Polonia,śląskie,częstochowski,gm. Mstów,,1810 +Polonia,śląskie,częstochowski,gm. Mykanów,,1811 +Polonia,śląskie,częstochowski,gm. Olsztyn,,1812 +Polonia,śląskie,częstochowski,gm. Poczesna,,1813 +Polonia,śląskie,częstochowski,gm. Przyrów,,1814 +Polonia,śląskie,częstochowski,gm. Rędziny,,1815 +Polonia,śląskie,częstochowski,gm. Starcza,,1816 +Polonia,śląskie,gliwicki,m. Knurów,,1817 +Polonia,śląskie,gliwicki,m. Pyskowice,,1818 +Polonia,śląskie,gliwicki,gm. Gierałtowice,,1819 +Polonia,śląskie,gliwicki,gm. Pilchowice,,1820 +Polonia,śląskie,gliwicki,gm. Rudziniec,,1821 +Polonia,śląskie,gliwicki,gm. Sośnicowice,,1822 +Polonia,śląskie,gliwicki,gm. Toszek,,1823 +Polonia,śląskie,gliwicki,gm. Wielowieś,,1824 +Polonia,śląskie,kłobucki,gm. Kłobuck,,1825 +Polonia,śląskie,kłobucki,gm. Krzepice,,1826 +Polonia,śląskie,kłobucki,gm. Lipie,,1827 +Polonia,śląskie,kłobucki,gm. Miedźno,,1828 +Polonia,śląskie,kłobucki,gm. Opatów,,1829 +Polonia,śląskie,kłobucki,gm. Panki,,1830 +Polonia,śląskie,kłobucki,gm. Popów,,1831 +Polonia,śląskie,kłobucki,gm. Przystajń,,1832 +Polonia,śląskie,kłobucki,gm. Wręczyca Wielka,,1833 +Polonia,śląskie,lubliniecki,m. Lubliniec,,1834 +Polonia,śląskie,lubliniecki,gm. Boronów,,1835 +Polonia,śląskie,lubliniecki,gm. Ciasna,,1836 +Polonia,śląskie,lubliniecki,gm. Herby,,1837 +Polonia,śląskie,lubliniecki,gm. Kochanowice,,1838 +Polonia,śląskie,lubliniecki,gm. Koszęcin,,1839 +Polonia,śląskie,lubliniecki,gm. Pawonków,,1840 +Polonia,śląskie,lubliniecki,gm. Woźniki,,1841 +Polonia,śląskie,mikołowski,m. Łaziska Górne,,1842 +Polonia,śląskie,mikołowski,m. Mikołów,,1843 +Polonia,śląskie,mikołowski,m. Orzesze,,1844 +Polonia,śląskie,mikołowski,gm. Ornontowice,,1845 +Polonia,śląskie,mikołowski,gm. Wyry,,1846 +Polonia,śląskie,myszkowski,m. Myszków,,1847 +Polonia,śląskie,myszkowski,gm. Koziegłowy,,1848 +Polonia,śląskie,myszkowski,gm. Niegowa,,1849 +Polonia,śląskie,myszkowski,gm. Poraj,,1850 +Polonia,śląskie,myszkowski,gm. Żarki,,1851 +Polonia,śląskie,pszczyński,gm. Goczałkowice-Zdrój,,1852 +Polonia,śląskie,pszczyński,gm. Kobiór,,1853 +Polonia,śląskie,pszczyński,gm. Miedźna,,1854 +Polonia,śląskie,pszczyński,gm. Pawłowice,,1855 +Polonia,śląskie,pszczyński,gm. Pszczyna,,1856 +Polonia,śląskie,pszczyński,gm. Suszec,,1857 +Polonia,śląskie,raciborski,m. Racibórz,,1858 +Polonia,śląskie,raciborski,gm. Kornowac,,1859 +Polonia,śląskie,raciborski,gm. Krzanowice,,1860 +Polonia,śląskie,raciborski,gm. Krzyżanowice,,1861 +Polonia,śląskie,raciborski,gm. Kuźnia Raciborska,,1862 +Polonia,śląskie,raciborski,gm. Nędza,,1863 +Polonia,śląskie,raciborski,gm. Pietrowice Wielkie,,1864 +Polonia,śląskie,raciborski,gm. Rudnik,,1865 +Polonia,śląskie,rybnicki,gm. Czerwionka-Leszczyny,,1866 +Polonia,śląskie,rybnicki,gm. Gaszowice,,1867 +Polonia,śląskie,rybnicki,gm. Jejkowice,,1868 +Polonia,śląskie,rybnicki,gm. Lyski,,1869 +Polonia,śląskie,rybnicki,gm. Świerklany,,1870 +Polonia,śląskie,tarnogórski,m. Kalety,,1871 +Polonia,śląskie,tarnogórski,m. Miasteczko Śląskie,,1872 +Polonia,śląskie,tarnogórski,m. Radzionków,,1873 +Polonia,śląskie,tarnogórski,m. Tarnowskie Góry,,1874 +Polonia,śląskie,tarnogórski,gm. Krupski Młyn,,1875 +Polonia,śląskie,tarnogórski,gm. Ożarowice,,1876 +Polonia,śląskie,tarnogórski,gm. Świerklaniec,,1877 +Polonia,śląskie,tarnogórski,gm. Tworóg,,1878 +Polonia,śląskie,tarnogórski,gm. Zbrosławice,,1879 +Polonia,śląskie,bieruńsko-lędziński,m. Bieruń,,1880 +Polonia,śląskie,bieruńsko-lędziński,m. Imielin,,1881 +Polonia,śląskie,bieruńsko-lędziński,m. Lędziny,,1882 +Polonia,śląskie,bieruńsko-lędziński,gm. Bojszowy,,1883 +Polonia,śląskie,bieruńsko-lędziński,gm. Chełm Śląski,,1884 +Polonia,śląskie,wodzisławski,m. Pszów,,1885 +Polonia,śląskie,wodzisławski,m. Radlin,,1886 +Polonia,śląskie,wodzisławski,m. Rydułtowy,,1887 +Polonia,śląskie,wodzisławski,m. Wodzisław Śląski,,1888 +Polonia,śląskie,wodzisławski,gm. Godów,,1889 +Polonia,śląskie,wodzisławski,gm. Gorzyce,,1890 +Polonia,śląskie,wodzisławski,gm. Lubomia,,1891 +Polonia,śląskie,wodzisławski,gm. Marklowice,,1892 +Polonia,śląskie,wodzisławski,gm. Mszana,,1893 +Polonia,śląskie,zawierciański,m. Poręba,,1894 +Polonia,śląskie,zawierciański,m. Zawiercie,,1895 +Polonia,śląskie,zawierciański,gm. Irządze,,1896 +Polonia,śląskie,zawierciański,gm. Kroczyce,,1897 +Polonia,śląskie,zawierciański,gm. Łazy,,1898 +Polonia,śląskie,zawierciański,gm. Ogrodzieniec,,1899 +Polonia,śląskie,zawierciański,gm. Pilica,,1900 +Polonia,śląskie,zawierciański,gm. Szczekociny,,1901 +Polonia,śląskie,zawierciański,gm. Włodowice,,1902 +Polonia,śląskie,zawierciański,gm. Żarnowiec,,1903 +Polonia,śląskie,żywiecki,m. Żywiec,,1904 +Polonia,śląskie,żywiecki,gm. Czernichów,,1905 +Polonia,śląskie,żywiecki,gm. Gilowice,,1906 +Polonia,śląskie,żywiecki,gm. Jeleśnia,,1907 +Polonia,śląskie,żywiecki,gm. Koszarawa,,1908 +Polonia,śląskie,żywiecki,gm. Lipowa,,1909 +Polonia,śląskie,żywiecki,gm. Łękawica,,1910 +Polonia,śląskie,żywiecki,gm. Łodygowice,,1911 +Polonia,śląskie,żywiecki,gm. Milówka,,1912 +Polonia,śląskie,żywiecki,gm. Radziechowy-Wieprz,,1913 +Polonia,śląskie,żywiecki,gm. Rajcza,,1914 +Polonia,śląskie,żywiecki,gm. Ślemień,,1915 +Polonia,śląskie,żywiecki,gm. Świnna,,1916 +Polonia,śląskie,żywiecki,gm. Ujsoły,,1917 +Polonia,śląskie,żywiecki,gm. Węgierska Górka,,1918 +Polonia,śląskie,Bielsko-Biała,m. Bielsko-Biała,,1919 +Polonia,śląskie,Bytom,m. Bytom,,1920 +Polonia,śląskie,Chorzów,m. Chorzów,,1921 +Polonia,śląskie,Częstochowa,m. Częstochowa,,1922 +Polonia,śląskie,Dąbrowa Górnicza,m. Dąbrowa Górnicza,,1923 +Polonia,śląskie,Gliwice,m. Gliwice,,1924 +Polonia,śląskie,Jastrzębie-Zdrój,m. Jastrzębie-Zdrój,,1925 +Polonia,śląskie,Jaworzno,m. Jaworzno,,1926 +Polonia,śląskie,Katowice,m. Katowice,,1927 +Polonia,śląskie,Mysłowice,m. Mysłowice,,1928 +Polonia,śląskie,Piekary Śląskie,m. Piekary Śląskie,,1929 +Polonia,śląskie,Ruda Śląska,m. Ruda Śląska,,1930 +Polonia,śląskie,Rybnik,m. Rybnik,,1931 +Polonia,śląskie,Siemianowice Śląskie,m. Siemianowice Śląskie,,1932 +Polonia,śląskie,Sosnowiec,m. Sosnowiec,,1933 +Polonia,śląskie,Świętochłowice,m. Świętochłowice,,1934 +Polonia,śląskie,Tychy,m. Tychy,,1935 +Polonia,śląskie,Zabrze,m. Zabrze,,1936 +Polonia,śląskie,Żory,m. Żory,,1937 +Polonia,świętokrzyskie,buski,gm. Busko-Zdrój,,1938 +Polonia,świętokrzyskie,buski,gm. Gnojno,,1939 +Polonia,świętokrzyskie,buski,gm. Nowy Korczyn,,1940 +Polonia,świętokrzyskie,buski,gm. Pacanów,,1941 +Polonia,świętokrzyskie,buski,gm. Solec-Zdrój,,1942 +Polonia,świętokrzyskie,buski,gm. Stopnica,,1943 +Polonia,świętokrzyskie,buski,gm. Tuczępy,,1944 +Polonia,świętokrzyskie,buski,gm. Wiślica,,1945 +Polonia,świętokrzyskie,jędrzejowski,gm. Imielno,,1946 +Polonia,świętokrzyskie,jędrzejowski,gm. Jędrzejów,,1947 +Polonia,świętokrzyskie,jędrzejowski,gm. Małogoszcz,,1948 +Polonia,świętokrzyskie,jędrzejowski,gm. Nagłowice,,1949 +Polonia,świętokrzyskie,jędrzejowski,gm. Oksa,,1950 +Polonia,świętokrzyskie,jędrzejowski,gm. Sędziszów,,1951 +Polonia,świętokrzyskie,jędrzejowski,gm. Słupia (Jędrzejowska),,1952 +Polonia,świętokrzyskie,jędrzejowski,gm. Sobków,,1953 +Polonia,świętokrzyskie,jędrzejowski,gm. Wodzisław,,1954 +Polonia,świętokrzyskie,kazimierski,gm. Bejsce,,1955 +Polonia,świętokrzyskie,kazimierski,gm. Czarnocin,,1956 +Polonia,świętokrzyskie,kazimierski,gm. Kazimierza Wielka,,1957 +Polonia,świętokrzyskie,kazimierski,gm. Opatowiec,,1958 +Polonia,świętokrzyskie,kazimierski,gm. Skalbmierz,,1959 +Polonia,świętokrzyskie,kielecki,gm. Bieliny,,1960 +Polonia,świętokrzyskie,kielecki,gm. Bodzentyn,,1961 +Polonia,świętokrzyskie,kielecki,gm. Chęciny,,1962 +Polonia,świętokrzyskie,kielecki,gm. Chmielnik,,1963 +Polonia,świętokrzyskie,kielecki,gm. Daleszyce,,1964 +Polonia,świętokrzyskie,kielecki,gm. Górno,,1965 +Polonia,świętokrzyskie,kielecki,gm. Łagów,,1966 +Polonia,świętokrzyskie,kielecki,gm. Łopuszno,,1967 +Polonia,świętokrzyskie,kielecki,gm. Masłów,,1968 +Polonia,świętokrzyskie,kielecki,gm. Miedziana Góra,,1969 +Polonia,świętokrzyskie,kielecki,gm. Mniów,,1970 +Polonia,świętokrzyskie,kielecki,gm. Morawica,,1971 +Polonia,świętokrzyskie,kielecki,gm. Nowa Słupia,,1972 +Polonia,świętokrzyskie,kielecki,gm. Piekoszów,,1973 +Polonia,świętokrzyskie,kielecki,gm. Pierzchnica,,1974 +Polonia,świętokrzyskie,kielecki,gm. Raków,,1975 +Polonia,świętokrzyskie,kielecki,gm. Nowiny,,1976 +Polonia,świętokrzyskie,kielecki,gm. Strawczyn,,1977 +Polonia,świętokrzyskie,kielecki,gm. Zagnańsk,,1978 +Polonia,świętokrzyskie,konecki,gm. Fałków,,1979 +Polonia,świętokrzyskie,konecki,gm. Gowarczów,,1980 +Polonia,świętokrzyskie,konecki,gm. Końskie,,1981 +Polonia,świętokrzyskie,konecki,gm. Radoszyce,,1982 +Polonia,świętokrzyskie,konecki,gm. Ruda Maleniecka,,1983 +Polonia,świętokrzyskie,konecki,gm. Słupia Konecka,,1984 +Polonia,świętokrzyskie,konecki,gm. Smyków,,1985 +Polonia,świętokrzyskie,konecki,gm. Stąporków,,1986 +Polonia,świętokrzyskie,opatowski,gm. Baćkowice,,1987 +Polonia,świętokrzyskie,opatowski,gm. Iwaniska,,1988 +Polonia,świętokrzyskie,opatowski,gm. Lipnik,,1989 +Polonia,świętokrzyskie,opatowski,gm. Opatów,,1990 +Polonia,świętokrzyskie,opatowski,gm. Ożarów,,1991 +Polonia,świętokrzyskie,opatowski,gm. Sadowie,,1992 +Polonia,świętokrzyskie,opatowski,gm. Tarłów,,1993 +Polonia,świętokrzyskie,opatowski,gm. Wojciechowice,,1994 +Polonia,świętokrzyskie,ostrowiecki,m. Ostrowiec Świętokrzyski,,1995 +Polonia,świętokrzyskie,ostrowiecki,gm. Bałtów,,1996 +Polonia,świętokrzyskie,ostrowiecki,gm. Bodzechów,,1997 +Polonia,świętokrzyskie,ostrowiecki,gm. Ćmielów,,1998 +Polonia,świętokrzyskie,ostrowiecki,gm. Kunów,,1999 +Polonia,świętokrzyskie,ostrowiecki,gm. Waśniów,,2000 +Polonia,świętokrzyskie,pińczowski,gm. Działoszyce,,2001 +Polonia,świętokrzyskie,pińczowski,gm. Kije,,2002 +Polonia,świętokrzyskie,pińczowski,gm. Michałów,,2003 +Polonia,świętokrzyskie,pińczowski,gm. Pińczów,,2004 +Polonia,świętokrzyskie,pińczowski,gm. Złota,,2005 +Polonia,świętokrzyskie,sandomierski,m. Sandomierz,,2006 +Polonia,świętokrzyskie,sandomierski,gm. Dwikozy,,2007 +Polonia,świętokrzyskie,sandomierski,gm. Klimontów,,2008 +Polonia,świętokrzyskie,sandomierski,gm. Koprzywnica,,2009 +Polonia,świętokrzyskie,sandomierski,gm. Łoniów,,2010 +Polonia,świętokrzyskie,sandomierski,gm. Obrazów,,2011 +Polonia,świętokrzyskie,sandomierski,gm. Samborzec,,2012 +Polonia,świętokrzyskie,sandomierski,gm. Wilczyce,,2013 +Polonia,świętokrzyskie,sandomierski,gm. Zawichost,,2014 +Polonia,świętokrzyskie,skarżyski,m. Skarżysko-Kamienna,,2015 +Polonia,świętokrzyskie,skarżyski,gm. Bliżyn,,2016 +Polonia,świętokrzyskie,skarżyski,gm. Łączna,,2017 +Polonia,świętokrzyskie,skarżyski,gm. Skarżysko Kościelne,,2018 +Polonia,świętokrzyskie,skarżyski,gm. Suchedniów,,2019 +Polonia,świętokrzyskie,starachowicki,m. Starachowice,,2020 +Polonia,świętokrzyskie,starachowicki,gm. Brody,,2021 +Polonia,świętokrzyskie,starachowicki,gm. Mirzec,,2022 +Polonia,świętokrzyskie,starachowicki,gm. Pawłów,,2023 +Polonia,świętokrzyskie,starachowicki,gm. Wąchock,,2024 +Polonia,świętokrzyskie,staszowski,gm. Bogoria,,2025 +Polonia,świętokrzyskie,staszowski,gm. Łubnice,,2026 +Polonia,świętokrzyskie,staszowski,gm. Oleśnica,,2027 +Polonia,świętokrzyskie,staszowski,gm. Osiek,,2028 +Polonia,świętokrzyskie,staszowski,gm. Połaniec,,2029 +Polonia,świętokrzyskie,staszowski,gm. Rytwiany,,2030 +Polonia,świętokrzyskie,staszowski,gm. Staszów,,2031 +Polonia,świętokrzyskie,staszowski,gm. Szydłów,,2032 +Polonia,świętokrzyskie,włoszczowski,gm. Kluczewsko,,2033 +Polonia,świętokrzyskie,włoszczowski,gm. Krasocin,,2034 +Polonia,świętokrzyskie,włoszczowski,gm. Moskorzew,,2035 +Polonia,świętokrzyskie,włoszczowski,gm. Radków,,2036 +Polonia,świętokrzyskie,włoszczowski,gm. Secemin,,2037 +Polonia,świętokrzyskie,włoszczowski,gm. Włoszczowa,,2038 +Polonia,świętokrzyskie,Kielce,m. Kielce,,2039 +Polonia,warmińsko-mazurskie,bartoszycki,m. Bartoszyce,,2040 +Polonia,warmińsko-mazurskie,bartoszycki,m. Górowo Iławeckie,,2041 +Polonia,warmińsko-mazurskie,bartoszycki,gm. Bartoszyce,,2042 +Polonia,warmińsko-mazurskie,bartoszycki,gm. Bisztynek,,2043 +Polonia,warmińsko-mazurskie,bartoszycki,gm. Górowo Iławeckie,,2044 +Polonia,warmińsko-mazurskie,bartoszycki,gm. Sępopol,,2045 +Polonia,warmińsko-mazurskie,braniewski,m. Braniewo,,2046 +Polonia,warmińsko-mazurskie,braniewski,gm. Braniewo,,2047 +Polonia,warmińsko-mazurskie,braniewski,gm. Frombork,,2048 +Polonia,warmińsko-mazurskie,braniewski,gm. Lelkowo,,2049 +Polonia,warmińsko-mazurskie,braniewski,gm. Pieniężno,,2050 +Polonia,warmińsko-mazurskie,braniewski,gm. Płoskinia,,2051 +Polonia,warmińsko-mazurskie,braniewski,gm. Wilczęta,,2052 +Polonia,warmińsko-mazurskie,działdowski,m. Działdowo,,2053 +Polonia,warmińsko-mazurskie,działdowski,gm. Działdowo,,2054 +Polonia,warmińsko-mazurskie,działdowski,gm. Iłowo-Osada,,2055 +Polonia,warmińsko-mazurskie,działdowski,gm. Lidzbark,,2056 +Polonia,warmińsko-mazurskie,działdowski,gm. Płośnica,,2057 +Polonia,warmińsko-mazurskie,działdowski,gm. Rybno,,2058 +Polonia,warmińsko-mazurskie,elbląski,gm. Elbląg,,2059 +Polonia,warmińsko-mazurskie,elbląski,gm. Godkowo,,2060 +Polonia,warmińsko-mazurskie,elbląski,gm. Gronowo Elbląskie,,2061 +Polonia,warmińsko-mazurskie,elbląski,gm. Markusy,,2062 +Polonia,warmińsko-mazurskie,elbląski,gm. Milejewo,,2063 +Polonia,warmińsko-mazurskie,elbląski,gm. Młynary,,2064 +Polonia,warmińsko-mazurskie,elbląski,gm. Pasłęk,,2065 +Polonia,warmińsko-mazurskie,elbląski,gm. Rychliki,,2066 +Polonia,warmińsko-mazurskie,elbląski,gm. Tolkmicko,,2067 +Polonia,warmińsko-mazurskie,ełcki,m. Ełk,,2068 +Polonia,warmińsko-mazurskie,ełcki,gm. Ełk,,2069 +Polonia,warmińsko-mazurskie,ełcki,gm. Kalinowo,,2070 +Polonia,warmińsko-mazurskie,ełcki,gm. Prostki,,2071 +Polonia,warmińsko-mazurskie,ełcki,gm. Stare Juchy,,2072 +Polonia,warmińsko-mazurskie,giżycki,m. Giżycko,,2073 +Polonia,warmińsko-mazurskie,giżycki,gm. Giżycko,,2074 +Polonia,warmińsko-mazurskie,giżycki,gm. Kruklanki,,2075 +Polonia,warmińsko-mazurskie,giżycki,gm. Miłki,,2076 +Polonia,warmińsko-mazurskie,giżycki,gm. Ryn,,2077 +Polonia,warmińsko-mazurskie,giżycki,gm. Wydminy,,2078 +Polonia,warmińsko-mazurskie,iławski,m. Iława,,2079 +Polonia,warmińsko-mazurskie,iławski,m. Lubawa,,2080 +Polonia,warmińsko-mazurskie,iławski,gm. Iława,,2081 +Polonia,warmińsko-mazurskie,iławski,gm. Kisielice,,2082 +Polonia,warmińsko-mazurskie,iławski,gm. Lubawa,,2083 +Polonia,warmińsko-mazurskie,iławski,gm. Susz,,2084 +Polonia,warmińsko-mazurskie,iławski,gm. Zalewo,,2085 +Polonia,warmińsko-mazurskie,kętrzyński,m. Kętrzyn,,2086 +Polonia,warmińsko-mazurskie,kętrzyński,gm. Barciany,,2087 +Polonia,warmińsko-mazurskie,kętrzyński,gm. Kętrzyn,,2088 +Polonia,warmińsko-mazurskie,kętrzyński,gm. Korsze,,2089 +Polonia,warmińsko-mazurskie,kętrzyński,gm. Reszel,,2090 +Polonia,warmińsko-mazurskie,kętrzyński,gm. Srokowo,,2091 +Polonia,warmińsko-mazurskie,lidzbarski,m. Lidzbark Warmiński,,2092 +Polonia,warmińsko-mazurskie,lidzbarski,gm. Kiwity,,2093 +Polonia,warmińsko-mazurskie,lidzbarski,gm. Lidzbark Warmiński,,2094 +Polonia,warmińsko-mazurskie,lidzbarski,gm. Lubomino,,2095 +Polonia,warmińsko-mazurskie,lidzbarski,gm. Orneta,,2096 +Polonia,warmińsko-mazurskie,mrągowski,m. Mrągowo,,2097 +Polonia,warmińsko-mazurskie,mrągowski,gm. Mikołajki,,2098 +Polonia,warmińsko-mazurskie,mrągowski,gm. Mrągowo,,2099 +Polonia,warmińsko-mazurskie,mrągowski,gm. Piecki,,2100 +Polonia,warmińsko-mazurskie,mrągowski,gm. Sorkwity,,2101 +Polonia,warmińsko-mazurskie,nidzicki,gm. Janowiec Kościelny,,2102 +Polonia,warmińsko-mazurskie,nidzicki,gm. Janowo,,2103 +Polonia,warmińsko-mazurskie,nidzicki,gm. Kozłowo,,2104 +Polonia,warmińsko-mazurskie,nidzicki,gm. Nidzica,,2105 +Polonia,warmińsko-mazurskie,nowomiejski,m. Nowe Miasto Lubawskie,,2106 +Polonia,warmińsko-mazurskie,nowomiejski,gm. Biskupiec,,2107 +Polonia,warmińsko-mazurskie,nowomiejski,gm. Grodziczno,,2108 +Polonia,warmińsko-mazurskie,nowomiejski,gm. Kurzętnik,,2109 +Polonia,warmińsko-mazurskie,nowomiejski,gm. Nowe Miasto Lubawskie,,2110 +Polonia,warmińsko-mazurskie,olecki,gm. Kowale Oleckie,,2111 +Polonia,warmińsko-mazurskie,olecki,gm. Olecko,,2112 +Polonia,warmińsko-mazurskie,olecki,gm. Świętajno,,2113 +Polonia,warmińsko-mazurskie,olecki,gm. Wieliczki,,2114 +Polonia,warmińsko-mazurskie,olsztyński,gm. Barczewo,,2115 +Polonia,warmińsko-mazurskie,olsztyński,gm. Biskupiec,,2116 +Polonia,warmińsko-mazurskie,olsztyński,gm. Dobre Miasto,,2117 +Polonia,warmińsko-mazurskie,olsztyński,gm. Dywity,,2118 +Polonia,warmińsko-mazurskie,olsztyński,gm. Gietrzwałd,,2119 +Polonia,warmińsko-mazurskie,olsztyński,gm. Jeziorany,,2120 +Polonia,warmińsko-mazurskie,olsztyński,gm. Jonkowo,,2121 +Polonia,warmińsko-mazurskie,olsztyński,gm. Kolno,,2122 +Polonia,warmińsko-mazurskie,olsztyński,gm. Olsztynek,,2123 +Polonia,warmińsko-mazurskie,olsztyński,gm. Purda,,2124 +Polonia,warmińsko-mazurskie,olsztyński,gm. Stawiguda,,2125 +Polonia,warmińsko-mazurskie,olsztyński,gm. Świątki,,2126 +Polonia,warmińsko-mazurskie,ostródzki,m. Ostróda,,2127 +Polonia,warmińsko-mazurskie,ostródzki,gm. Dąbrówno,,2128 +Polonia,warmińsko-mazurskie,ostródzki,gm. Grunwald,,2129 +Polonia,warmińsko-mazurskie,ostródzki,gm. Łukta,,2130 +Polonia,warmińsko-mazurskie,ostródzki,gm. Małdyty,,2131 +Polonia,warmińsko-mazurskie,ostródzki,gm. Miłakowo,,2132 +Polonia,warmińsko-mazurskie,ostródzki,gm. Miłomłyn,,2133 +Polonia,warmińsko-mazurskie,ostródzki,gm. Morąg,,2134 +Polonia,warmińsko-mazurskie,ostródzki,gm. Ostróda,,2135 +Polonia,warmińsko-mazurskie,piski,gm. Biała Piska,,2136 +Polonia,warmińsko-mazurskie,piski,gm. Orzysz,,2137 +Polonia,warmińsko-mazurskie,piski,gm. Pisz,,2138 +Polonia,warmińsko-mazurskie,piski,gm. Ruciane-Nida,,2139 +Polonia,warmińsko-mazurskie,szczycieński,m. Szczytno,,2140 +Polonia,warmińsko-mazurskie,szczycieński,gm. Dźwierzuty,,2141 +Polonia,warmińsko-mazurskie,szczycieński,gm. Jedwabno,,2142 +Polonia,warmińsko-mazurskie,szczycieński,gm. Pasym,,2143 +Polonia,warmińsko-mazurskie,szczycieński,gm. Rozogi,,2144 +Polonia,warmińsko-mazurskie,szczycieński,gm. Szczytno,,2145 +Polonia,warmińsko-mazurskie,szczycieński,gm. Świętajno,,2146 +Polonia,warmińsko-mazurskie,szczycieński,gm. Wielbark,,2147 +Polonia,warmińsko-mazurskie,gołdapski,gm. Banie Mazurskie,,2148 +Polonia,warmińsko-mazurskie,gołdapski,gm. Dubeninki,,2149 +Polonia,warmińsko-mazurskie,gołdapski,gm. Gołdap,,2150 +Polonia,warmińsko-mazurskie,węgorzewski,gm. Budry,,2151 +Polonia,warmińsko-mazurskie,węgorzewski,gm. Pozezdrze,,2152 +Polonia,warmińsko-mazurskie,węgorzewski,gm. Węgorzewo,,2153 +Polonia,warmińsko-mazurskie,Elbląg,m. Elbląg,,2154 +Polonia,warmińsko-mazurskie,Olsztyn,m. Olsztyn,,2155 +Polonia,wielkopolskie,chodzieski,m. Chodzież,,2156 +Polonia,wielkopolskie,chodzieski,gm. Budzyń,,2157 +Polonia,wielkopolskie,chodzieski,gm. Chodzież,,2158 +Polonia,wielkopolskie,chodzieski,gm. Margonin,,2159 +Polonia,wielkopolskie,chodzieski,gm. Szamocin,,2160 +Polonia,wielkopolskie,czarnkowsko-trzcianecki,m. Czarnków,,2161 +Polonia,wielkopolskie,czarnkowsko-trzcianecki,gm. Czarnków,,2162 +Polonia,wielkopolskie,czarnkowsko-trzcianecki,gm. Drawsko,,2163 +Polonia,wielkopolskie,czarnkowsko-trzcianecki,gm. Krzyż Wielkopolski,,2164 +Polonia,wielkopolskie,czarnkowsko-trzcianecki,gm. Lubasz,,2165 +Polonia,wielkopolskie,czarnkowsko-trzcianecki,gm. Połajewo,,2166 +Polonia,wielkopolskie,czarnkowsko-trzcianecki,gm. Trzcianka,,2167 +Polonia,wielkopolskie,czarnkowsko-trzcianecki,gm. Wieleń,,2168 +Polonia,wielkopolskie,gnieźnieński,m. Gniezno,,2169 +Polonia,wielkopolskie,gnieźnieński,gm. Czerniejewo,,2170 +Polonia,wielkopolskie,gnieźnieński,gm. Gniezno,,2171 +Polonia,wielkopolskie,gnieźnieński,gm. Kiszkowo,,2172 +Polonia,wielkopolskie,gnieźnieński,gm. Kłecko,,2173 +Polonia,wielkopolskie,gnieźnieński,gm. Łubowo,,2174 +Polonia,wielkopolskie,gnieźnieński,gm. Mieleszyn,,2175 +Polonia,wielkopolskie,gnieźnieński,gm. Niechanowo,,2176 +Polonia,wielkopolskie,gnieźnieński,gm. Trzemeszno,,2177 +Polonia,wielkopolskie,gnieźnieński,gm. Witkowo,,2178 +Polonia,wielkopolskie,gostyński,gm. Borek Wielkopolski,,2179 +Polonia,wielkopolskie,gostyński,gm. Gostyń,,2180 +Polonia,wielkopolskie,gostyński,gm. Krobia,,2181 +Polonia,wielkopolskie,gostyński,gm. Pępowo,,2182 +Polonia,wielkopolskie,gostyński,gm. Piaski,,2183 +Polonia,wielkopolskie,gostyński,gm. Pogorzela,,2184 +Polonia,wielkopolskie,gostyński,gm. Poniec,,2185 +Polonia,wielkopolskie,grodziski,gm. Granowo,,2186 +Polonia,wielkopolskie,grodziski,gm. Grodzisk Wielkopolski,,2187 +Polonia,wielkopolskie,grodziski,gm. Kamieniec,,2188 +Polonia,wielkopolskie,grodziski,gm. Rakoniewice,,2189 +Polonia,wielkopolskie,grodziski,gm. Wielichowo,,2190 +Polonia,wielkopolskie,jarociński,gm. Jaraczewo,,2191 +Polonia,wielkopolskie,jarociński,gm. Jarocin,,2192 +Polonia,wielkopolskie,jarociński,gm. Kotlin,,2193 +Polonia,wielkopolskie,jarociński,gm. Żerków,,2194 +Polonia,wielkopolskie,kaliski,gm. Blizanów,,2195 +Polonia,wielkopolskie,kaliski,gm. Brzeziny,,2196 +Polonia,wielkopolskie,kaliski,gm. Ceków-Kolonia,,2197 +Polonia,wielkopolskie,kaliski,gm. Godziesze Wielkie,,2198 +Polonia,wielkopolskie,kaliski,gm. Koźminek,,2199 +Polonia,wielkopolskie,kaliski,gm. Lisków,,2200 +Polonia,wielkopolskie,kaliski,gm. Mycielin,,2201 +Polonia,wielkopolskie,kaliski,gm. Opatówek,,2202 +Polonia,wielkopolskie,kaliski,gm. Stawiszyn,,2203 +Polonia,wielkopolskie,kaliski,gm. Szczytniki,,2204 +Polonia,wielkopolskie,kaliski,gm. Żelazków,,2205 +Polonia,wielkopolskie,kępiński,gm. Baranów,,2206 +Polonia,wielkopolskie,kępiński,gm. Bralin,,2207 +Polonia,wielkopolskie,kępiński,gm. Kępno,,2208 +Polonia,wielkopolskie,kępiński,gm. Łęka Opatowska,,2209 +Polonia,wielkopolskie,kępiński,gm. Perzów,,2210 +Polonia,wielkopolskie,kępiński,gm. Rychtal,,2211 +Polonia,wielkopolskie,kępiński,gm. Trzcinica,,2212 +Polonia,wielkopolskie,kolski,m. Koło,,2213 +Polonia,wielkopolskie,kolski,gm. Babiak,,2214 +Polonia,wielkopolskie,kolski,gm. Chodów,,2215 +Polonia,wielkopolskie,kolski,gm. Dąbie,,2216 +Polonia,wielkopolskie,kolski,gm. Grzegorzew,,2217 +Polonia,wielkopolskie,kolski,gm. Kłodawa,,2218 +Polonia,wielkopolskie,kolski,gm. Koło,,2219 +Polonia,wielkopolskie,kolski,gm. Kościelec,,2220 +Polonia,wielkopolskie,kolski,gm. Olszówka,,2221 +Polonia,wielkopolskie,kolski,gm. Osiek Mały,,2222 +Polonia,wielkopolskie,kolski,gm. Przedecz,,2223 +Polonia,wielkopolskie,koniński,gm. Golina,,2224 +Polonia,wielkopolskie,koniński,gm. Grodziec,,2225 +Polonia,wielkopolskie,koniński,gm. Kazimierz Biskupi,,2226 +Polonia,wielkopolskie,koniński,gm. Kleczew,,2227 +Polonia,wielkopolskie,koniński,gm. Kramsk,,2228 +Polonia,wielkopolskie,koniński,gm. Krzymów,,2229 +Polonia,wielkopolskie,koniński,gm. Rychwał,,2230 +Polonia,wielkopolskie,koniński,gm. Rzgów,,2231 +Polonia,wielkopolskie,koniński,gm. Skulsk,,2232 +Polonia,wielkopolskie,koniński,gm. Sompolno,,2233 +Polonia,wielkopolskie,koniński,gm. Stare Miasto,,2234 +Polonia,wielkopolskie,koniński,gm. Ślesin,,2235 +Polonia,wielkopolskie,koniński,gm. Wierzbinek,,2236 +Polonia,wielkopolskie,koniński,gm. Wilczyn,,2237 +Polonia,wielkopolskie,kościański,m. Kościan,,2238 +Polonia,wielkopolskie,kościański,gm. Czempiń,,2239 +Polonia,wielkopolskie,kościański,gm. Kościan,,2240 +Polonia,wielkopolskie,kościański,gm. Krzywiń,,2241 +Polonia,wielkopolskie,kościański,gm. Śmigiel,,2242 +Polonia,wielkopolskie,krotoszyński,m. Sulmierzyce,,2243 +Polonia,wielkopolskie,krotoszyński,gm. Kobylin,,2244 +Polonia,wielkopolskie,krotoszyński,gm. Koźmin Wielkopolski,,2245 +Polonia,wielkopolskie,krotoszyński,gm. Krotoszyn,,2246 +Polonia,wielkopolskie,krotoszyński,gm. Rozdrażew,,2247 +Polonia,wielkopolskie,krotoszyński,gm. Zduny,,2248 +Polonia,wielkopolskie,leszczyński,gm. Krzemieniewo,,2249 +Polonia,wielkopolskie,leszczyński,gm. Lipno,,2250 +Polonia,wielkopolskie,leszczyński,gm. Osieczna,,2251 +Polonia,wielkopolskie,leszczyński,gm. Rydzyna,,2252 +Polonia,wielkopolskie,leszczyński,gm. Święciechowa,,2253 +Polonia,wielkopolskie,leszczyński,gm. Wijewo,,2254 +Polonia,wielkopolskie,leszczyński,gm. Włoszakowice,,2255 +Polonia,wielkopolskie,międzychodzki,gm. Chrzypsko Wielkie,,2256 +Polonia,wielkopolskie,międzychodzki,gm. Kwilcz,,2257 +Polonia,wielkopolskie,międzychodzki,gm. Międzychód,,2258 +Polonia,wielkopolskie,międzychodzki,gm. Sieraków,,2259 +Polonia,wielkopolskie,nowotomyski,gm. Kuślin,,2260 +Polonia,wielkopolskie,nowotomyski,gm. Lwówek,,2261 +Polonia,wielkopolskie,nowotomyski,gm. Miedzichowo,,2262 +Polonia,wielkopolskie,nowotomyski,gm. Nowy Tomyśl,,2263 +Polonia,wielkopolskie,nowotomyski,gm. Opalenica,,2264 +Polonia,wielkopolskie,nowotomyski,gm. Zbąszyń,,2265 +Polonia,wielkopolskie,obornicki,gm. Oborniki,,2266 +Polonia,wielkopolskie,obornicki,gm. Rogoźno,,2267 +Polonia,wielkopolskie,obornicki,gm. Ryczywół,,2268 +Polonia,wielkopolskie,ostrowski,m. Ostrów Wielkopolski,,2269 +Polonia,wielkopolskie,ostrowski,gm. Nowe Skalmierzyce,,2270 +Polonia,wielkopolskie,ostrowski,gm. Odolanów,,2271 +Polonia,wielkopolskie,ostrowski,gm. Ostrów Wielkopolski,,2272 +Polonia,wielkopolskie,ostrowski,gm. Przygodzice,,2273 +Polonia,wielkopolskie,ostrowski,gm. Raszków,,2274 +Polonia,wielkopolskie,ostrowski,gm. Sieroszewice,,2275 +Polonia,wielkopolskie,ostrowski,gm. Sośnie,,2276 +Polonia,wielkopolskie,ostrzeszowski,gm. Czajków,,2277 +Polonia,wielkopolskie,ostrzeszowski,gm. Doruchów,,2278 +Polonia,wielkopolskie,ostrzeszowski,gm. Grabów nad Prosną,,2279 +Polonia,wielkopolskie,ostrzeszowski,gm. Kobyla Góra,,2280 +Polonia,wielkopolskie,ostrzeszowski,gm. Kraszewice,,2281 +Polonia,wielkopolskie,ostrzeszowski,gm. Mikstat,,2282 +Polonia,wielkopolskie,ostrzeszowski,gm. Ostrzeszów,,2283 +Polonia,wielkopolskie,pilski,m. Piła,,2284 +Polonia,wielkopolskie,pilski,gm. Białośliwie,,2285 +Polonia,wielkopolskie,pilski,gm. Kaczory,,2286 +Polonia,wielkopolskie,pilski,gm. Łobżenica,,2287 +Polonia,wielkopolskie,pilski,gm. Miasteczko Krajeńskie,,2288 +Polonia,wielkopolskie,pilski,gm. Szydłowo,,2289 +Polonia,wielkopolskie,pilski,gm. Ujście,,2290 +Polonia,wielkopolskie,pilski,gm. Wyrzysk,,2291 +Polonia,wielkopolskie,pilski,gm. Wysoka,,2292 +Polonia,wielkopolskie,pleszewski,gm. Chocz,,2293 +Polonia,wielkopolskie,pleszewski,gm. Czermin,,2294 +Polonia,wielkopolskie,pleszewski,gm. Dobrzyca,,2295 +Polonia,wielkopolskie,pleszewski,gm. Gizałki,,2296 +Polonia,wielkopolskie,pleszewski,gm. Gołuchów,,2297 +Polonia,wielkopolskie,pleszewski,gm. Pleszew,,2298 +Polonia,wielkopolskie,poznański,m. Luboń,,2299 +Polonia,wielkopolskie,poznański,m. Puszczykowo,,2300 +Polonia,wielkopolskie,poznański,gm. Buk,,2301 +Polonia,wielkopolskie,poznański,gm. Czerwonak,,2302 +Polonia,wielkopolskie,poznański,gm. Dopiewo,,2303 +Polonia,wielkopolskie,poznański,gm. Kleszczewo,,2304 +Polonia,wielkopolskie,poznański,gm. Komorniki,,2305 +Polonia,wielkopolskie,poznański,gm. Kostrzyn,,2306 +Polonia,wielkopolskie,poznański,gm. Kórnik,,2307 +Polonia,wielkopolskie,poznański,gm. Mosina,,2308 +Polonia,wielkopolskie,poznański,gm. Murowana Goślina,,2309 +Polonia,wielkopolskie,poznański,gm. Pobiedziska,,2310 +Polonia,wielkopolskie,poznański,gm. Rokietnica,,2311 +Polonia,wielkopolskie,poznański,gm. Stęszew,,2312 +Polonia,wielkopolskie,poznański,gm. Suchy Las,,2313 +Polonia,wielkopolskie,poznański,gm. Swarzędz,,2314 +Polonia,wielkopolskie,poznański,gm. Tarnowo Podgórne,,2315 +Polonia,wielkopolskie,rawicki,gm. Bojanowo,,2316 +Polonia,wielkopolskie,rawicki,gm. Jutrosin,,2317 +Polonia,wielkopolskie,rawicki,gm. Miejska Górka,,2318 +Polonia,wielkopolskie,rawicki,gm. Pakosław,,2319 +Polonia,wielkopolskie,rawicki,gm. Rawicz,,2320 +Polonia,wielkopolskie,słupecki,m. Słupca,,2321 +Polonia,wielkopolskie,słupecki,gm. Lądek,,2322 +Polonia,wielkopolskie,słupecki,gm. Orchowo,,2323 +Polonia,wielkopolskie,słupecki,gm. Ostrowite,,2324 +Polonia,wielkopolskie,słupecki,gm. Powidz,,2325 +Polonia,wielkopolskie,słupecki,gm. Słupca,,2326 +Polonia,wielkopolskie,słupecki,gm. Strzałkowo,,2327 +Polonia,wielkopolskie,słupecki,gm. Zagórów,,2328 +Polonia,wielkopolskie,szamotulski,m. Obrzycko,,2329 +Polonia,wielkopolskie,szamotulski,gm. Duszniki,,2330 +Polonia,wielkopolskie,szamotulski,gm. Kaźmierz,,2331 +Polonia,wielkopolskie,szamotulski,gm. Obrzycko,,2332 +Polonia,wielkopolskie,szamotulski,gm. Ostroróg,,2333 +Polonia,wielkopolskie,szamotulski,gm. Pniewy,,2334 +Polonia,wielkopolskie,szamotulski,gm. Szamotuły,,2335 +Polonia,wielkopolskie,szamotulski,gm. Wronki,,2336 +Polonia,wielkopolskie,średzki,gm. Dominowo,,2337 +Polonia,wielkopolskie,średzki,gm. Krzykosy,,2338 +Polonia,wielkopolskie,średzki,gm. Nowe Miasto nad Wartą,,2339 +Polonia,wielkopolskie,średzki,gm. Środa Wielkopolska,,2340 +Polonia,wielkopolskie,średzki,gm. Zaniemyśl,,2341 +Polonia,wielkopolskie,śremski,gm. Brodnica,,2342 +Polonia,wielkopolskie,śremski,gm. Dolsk,,2343 +Polonia,wielkopolskie,śremski,gm. Książ Wielkopolski,,2344 +Polonia,wielkopolskie,śremski,gm. Śrem,,2345 +Polonia,wielkopolskie,turecki,m. Turek,,2346 +Polonia,wielkopolskie,turecki,gm. Brudzew,,2347 +Polonia,wielkopolskie,turecki,gm. Dobra,,2348 +Polonia,wielkopolskie,turecki,gm. Kawęczyn,,2349 +Polonia,wielkopolskie,turecki,gm. Malanów,,2350 +Polonia,wielkopolskie,turecki,gm. Przykona,,2351 +Polonia,wielkopolskie,turecki,gm. Tuliszków,,2352 +Polonia,wielkopolskie,turecki,gm. Turek,,2353 +Polonia,wielkopolskie,turecki,gm. Władysławów,,2354 +Polonia,wielkopolskie,wągrowiecki,m. Wągrowiec,,2355 +Polonia,wielkopolskie,wągrowiecki,gm. Damasławek,,2356 +Polonia,wielkopolskie,wągrowiecki,gm. Gołańcz,,2357 +Polonia,wielkopolskie,wągrowiecki,gm. Mieścisko,,2358 +Polonia,wielkopolskie,wągrowiecki,gm. Skoki,,2359 +Polonia,wielkopolskie,wągrowiecki,gm. Wapno,,2360 +Polonia,wielkopolskie,wągrowiecki,gm. Wągrowiec,,2361 +Polonia,wielkopolskie,wolsztyński,gm. Przemęt,,2362 +Polonia,wielkopolskie,wolsztyński,gm. Siedlec,,2363 +Polonia,wielkopolskie,wolsztyński,gm. Wolsztyn,,2364 +Polonia,wielkopolskie,wrzesiński,gm. Kołaczkowo,,2365 +Polonia,wielkopolskie,wrzesiński,gm. Miłosław,,2366 +Polonia,wielkopolskie,wrzesiński,gm. Nekla,,2367 +Polonia,wielkopolskie,wrzesiński,gm. Pyzdry,,2368 +Polonia,wielkopolskie,wrzesiński,gm. Września,,2369 +Polonia,wielkopolskie,złotowski,m. Złotów,,2370 +Polonia,wielkopolskie,złotowski,gm. Jastrowie,,2371 +Polonia,wielkopolskie,złotowski,gm. Krajenka,,2372 +Polonia,wielkopolskie,złotowski,gm. Lipka,,2373 +Polonia,wielkopolskie,złotowski,gm. Okonek,,2374 +Polonia,wielkopolskie,złotowski,gm. Tarnówka,,2375 +Polonia,wielkopolskie,złotowski,gm. Zakrzewo,,2376 +Polonia,wielkopolskie,złotowski,gm. Złotów,,2377 +Polonia,wielkopolskie,Kalisz,m. Kalisz,,2378 +Polonia,wielkopolskie,Konin,m. Konin,,2379 +Polonia,wielkopolskie,Leszno,m. Leszno,,2380 +Polonia,wielkopolskie,Poznań,m. Poznań,,2381 +Polonia,zachodniopomorskie,białogardzki,m. Białogard,,2382 +Polonia,zachodniopomorskie,białogardzki,gm. Białogard,,2383 +Polonia,zachodniopomorskie,białogardzki,gm. Karlino,,2384 +Polonia,zachodniopomorskie,białogardzki,gm. Tychowo,,2385 +Polonia,zachodniopomorskie,choszczeński,gm. Bierzwnik,,2386 +Polonia,zachodniopomorskie,choszczeński,gm. Choszczno,,2387 +Polonia,zachodniopomorskie,choszczeński,gm. Drawno,,2388 +Polonia,zachodniopomorskie,choszczeński,gm. Krzęcin,,2389 +Polonia,zachodniopomorskie,choszczeński,gm. Pełczyce,,2390 +Polonia,zachodniopomorskie,choszczeński,gm. Recz,,2391 +Polonia,zachodniopomorskie,drawski,gm. Czaplinek,,2392 +Polonia,zachodniopomorskie,drawski,gm. Drawsko Pomorskie,,2393 +Polonia,zachodniopomorskie,drawski,gm. Kalisz Pomorski,,2394 +Polonia,zachodniopomorskie,drawski,gm. Wierzchowo,,2395 +Polonia,zachodniopomorskie,drawski,gm. Złocieniec,,2396 +Polonia,zachodniopomorskie,goleniowski,gm. Goleniów,,2397 +Polonia,zachodniopomorskie,goleniowski,gm. Maszewo,,2398 +Polonia,zachodniopomorskie,goleniowski,gm. Nowogard,,2399 +Polonia,zachodniopomorskie,goleniowski,gm. Osina,,2400 +Polonia,zachodniopomorskie,goleniowski,gm. Przybiernów,,2401 +Polonia,zachodniopomorskie,goleniowski,gm. Stepnica,,2402 +Polonia,zachodniopomorskie,gryficki,gm. Brojce,,2403 +Polonia,zachodniopomorskie,gryficki,gm. Gryfice,,2404 +Polonia,zachodniopomorskie,gryficki,gm. Karnice,,2405 +Polonia,zachodniopomorskie,gryficki,gm. Płoty,,2406 +Polonia,zachodniopomorskie,gryficki,gm. Rewal,,2407 +Polonia,zachodniopomorskie,gryficki,gm. Trzebiatów,,2408 +Polonia,zachodniopomorskie,gryfiński,gm. Banie,,2409 +Polonia,zachodniopomorskie,gryfiński,gm. Cedynia,,2410 +Polonia,zachodniopomorskie,gryfiński,gm. Chojna,,2411 +Polonia,zachodniopomorskie,gryfiński,gm. Gryfino,,2412 +Polonia,zachodniopomorskie,gryfiński,gm. Mieszkowice,,2413 +Polonia,zachodniopomorskie,gryfiński,gm. Moryń,,2414 +Polonia,zachodniopomorskie,gryfiński,gm. Stare Czarnowo,,2415 +Polonia,zachodniopomorskie,gryfiński,gm. Trzcińsko-Zdrój,,2416 +Polonia,zachodniopomorskie,gryfiński,gm. Widuchowa,,2417 +Polonia,zachodniopomorskie,kamieński,gm. Dziwnów,,2418 +Polonia,zachodniopomorskie,kamieński,gm. Golczewo,,2419 +Polonia,zachodniopomorskie,kamieński,gm. Kamień Pomorski,,2420 +Polonia,zachodniopomorskie,kamieński,gm. Międzyzdroje,,2421 +Polonia,zachodniopomorskie,kamieński,gm. Świerzno,,2422 +Polonia,zachodniopomorskie,kamieński,gm. Wolin,,2423 +Polonia,zachodniopomorskie,kołobrzeski,m. Kołobrzeg,,2424 +Polonia,zachodniopomorskie,kołobrzeski,gm. Dygowo,,2425 +Polonia,zachodniopomorskie,kołobrzeski,gm. Gościno,,2426 +Polonia,zachodniopomorskie,kołobrzeski,gm. Kołobrzeg,,2427 +Polonia,zachodniopomorskie,kołobrzeski,gm. Rymań,,2428 +Polonia,zachodniopomorskie,kołobrzeski,gm. Siemyśl,,2429 +Polonia,zachodniopomorskie,kołobrzeski,gm. Ustronie Morskie,,2430 +Polonia,zachodniopomorskie,koszaliński,gm. Będzino,,2431 +Polonia,zachodniopomorskie,koszaliński,gm. Biesiekierz,,2432 +Polonia,zachodniopomorskie,koszaliński,gm. Bobolice,,2433 +Polonia,zachodniopomorskie,koszaliński,gm. Manowo,,2434 +Polonia,zachodniopomorskie,koszaliński,gm. Mielno,,2435 +Polonia,zachodniopomorskie,koszaliński,gm. Polanów,,2436 +Polonia,zachodniopomorskie,koszaliński,gm. Sianów,,2437 +Polonia,zachodniopomorskie,koszaliński,gm. Świeszyno,,2438 +Polonia,zachodniopomorskie,myśliborski,gm. Barlinek,,2439 +Polonia,zachodniopomorskie,myśliborski,gm. Boleszkowice,,2440 +Polonia,zachodniopomorskie,myśliborski,gm. Dębno,,2441 +Polonia,zachodniopomorskie,myśliborski,gm. Myślibórz,,2442 +Polonia,zachodniopomorskie,myśliborski,gm. Nowogródek Pomorski,,2443 +Polonia,zachodniopomorskie,policki,gm. Dobra (Szczecińska),,2444 +Polonia,zachodniopomorskie,policki,gm. Kołbaskowo,,2445 +Polonia,zachodniopomorskie,policki,gm. Nowe Warpno,,2446 +Polonia,zachodniopomorskie,policki,gm. Police,,2447 +Polonia,zachodniopomorskie,pyrzycki,gm. Bielice,,2448 +Polonia,zachodniopomorskie,pyrzycki,gm. Kozielice,,2449 +Polonia,zachodniopomorskie,pyrzycki,gm. Lipiany,,2450 +Polonia,zachodniopomorskie,pyrzycki,gm. Przelewice,,2451 +Polonia,zachodniopomorskie,pyrzycki,gm. Pyrzyce,,2452 +Polonia,zachodniopomorskie,pyrzycki,gm. Warnice,,2453 +Polonia,zachodniopomorskie,sławieński,m. Darłowo,,2454 +Polonia,zachodniopomorskie,sławieński,m. Sławno,,2455 +Polonia,zachodniopomorskie,sławieński,gm. Darłowo,,2456 +Polonia,zachodniopomorskie,sławieński,gm. Malechowo,,2457 +Polonia,zachodniopomorskie,sławieński,gm. Postomino,,2458 +Polonia,zachodniopomorskie,sławieński,gm. Sławno,,2459 +Polonia,zachodniopomorskie,stargardzki,m. Stargard,,2460 +Polonia,zachodniopomorskie,stargardzki,gm. Chociwel,,2461 +Polonia,zachodniopomorskie,stargardzki,gm. Dobrzany,,2462 +Polonia,zachodniopomorskie,stargardzki,gm. Dolice,,2463 +Polonia,zachodniopomorskie,stargardzki,gm. Ińsko,,2464 +Polonia,zachodniopomorskie,stargardzki,gm. Kobylanka,,2465 +Polonia,zachodniopomorskie,stargardzki,gm. Marianowo,,2466 +Polonia,zachodniopomorskie,stargardzki,gm. Stara Dąbrowa,,2467 +Polonia,zachodniopomorskie,stargardzki,gm. Stargard,,2468 +Polonia,zachodniopomorskie,stargardzki,gm. Suchań,,2469 +Polonia,zachodniopomorskie,szczecinecki,m. Szczecinek,,2470 +Polonia,zachodniopomorskie,szczecinecki,gm. Barwice,,2471 +Polonia,zachodniopomorskie,szczecinecki,gm. Biały Bór,,2472 +Polonia,zachodniopomorskie,szczecinecki,gm. Borne Sulinowo,,2473 +Polonia,zachodniopomorskie,szczecinecki,gm. Grzmiąca,,2474 +Polonia,zachodniopomorskie,szczecinecki,gm. Szczecinek,,2475 +Polonia,zachodniopomorskie,świdwiński,m. Świdwin,,2476 +Polonia,zachodniopomorskie,świdwiński,gm. Brzeżno,,2477 +Polonia,zachodniopomorskie,świdwiński,gm. Połczyn-Zdrój,,2478 +Polonia,zachodniopomorskie,świdwiński,gm. Rąbino,,2479 +Polonia,zachodniopomorskie,świdwiński,gm. Sławoborze,,2480 +Polonia,zachodniopomorskie,świdwiński,gm. Świdwin,,2481 +Polonia,zachodniopomorskie,wałecki,m. Wałcz,,2482 +Polonia,zachodniopomorskie,wałecki,gm. Człopa,,2483 +Polonia,zachodniopomorskie,wałecki,gm. Mirosławiec,,2484 +Polonia,zachodniopomorskie,wałecki,gm. Tuczno,,2485 +Polonia,zachodniopomorskie,wałecki,gm. Wałcz,,2486 +Polonia,zachodniopomorskie,łobeski,gm. Dobra,,2487 +Polonia,zachodniopomorskie,łobeski,gm. Łobez,,2488 +Polonia,zachodniopomorskie,łobeski,gm. Radowo Małe,,2489 +Polonia,zachodniopomorskie,łobeski,gm. Resko,,2490 +Polonia,zachodniopomorskie,łobeski,gm. Węgorzyno,,2491 +Polonia,zachodniopomorskie,Koszalin,m. Koszalin,,2492 +Polonia,zachodniopomorskie,Szczecin,m. Szczecin,,2493 +Polonia,zachodniopomorskie,Świnoujście,m. Świnoujście,,2494 +Diaspora,Albania,,,,2495 +Diaspora,Algieria,,,,2496 +Diaspora,Angola,,,,2497 +Diaspora,Arabia Saudyjska,,,,2498 +Diaspora,Oman,,,,2499 +Diaspora,Argentyna,,,,2500 +Diaspora,Armenia,,,,2501 +Diaspora,Australia,,,,2502 +Diaspora,Austria,,,,2503 +Diaspora,Azerbejdżan,,,,2504 +Diaspora,Belgia,,,,2505 +Diaspora,Białoruś,,,,2506 +Diaspora,Bośnia i Hercegowina,,,,2507 +Diaspora,Brazylia,,,,2508 +Diaspora,Bułgaria,,,,2509 +Diaspora,Chile,,,,2510 +Diaspora,Chiny,,,,2511 +Diaspora,Chorwacja,,,,2512 +Diaspora,Cypr,,,,2513 +Diaspora,Czarnogóra,,,,2514 +Diaspora,Czechy,,,,2515 +Diaspora,Dania,,,,2516 +Diaspora,Egipt,,,,2517 +Diaspora,Estonia,,,,2518 +Diaspora,Etiopia,,,,2519 +Diaspora,Filipiny,,,,2520 +Diaspora,Finlandia,,,,2521 +Diaspora,Francja,,,,2522 +Diaspora,Grecja,,,,2523 +Diaspora,Gruzja,,,,2524 +Diaspora,Hiszpania,,,,2525 +Diaspora,Indie,,,,2526 +Diaspora,Indonezja,,,,2527 +Diaspora,Irak,,,,2528 +Diaspora,Iran,,,,2529 +Diaspora,Irlandia,,,,2530 +Diaspora,Islandia,,,,2531 +Diaspora,Japonia,,,,2532 +Diaspora,Jordania,,,,2533 +Diaspora,Kanada,,,,2534 +Diaspora,Katar,,,,2535 +Diaspora,Kazachstan,,,,2536 +Diaspora,Kenia,,,,2537 +Diaspora,Kolumbia,,,,2538 +Diaspora,Korea Południowa,,,,2539 +Diaspora,Kosowo,,,,2540 +Diaspora,Kuba,,,,2541 +Diaspora,Kuwejt,,,,2542 +Diaspora,Liban,,,,2543 +Diaspora,Litwa,,,,2544 +Diaspora,Luksemburg,,,,2545 +Diaspora,Łotwa,,,,2546 +Diaspora,Macedonia Północna,,,,2547 +Diaspora,Malezja,,,,2548 +Diaspora,Malta,,,,2549 +Diaspora,Maroko,,,,2550 +Diaspora,Meksyk,,,,2551 +Diaspora,Mołdawia,,,,2552 +Diaspora,Mongolia,,,,2553 +Diaspora,Holandia,,,,2554 +Diaspora,Niemcy,,,,2555 +Diaspora,Nigeria,,,,2556 +Diaspora,Norwegia,,,,2557 +Diaspora,Nowa Zelandia,,,,2558 +Diaspora,Pakistan,,,,2559 +Diaspora,Panama,,,,2560 +Diaspora,Peru,,,,2561 +Diaspora,Portugalia,,,,2562 +Diaspora,Południowa Afryka,,,,2563 +Diaspora,Rosja,,,,2564 +Diaspora,Rumunia,,,,2565 +Diaspora,Senegal,,,,2566 +Diaspora,Serbia,,,,2567 +Diaspora,Singapur,,,,2568 +Diaspora,Słowacja,,,,2569 +Diaspora,Słowenia,,,,2570 +Diaspora,Stany Zjednoczone,,,,2571 +Diaspora,Szwajcaria,,,,2572 +Diaspora,Szwecja,,,,2573 +Diaspora,Tajlandia,,,,2574 +Diaspora,Miasto Tajpej,,,,2575 +Diaspora,Tanzania,,,,2576 +Diaspora,Tunezja,,,,2577 +Diaspora,Turcja,,,,2578 +Diaspora,Uzbekistan,,,,2579 +Diaspora,Wenezuela,,,,2580 +Diaspora,Węgry,,,,2581 +Diaspora,Wielka Brytania,,,,2582 +Diaspora,Wietnam,,,,2583 +Diaspora,Włochy,,,,2584 +Diaspora,Zjednoczone Emiraty Arabskie,,,,2585 +statki,Dar Młodzieży,,,,2586 +statki,Baltica,,,,2587 +statki,Fryderyk Chopin,,,,2588 +statki,Kontradmirał Xawery CZERNICKI,,,,2589 +statki,BALTIC BETA,,,,2590 +statki,LOTOS PETROBALTIC,,,,2591 +statki,PETROBALTIC,,,,2592 +statki,PETRO GIANT,,,,2593 diff --git a/web/src/components/LocationsFilters/LocationsFilters.tsx b/web/src/components/LocationsFilters/LocationsFilters.tsx new file mode 100644 index 000000000..f97963b8d --- /dev/null +++ b/web/src/components/LocationsFilters/LocationsFilters.tsx @@ -0,0 +1,187 @@ +import { useSetPrevSearch } from '@/common/prev-search-store'; +import type { FunctionComponent } from '@/common/types'; +import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; +import { useCurrentElectionRoundStore } from '@/context/election-round.store'; +import { useLocationsLevels } from '@/hooks/locations-levels'; +import { useNavigate, useSearch } from '@tanstack/react-router'; +import { useCallback, useMemo } from 'react'; + +export function LocationsFilters(): FunctionComponent { + const navigate = useNavigate(); + + const search: any = useSearch({ + strict: false, + }); + + const currentElectionRoundId = useCurrentElectionRoundStore(s => s.currentElectionRoundId); + const { data } = useLocationsLevels(currentElectionRoundId); + + const selectedLevel1Node = useMemo( + () => data?.[1]?.find((node) => node.name === search.level1Filter), + [data, search.level1Filter] + ); + + const selectedLevel2Node = useMemo( + () => data?.[2]?.find((node) => node.name === search.level2Filter), + [data, search.level2Filter] + ); + + const selectedLevel3Node = useMemo( + () => data?.[3]?.find((node) => node.name === search.level3Filter), + [data, search.level3Filter] + ); + + const selectedLevel4Node = useMemo( + () => data?.[4]?.find((node) => node.name === search.level4Filter), + [data, search.level4Filter] + ); + + const filteredLevel2Nodes = useMemo( + () => data?.[2]?.filter((node) => node.parentId === selectedLevel1Node?.id), + [data, selectedLevel1Node?.id] + ); + + const filteredLevel3Nodes = useMemo( + () => data?.[3]?.filter((node) => node.parentId === selectedLevel2Node?.id), + [data, selectedLevel2Node?.id] + ); + + const filteredLevel4Nodes = useMemo( + () => data?.[4]?.filter((node) => node.parentId === selectedLevel3Node?.id), + [data, selectedLevel3Node?.id] + ); + + const filteredLevel5Nodes = useMemo( + () => data?.[5]?.filter((node) => node.parentId === selectedLevel4Node?.id), + [data, selectedLevel4Node?.id] + ); + + const setPrevSearch = useSetPrevSearch(); + + const navigateHandler = useCallback( + (search: Record) => { + void navigate({ + search: (prev) => { + const newSearch: Record = { ...prev, ...search }; + setPrevSearch(newSearch); + return newSearch; + }, + }); + }, + [navigate, setPrevSearch] + ); + + return ( + <> + + + + + + + + + + + ); +} diff --git a/web/src/components/layout/Breadcrumbs/BackButton.tsx b/web/src/components/layout/Breadcrumbs/BackButton.tsx index 029ec104f..41bf29035 100644 --- a/web/src/components/layout/Breadcrumbs/BackButton.tsx +++ b/web/src/components/layout/Breadcrumbs/BackButton.tsx @@ -1,29 +1,32 @@ import { usePrevSearch } from '@/common/prev-search-store'; import type { FunctionComponent } from '@/common/types'; import { Link, useRouter } from '@tanstack/react-router'; +import { FC } from 'react'; + +export const BackButtonIcon: FC = () => { + return ( + + + + ); +}; const BackButton = (): FunctionComponent => { const { latestLocation } = useRouter(); const prevSearch = usePrevSearch(); const links = latestLocation.pathname.split('/').filter((crumb: string) => crumb !== ''); + if (links.length <= 1) return <>; + return ( - <> - {links.length > 1 ? ( - - - - - - ) : ( - '' - )} - + + + ); }; diff --git a/web/src/components/ui/badge.tsx b/web/src/components/ui/badge.tsx index 8484f6dcf..eaab177ba 100644 --- a/web/src/components/ui/badge.tsx +++ b/web/src/components/ui/badge.tsx @@ -1,8 +1,8 @@ -import { cva, type VariantProps } from 'class-variance-authority'; -import type * as React from 'react'; import type { FunctionComponent } from '@/common/types'; import { cn } from '@/lib/utils'; import { XMarkIcon } from '@heroicons/react/24/outline'; +import { cva, type VariantProps } from 'class-variance-authority'; +import type * as React from 'react'; const badgeVariants = cva( 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', @@ -10,10 +10,11 @@ const badgeVariants = cva( variants: { variant: { default: 'border-transparent bg-primary text-primary-foreground', - secondary: 'border border-input bg-background hover:bg-purple-50 text-purple-900 border-purple-900 hover:text-accent-foreground', + secondary: + 'border border-input bg-background hover:bg-purple-50 text-purple-900 border-purple-900 hover:text-accent-foreground', destructive: 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80', outline: - 'border border-input bg-purple-100 hover:bg-purple-50 text-purple-900 border-purple-900 hover:text-accent-foreground', + 'border border-input bg-purple-100 hover:bg-purple-50 text-purple-900 border-purple-900 hover:text-accent-foreground', }, }, defaultVariants: { @@ -37,11 +38,11 @@ function FilterBadge({ label, onClear }: FilterBadgeProps): FunctionComponent { return ( {label} - ); } -export { Badge, FilterBadge, badgeVariants }; +export { Badge, badgeVariants, FilterBadge }; diff --git a/web/src/components/ui/tag-selector.tsx b/web/src/components/ui/tag-selector.tsx index c65e07302..37e6c48ca 100644 --- a/web/src/components/ui/tag-selector.tsx +++ b/web/src/components/ui/tag-selector.tsx @@ -1,32 +1,12 @@ -import { cva, type VariantProps } from "class-variance-authority"; -import { - ChevronDown, - XIcon -} from "lucide-react"; -import * as React from "react"; +import { cn, getTagColor } from '@/lib/utils'; +import { Combobox, Popover } from '@headlessui/react'; +import { ChevronDown, Search, XIcon } from 'lucide-react'; +import { FC, useEffect, useRef, useState } from 'react'; +import { Badge } from './badge'; +import { Input } from './input'; +import { Separator } from './separator'; -import { Badge } from "@/components/ui/badge"; -import { Button } from "@/components/ui/button"; -import { - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList, - CommandSeparator, -} from "@/components/ui/command"; -import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover"; -import { Separator } from "@/components/ui/separator"; -import { cn, getTagColor } from "@/lib/utils"; - - -interface TagsSelectFormFieldProps - extends React.ButtonHTMLAttributes { +interface TagsSelectFormFieldProps extends React.ButtonHTMLAttributes { asChild?: boolean; options: string[]; defaultValue?: string[]; @@ -36,79 +16,56 @@ interface TagsSelectFormFieldProps onValueChange: (value: string[]) => void; } -const TagsSelectFormField = React.forwardRef< - HTMLButtonElement, - TagsSelectFormFieldProps ->( - ( - { - className, - asChild = false, - options, - defaultValue, - onValueChange, - disabled, - placeholder, - ...props - }, - ref - ) => { - const [selectedValues, setSelectedValues] = React.useState( - defaultValue || [] - ); - const selectedValuesSet = React.useRef(new Set(selectedValues)); - const [isPopoverOpen, setIsPopoverOpen] = React.useState(false); - const [search, setSearch] = React.useState('') +const TagsSelectFormField: FC = (props) => { + const { options, defaultValue, placeholder, onValueChange } = props; + const [selectedValues, setSelectedValues] = useState(defaultValue || []); + const [query, setQuery] = useState(''); + const searchRef = useRef(null); + const hasSelectedValues = selectedValues.length > 0; + + useEffect(() => { + const valuesSet = new Set(selectedValues); + onValueChange(Array.from(valuesSet)); + }, [selectedValues]); - React.useEffect(() => { - setSelectedValues(defaultValue || []); - selectedValuesSet.current = new Set(defaultValue); - }, [defaultValue]); + const handleInputKeyDown = (event: any) => { + if (event.key !== 'Enter') return; + setQuery(''); + }; + const toggleOption = (value: string) => { + const currentTag = selectedValues.find((t) => t.toLocaleLowerCase() === value.trim().toLocaleLowerCase()); - const handleInputKeyDown = (event: any) => { - if (event.key === "Enter") { - if(search){ - toggleOption(search) - } - } - }; + if (currentTag) setSelectedValues(selectedValues.filter((v) => v !== value.trim())); + else setSelectedValues([...selectedValues, value.trim()]); + }; - const toggleOption = (value: string) => { - const currentTag = selectedValues.find(t => t.toLocaleLowerCase() === value.trim().toLocaleLowerCase()); + const filteredOptions = + query === '' + ? options + : options.filter((option) => { + return option.toLowerCase().includes(query.toLowerCase()); + }); - if (currentTag) { - selectedValuesSet.current.delete(currentTag); - setSelectedValues(selectedValues.filter((v) => v !== value.trim())); - } else { - selectedValuesSet.current.add(value.trim()); - setSelectedValues([...selectedValues, value.trim()]); - } - - onValueChange(Array.from(selectedValuesSet.current)); - }; + const comboboxClasses = cn( + "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground data-[focus]:bg-accent data-[focus]:text-accent-foreground data-[disabled='true']:pointer-events-none data-[disabled='true']:opacity-50 cursor-pointer" + ); - return ( - - - - - setIsPopoverOpen(false)} - > - - - - {/* Press enter to create this tag. */} - - {options.map((option) => { - return ( - toggleOption(option)} - style={{ - pointerEvents: "auto", - opacity: 1, + +
+ {hasSelectedValues && ( + <> + { + setSelectedValues([]); + onValueChange([]); + event.stopPropagation(); }} - className="cursor-pointer" - > - {option} - - ); - })} - - - -
- {selectedValues.length > 0 && ( - <> - { - setSelectedValues([]); - selectedValuesSet.current.clear(); - onValueChange([]); - }} - style={{ - pointerEvents: "auto", - opacity: 1, - }} - className="flex-1 justify-center cursor-pointer" - > - Clear - - - - )} - - setIsPopoverOpen(false)} - style={{ - pointerEvents: "auto", - opacity: 1, - }} - className="flex-1 justify-center cursor-pointer" - > - Close - -
-
- - - - - ); - } -); + /> + + + )} + + + +
+ + + +
+ + + setQuery(event.target.value)} + onKeyDown={handleInputKeyDown} + /> +
+ + + {query.length > 0 && ( + + Create "{query}" + + )} -TagsSelectFormField.displayName = "TagsSelectFormField"; + {filteredOptions.map((option) => ( + + {option} + + ))} + +
+ + )} +
+ + ); +}; export default TagsSelectFormField; diff --git a/web/src/features/election-event/components/Dashboard/Dashboard.tsx b/web/src/features/election-event/components/Dashboard/Dashboard.tsx index 7ee591256..cbcaf2806 100644 --- a/web/src/features/election-event/components/Dashboard/Dashboard.tsx +++ b/web/src/features/election-event/components/Dashboard/Dashboard.tsx @@ -2,13 +2,15 @@ import Layout from '@/components/layout/Layout'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { useCurrentElectionRoundStore } from '@/context/election-round.store'; import FormsDashboard from '@/features/forms/components/Dashboard/Dashboard'; +import LocationsDashboard from '@/features/locations/components/Dashboard/Dashboard'; import PollingStationsDashboard from '@/features/polling-stations/components/Dashboard/Dashboard'; +import { cn } from '@/lib/utils'; import { getRouteApi } from '@tanstack/react-router'; import { ReactElement, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { useElectionRoundDetails } from '../../hooks/election-event-hooks'; import ElectionEventDetails from '../ElectionEventDetails/ElectionEventDetails'; import ObserversGuides from '../ObserversGuides/ObserversGuides'; -import { useTranslation } from 'react-i18next'; const routeApi = getRouteApi('/election-event/$tab'); @@ -16,7 +18,8 @@ export default function ElectionEventDashboard(): ReactElement { const { t } = useTranslation(); const { tab } = routeApi.useParams(); const [currentTab, setCurrentTab] = useState(tab); - const currentElectionRoundId = useCurrentElectionRoundStore(s => s.currentElectionRoundId); + const currentElectionRoundId = useCurrentElectionRoundStore((s) => s.currentElectionRoundId); + const isMonitoringNgoForCitizenReporting = useCurrentElectionRoundStore((s) => s.isMonitoringNgoForCitizenReporting); const navigate = routeApi.useNavigate(); @@ -33,17 +36,34 @@ export default function ElectionEventDashboard(): ReactElement { return ( } backButton={<>}> - + {t('electionEvent.eventDetails.tabTitle')} {t('electionEvent.pollingStations.tabTitle')} {t('electionEvent.observerGuides.tabTitle')} {t('electionEvent.observerForms.tabTitle')} + {t('electionEvent.locations.tabTitle')} - - - - + + + + + + + + + + + + + {isMonitoringNgoForCitizenReporting && ( + + + + )} ); diff --git a/web/src/features/election-event/components/ElectionEventDetails/ElectionEventDetails.tsx b/web/src/features/election-event/components/ElectionEventDetails/ElectionEventDetails.tsx index 88b3c7606..8bd464553 100644 --- a/web/src/features/election-event/components/ElectionEventDetails/ElectionEventDetails.tsx +++ b/web/src/features/election-event/components/ElectionEventDetails/ElectionEventDetails.tsx @@ -13,7 +13,7 @@ export default function ElectionEventDetails() { const { data: electionEvent } = useElectionRoundDetails(currentElectionRoundId); return ( - +
{t('electionEvent.eventDetails.cardTitle')} diff --git a/web/src/features/filtering/components/ActiveFilters.tsx b/web/src/features/filtering/components/ActiveFilters.tsx new file mode 100644 index 000000000..753772c1f --- /dev/null +++ b/web/src/features/filtering/components/ActiveFilters.tsx @@ -0,0 +1,69 @@ +import { FilterBadge } from '@/components/ui/badge'; +import { useNavigate } from '@tanstack/react-router'; +import { FC, useCallback } from 'react'; +import { FILTER_KEY, FILTER_LABEL } from '../filtering-enums'; + +interface ActiveFilterProps { + filterId: string; + value: string; + isArray?: boolean; +} + +type SearchParams = { + [key: string]: any; +}; + +const HIDDEN_FILTERS = [FILTER_KEY.PageSize, FILTER_KEY.PageNumber]; +const FILTER_LABELS = new Map([ + [FILTER_KEY.MonitoringObserverStatus, FILTER_LABEL.MonitoringObserverStatus], + [FILTER_KEY.MonitoringObserverTags, FILTER_LABEL.MonitoringObserverTags], +]); + +const ActiveFilter: FC = ({ filterId, value, isArray }) => { + const label = FILTER_LABELS.get(filterId) ?? filterId; + + const navigate = useNavigate(); + const onClearFilter = useCallback( + (filter: string, value?: string) => () => { + if (!isArray) { + return navigate({ search: (prev) => ({ ...prev, [filter]: undefined }) }); + } + return navigate({ + search: (prev: SearchParams) => ({ + ...prev, + [filter]: prev[filter]?.filter((item: string) => item !== value), // Remove the value from the array + }), + }); + }, + [navigate] + ); + return ; +}; + +interface ActiveFiltersProps { + queryParams: any; +} + +export const ActiveFilters: FC = ({ queryParams }) => { + return ( +
+ {Object.keys(queryParams).map((filterId) => { + let key = ''; + const value = queryParams[filterId]; + const isArray = Array.isArray(value); + + if (HIDDEN_FILTERS.includes(filterId)) return; + + if (!isArray) { + key = `active-filter-${filterId}`; + return ; + } + return value.map((item) => { + key = `active-filter-${filterId}-${item}`; + + return ; + }); + })} +
+ ); +}; diff --git a/web/src/features/filtering/components/FilteringContainer.tsx b/web/src/features/filtering/components/FilteringContainer.tsx new file mode 100644 index 000000000..d6487c581 --- /dev/null +++ b/web/src/features/filtering/components/FilteringContainer.tsx @@ -0,0 +1,21 @@ +import { Button } from '@/components/ui/button'; +import { FC, ReactNode } from 'react'; +import { useFilteringContainer } from '../hooks/useFilteringContainer'; +import { ActiveFilters } from './ActiveFilters'; + +interface FilteringContainerProps { + children?: ReactNode; +} + +export const FilteringContainer: FC = ({ children }) => { + const { filteringIsActive, queryParams, resetFilters } = useFilteringContainer(); + return ( +
+ {children} + + {filteringIsActive && } +
+ ); +}; diff --git a/web/src/features/filtering/components/SelectFilter.tsx b/web/src/features/filtering/components/SelectFilter.tsx new file mode 100644 index 000000000..ad7d0119d --- /dev/null +++ b/web/src/features/filtering/components/SelectFilter.tsx @@ -0,0 +1,39 @@ +import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; +import { FC } from 'react'; + +export type SelectFilterOption = { + value: string; + label: string; +}; + +interface SelectFilterProps { + placeholder: string; + value: string; + options: SelectFilterOption[]; + onChange: (value: string) => void; +} + +export const SelectFilter: FC = (props) => { + const { placeholder, value, options, onChange } = props; + + const selectId = crypto.randomUUID(); + + return ( + + ); +}; diff --git a/web/src/features/filtering/filtering-enums.ts b/web/src/features/filtering/filtering-enums.ts new file mode 100644 index 000000000..ce834be93 --- /dev/null +++ b/web/src/features/filtering/filtering-enums.ts @@ -0,0 +1,11 @@ +export const enum FILTER_KEY { + PageSize = 'pageSize', + PageNumber = 'pageNumber', + MonitoringObserverStatus = 'monitoringObserverStatus', + MonitoringObserverTags = 'tags', +} + +export const enum FILTER_LABEL { + MonitoringObserverStatus = 'Observer status', + MonitoringObserverTags = 'Tags', +} diff --git a/web/src/features/filtering/hooks/useFilteringContainer.ts b/web/src/features/filtering/hooks/useFilteringContainer.ts new file mode 100644 index 000000000..bd7c5fbfa --- /dev/null +++ b/web/src/features/filtering/hooks/useFilteringContainer.ts @@ -0,0 +1,34 @@ +import { useSetPrevSearch } from '@/common/prev-search-store'; +import { useNavigate, useSearch } from '@tanstack/react-router'; +import { useCallback } from 'react'; + +export function useFilteringContainer() { + const navigate = useNavigate(); + const queryParams = useSearch({ strict: false }); + const setPrevSearch = useSetPrevSearch(); + const filteringIsActive = Object.keys(queryParams).some((key) => key !== 'tab' && key !== 'viewBy'); + + const navigateHandler = useCallback( + (search: Record) => { + void navigate({ + // @ts-ignore + search: (prev) => { + const newSearch: Record = { + ...prev, + ...search, + }; + setPrevSearch(newSearch); + return newSearch; + }, + }); + }, + [navigate, setPrevSearch] + ); + + const resetFilters = () => { + navigate({}); + setPrevSearch({}); + }; + + return { queryParams, filteringIsActive, navigate, navigateHandler, resetFilters }; +} diff --git a/web/src/features/locations/components/Dashboard/Dashboard.tsx b/web/src/features/locations/components/Dashboard/Dashboard.tsx new file mode 100644 index 000000000..5efc7ec1c --- /dev/null +++ b/web/src/features/locations/components/Dashboard/Dashboard.tsx @@ -0,0 +1,157 @@ +import { QueryParamsDataTable } from '@/components/ui/DataTable/QueryParamsDataTable'; + +import { LocationsFilters } from '@/components/LocationsFilters/LocationsFilters'; +import { FilterBadge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { Separator } from '@/components/ui/separator'; +import { useCurrentElectionRoundStore } from '@/context/election-round.store'; +import { ExportDataButton } from '@/features/responses/components/ExportDataButton/ExportDataButton'; +import { ExportedDataType } from '@/features/responses/models/data-export'; +import i18n from '@/i18n'; +import { FunnelIcon } from '@heroicons/react/24/outline'; +import { useNavigate, useSearch } from '@tanstack/react-router'; +import { useDebounce } from '@uidotdev/usehooks'; +import { useCallback, useMemo, useState, type ReactElement } from 'react'; +import { locationColDefs } from './table-cols'; +import { useLocations } from '../../hooks/use-locations'; + +export default function LocationsDashboard(): ReactElement { + const navigate = useNavigate(); + + const search = useSearch({ strict: false }) as { + level1Filter?: string; + level2Filter?: string; + level3Filter?: string; + level4Filter?: string; + level5Filter?: string; + }; + + const [isFiltering, setFiltering] = useState( + Object.keys(search).some( + (k) => + k === 'level1Filter' || + k === 'level2Filter' || + k === 'level3Filter' || + k === 'level4Filter' || + k === 'level5Filter' + ) + ); + + const changeIsFiltering = () => { + setFiltering((prev) => { + return !prev; + }); + }; + + const onClearFilter = useCallback( + (filter: string | string[]) => () => { + const filters = Array.isArray(filter) + ? Object.fromEntries(filter.map((key) => [key, undefined])) + : { [filter]: undefined }; + void navigate({ search: (prev) => ({ ...prev, ...filters }) }); + }, + [navigate] + ); + + const debouncedSearch = useDebounce(search, 300); + const currentElectionRoundId = useCurrentElectionRoundStore((s) => s.currentElectionRoundId); + + const queryParams = useMemo(() => { + const params = [ + ['level1Filter', debouncedSearch.level1Filter], + ['level2Filter', debouncedSearch.level2Filter], + ['level3Filter', debouncedSearch.level3Filter], + ['level4Filter', debouncedSearch.level4Filter], + ['level5Filter', debouncedSearch.level5Filter], + ].filter(([_, value]) => value); + + return Object.fromEntries(params); + }, [debouncedSearch]); + + return ( + + +
+ {i18n.t('electionEvent.locations.cardTitle')} + +
+ +
+
+ +
+ <> + + +
+ + {isFiltering && ( +
+ + + +
+ )} + {Object.entries(search).length > 0 && ( +
+ {search.level1Filter && ( + + )} + + {search.level2Filter && ( + + )} + + {search.level3Filter && ( + + )} + + {search.level4Filter && ( + + )} + + {search.level5Filter && ( + + )} +
+ )} +
+ + useLocations(currentElectionRoundId, params)} + queryParams={queryParams} + /> + +
+ ); +} diff --git a/web/src/features/locations/components/Dashboard/table-cols.tsx b/web/src/features/locations/components/Dashboard/table-cols.tsx new file mode 100644 index 000000000..ea658843c --- /dev/null +++ b/web/src/features/locations/components/Dashboard/table-cols.tsx @@ -0,0 +1,62 @@ +import { ColumnDef } from '@tanstack/react-table'; +import { Location } from '../../models/Location'; + +import TableTagList from '@/components/table-tag-list/TableTagList'; +import { DataTableColumnHeader } from '@/components/ui/DataTable/DataTableColumnHeader'; +import i18n from '@/i18n'; + +export const locationColDefs: ColumnDef[] = [ + { + header: ({ column }) => ( + + ), + accessorKey: 'level1', + enableSorting: true, + enableGlobalFilter: true, + }, + { + header: ({ column }) => ( + + ), + accessorKey: 'level2', + enableSorting: true, + enableGlobalFilter: true, + }, + { + header: ({ column }) => ( + + ), + accessorKey: 'level3', + enableSorting: true, + enableGlobalFilter: true, + }, + { + header: ({ column }) => ( + + ), + accessorKey: 'level4', + enableSorting: true, + enableGlobalFilter: true, + }, + { + header: ({ column }) => ( + + ), + accessorKey: 'level5', + enableSorting: true, + enableGlobalFilter: true, + }, + { + header: ({ column }) => ( + + ), + accessorKey: 'tags', + enableSorting: false, + enableGlobalFilter: true, + cell: ({ + row: { + original: { tags }, + }, + }) => `${key} : ${value}`)} />, + }, +]; diff --git a/web/src/features/locations/hooks/use-locations.ts b/web/src/features/locations/hooks/use-locations.ts new file mode 100644 index 000000000..cbcdce38d --- /dev/null +++ b/web/src/features/locations/hooks/use-locations.ts @@ -0,0 +1,37 @@ +import { authApi } from "@/common/auth-api"; +import { DataTableParameters, PageResponse } from "@/common/types"; +import { buildURLSearchParams } from "@/lib/utils"; +import { useQuery, UseQueryResult } from "@tanstack/react-query"; +import { Location } from '../models/Location'; + + +type LocationsResult = UseQueryResult, Error>; + +export function useLocations(electionRoundId: string, queryParams: DataTableParameters): LocationsResult { + return useQuery({ + queryKey: ['locations', electionRoundId, queryParams], + queryFn: async () => { + const params = { + ...queryParams.otherParams, + PageNumber: String(queryParams.pageNumber), + PageSize: String(queryParams.pageSize), + SortColumnName: queryParams.sortColumnName, + SortOrder: queryParams.sortOrder, + }; + const searchParams = buildURLSearchParams(params); + + const response = await authApi.get>(`/election-rounds/${electionRoundId}/locations:list`, + { + params: searchParams, + } + ); + + if (response.status !== 200) { + throw new Error('Failed to fetch locations'); + } + + return response.data; + }, + enabled: !!electionRoundId + }); +} diff --git a/web/src/features/locations/models/Location.ts b/web/src/features/locations/models/Location.ts new file mode 100644 index 000000000..f4173d62a --- /dev/null +++ b/web/src/features/locations/models/Location.ts @@ -0,0 +1,10 @@ +export interface Location { + id: string; + level1: string; + level2: string; + level3: string; + level4: string; + level5: string; + displayOrder: number; + tags: Record; +} \ No newline at end of file diff --git a/web/src/features/monitoring-observers/components/EditMonitoringObserver/EditMonitoringObserver.tsx b/web/src/features/monitoring-observers/components/EditMonitoringObserver/EditMonitoringObserver.tsx index 47f99eca6..7e95eaf47 100644 --- a/web/src/features/monitoring-observers/components/EditMonitoringObserver/EditMonitoringObserver.tsx +++ b/web/src/features/monitoring-observers/components/EditMonitoringObserver/EditMonitoringObserver.tsx @@ -18,15 +18,18 @@ import { useNavigate, useRouter } from '@tanstack/react-router'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; import { UpdateMonitoringObserverRequest } from '../../models/monitoring-observer'; +import { MonitorObserverBackButton } from '../MonitoringObserverBackButton'; export default function EditObserver() { const navigate = useNavigate(); const router = useRouter(); const queryClient = useQueryClient(); - const currentElectionRoundId = useCurrentElectionRoundStore(s => s.currentElectionRoundId); + const currentElectionRoundId = useCurrentElectionRoundStore((s) => s.currentElectionRoundId); const { monitoringObserverId } = Route.useParams(); - const monitoringObserverQuery = useSuspenseQuery(monitoringObserverDetailsQueryOptions(currentElectionRoundId, monitoringObserverId)); + const monitoringObserverQuery = useSuspenseQuery( + monitoringObserverDetailsQueryOptions(currentElectionRoundId, monitoringObserverId) + ); const monitoringObserver = monitoringObserverQuery.data; const { data: availableTags } = useMonitoringObserversTags(currentElectionRoundId); @@ -61,11 +64,17 @@ export default function EditObserver() { phoneNumber: values.phoneNumber, }; - editMutation.mutate({electionRoundId: currentElectionRoundId, request}); + editMutation.mutate({ electionRoundId: currentElectionRoundId, request }); } const editMutation = useMutation({ - mutationFn: ({ electionRoundId, request }: { electionRoundId: string; request: UpdateMonitoringObserverRequest }) => { + mutationFn: ({ + electionRoundId, + request, + }: { + electionRoundId: string; + request: UpdateMonitoringObserverRequest; + }) => { return authApi.post( `/election-rounds/${electionRoundId}/monitoring-observers/${monitoringObserver.id}`, request @@ -81,12 +90,17 @@ export default function EditObserver() { queryClient.invalidateQueries({ queryKey: ['monitoring-observers'] }); queryClient.invalidateQueries({ queryKey: ['tags'] }); - navigate({ to: '/monitoring-observers/view/$monitoringObserverId/$tab', params: { monitoringObserverId: monitoringObserver.id, tab: 'details' } }) + navigate({ + to: '/monitoring-observers/view/$monitoringObserverId/$tab', + params: { monitoringObserverId: monitoringObserver.id, tab: 'details' }, + }); }, }); return ( - + }>
@@ -148,10 +162,10 @@ export default function EditObserver() { Tags !field.value.includes(tag)) ?? []} + options={availableTags?.filter((tag) => !field.value.includes(tag)) ?? []} defaultValue={field.value} onValueChange={field.onChange} - placeholder="Observer tags" + placeholder='Observer tags' /> @@ -190,7 +204,12 @@ export default function EditObserver() { - resendInvitationsMutation.mutate({ electionRoundId: currentElectionRoundId, monitoringObserverId })} - {...confirmResendInvitesDialog.dialogProps} /> + onConfirm={() => + resendInvitationsMutation.mutate({ electionRoundId: currentElectionRoundId, monitoringObserverId }) + } + {...confirmResendInvitesDialog.dialogProps} + />
@@ -356,66 +362,7 @@ function MonitoringObserversList() { - {isFiltering ? ( -
- - - -
- Tags -
-
- - {tags?.map((tag) => ( - toggleTagsFilter(tag)} - key={tag}> - {tag} - - ))} - -
- -
- {statusFilter && ( - handleStatusFilter('')} - className='rounded-full cursor-pointer py-1 px-4 bg-purple-100 text-sm text-purple-900 font-medium flex items-center gap-2'> - Observer status: {statusFilter} - - - )} - - {tagsFilter.map((tag) => ( - toggleTagsFilter(tag)} - className='rounded-full cursor-pointer py-1 px-4 bg-purple-100 text-sm text-purple-900 font-medium flex items-center gap-2'> - Tags: {tag} - - - ))} -
-
- ) : ( - '' - )} + {isFiltering && }
{ + const { queryParams, navigateHandler } = useFilteringContainer(); + + const onStatusChange = (value: string) => { + navigateHandler({ [FILTER_KEY.MonitoringObserverStatus]: value }); + }; + + return ( + + ); +}; diff --git a/web/src/features/monitoring-observers/filtering/MonitoringObserverTagsSelect.tsx b/web/src/features/monitoring-observers/filtering/MonitoringObserverTagsSelect.tsx new file mode 100644 index 000000000..730de3494 --- /dev/null +++ b/web/src/features/monitoring-observers/filtering/MonitoringObserverTagsSelect.tsx @@ -0,0 +1,46 @@ +import { + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu'; +import { useCurrentElectionRoundStore } from '@/context/election-round.store'; +import { FILTER_KEY } from '@/features/filtering/filtering-enums'; +import { useFilteringContainer } from '@/features/filtering/hooks/useFilteringContainer'; +import { useMonitoringObserversTags } from '@/hooks/tags-queries'; +import { FC } from 'react'; + +export const MonitoringObserverTagsSelect: FC = () => { + const currentElectionRoundId = useCurrentElectionRoundStore((s) => s.currentElectionRoundId); + const { data: tags } = useMonitoringObserversTags(currentElectionRoundId); + const { queryParams, navigateHandler } = useFilteringContainer(); + const currentTags = (queryParams as any)?.[FILTER_KEY.MonitoringObserverTags] ?? []; + + const toggleTagsFilter = (tag: string) => { + if (!currentTags.includes(tag)) return navigateHandler({ tags: [...currentTags, tag] }); + + const filteredTags = currentTags.filter((tagText: string) => tagText !== tag); + + return navigateHandler({ [FILTER_KEY.MonitoringObserverTags]: filteredTags }); + }; + + return ( + + +
+ Observer tags +
+
+ + {tags?.map((tag) => ( + toggleTagsFilter(tag)} + key={tag}> + {tag} + + ))} + +
+ ); +}; diff --git a/web/src/features/monitoring-observers/filtering/MonitoringObserversListFilters.tsx b/web/src/features/monitoring-observers/filtering/MonitoringObserversListFilters.tsx new file mode 100644 index 000000000..463d4b46f --- /dev/null +++ b/web/src/features/monitoring-observers/filtering/MonitoringObserversListFilters.tsx @@ -0,0 +1,13 @@ +import { FilteringContainer } from '@/features/filtering/components/FilteringContainer'; +import { MonitoringObserverStatusSelect } from '@/features/monitoring-observers/filtering/MonitoringObserverStatusSelect'; +import { MonitoringObserverTagsSelect } from '@/features/monitoring-observers/filtering/MonitoringObserverTagsSelect'; +import { FC } from 'react'; + +export const MonitoringObserversListFilters: FC = () => { + return ( + + + + + ); +}; diff --git a/web/src/features/responses/components/ResetFiltersButton/ResetFiltersButton.tsx b/web/src/features/responses/components/ResetFiltersButton/ResetFiltersButton.tsx index 5c5ccf4f5..d886db5e7 100644 --- a/web/src/features/responses/components/ResetFiltersButton/ResetFiltersButton.tsx +++ b/web/src/features/responses/components/ResetFiltersButton/ResetFiltersButton.tsx @@ -1,7 +1,7 @@ -import { useNavigate } from '@tanstack/react-router'; +import { useSetPrevSearch } from '@/common/prev-search-store'; import type { FunctionComponent } from '@/common/types'; import { Button } from '@/components/ui/button'; -import { useSetPrevSearch } from '@/common/prev-search-store'; +import { useNavigate } from '@tanstack/react-router'; type ResetFiltersButtonProps = { disabled: boolean; diff --git a/web/src/features/responses/models/data-export.ts b/web/src/features/responses/models/data-export.ts index 6276f5593..4964c0306 100644 --- a/web/src/features/responses/models/data-export.ts +++ b/web/src/features/responses/models/data-export.ts @@ -14,6 +14,7 @@ export enum ExportedDataType { QuickReports = "QuickReports", CitizenReports = "CitizenReports", PollingStations = "PollingStations", + Locations = "Locations", } export interface ExportedDataDetails { diff --git a/web/src/hooks/locations-levels.ts b/web/src/hooks/locations-levels.ts new file mode 100644 index 000000000..c895927c0 --- /dev/null +++ b/web/src/hooks/locations-levels.ts @@ -0,0 +1,25 @@ +import { authApi } from '@/common/auth-api'; +import type { LevelNode } from '@/common/types'; +import { type UseQueryResult, useQuery } from '@tanstack/react-query'; + +type LocationsLevelsResponse = { nodes: LevelNode[] }; + +type UseLocationsLevelsResult = UseQueryResult, Error>; + +export function useLocationsLevels(electionRoundId: string): UseLocationsLevelsResult { + return useQuery({ + queryKey: ['locations', 'levels'], + queryFn: async () => { + + const response = await authApi.get( + `/election-rounds/${electionRoundId}/locations:fetchLevels` + ); + + return response.data.nodes.reduce>( + (group, node) => ({ ...group, [node.depth]: [...(group[node.depth] ?? []), node] }), + {} + ); + }, + enabled: !!electionRoundId + }); +} diff --git a/web/src/locales/en.json b/web/src/locales/en.json index 969c35995..291e26288 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -196,6 +196,19 @@ }, "createDialogTitle": "Create form", "resetFilters": "Reset filters" + }, + "locations": { + "tabTitle": "Locations", + "cardTitle": "Locations", + "headers": { + "tags": "Location tags", + "level1": "Level 1", + "level2": "Level 2", + "level3": "Level 3", + "level4": "Level 4", + "level5": "Level 5" + }, + "resetFilters": "Reset filters" } }, "pagination": { @@ -208,4 +221,4 @@ "goToLastPage": "Go to last page" } } -} \ No newline at end of file +} diff --git a/web/src/routes/election-event/$tab.tsx b/web/src/routes/election-event/$tab.tsx index 9008ee6ef..355941b01 100644 --- a/web/src/routes/election-event/$tab.tsx +++ b/web/src/routes/election-event/$tab.tsx @@ -7,6 +7,7 @@ const coerceTabSlug = (slug: string) => { if (slug?.toLowerCase()?.trim() === 'polling-stations') return 'polling-stations'; if (slug?.toLowerCase()?.trim() === 'observer-guides') return 'observer-guides'; if (slug?.toLowerCase()?.trim() === 'observer-forms') return 'observer-forms'; + if (slug?.toLowerCase()?.trim() === 'locations') return 'locations'; return 'event-details' };