diff --git a/WebApp/DTOs/EventSummaryDto.cs b/WebApp/DTOs/EventSummaryDto.cs index 9c56ab3..09d6ecb 100644 --- a/WebApp/DTOs/EventSummaryDto.cs +++ b/WebApp/DTOs/EventSummaryDto.cs @@ -12,8 +12,8 @@ public record class EventSummaryDto { [StringLength(500)] public string Description { get; set; } [Required] [StringLength(100)] public string Location { get; set; } [Required] public DateTime? EventDate { get; set; } - public ICollection EventSkills { get; set; } - public ICollection EventRegistrations { get; set; } + public ICollection EventSkills { get; set; } + public ICollection EventRegistrations { get; set; } }; diff --git a/WebApp/Endpoints/AuthEndpoints.cs b/WebApp/Endpoints/AuthEndpoints.cs index 7f31c3b..f69a9d2 100644 --- a/WebApp/Endpoints/AuthEndpoints.cs +++ b/WebApp/Endpoints/AuthEndpoints.cs @@ -229,7 +229,7 @@ namespace WebApp.Endpoints .Include(vs => vs.Skill) .Select(vs => new { - skillId = vs.Skill.SkillId, + skillId = vs.Skill!.SkillId, skillName = vs.Skill.Name }) .ToListAsync(); diff --git a/WebApp/Endpoints/EventsEndpoints.cs b/WebApp/Endpoints/EventsEndpoints.cs index 57f8c1f..8067c77 100644 --- a/WebApp/Endpoints/EventsEndpoints.cs +++ b/WebApp/Endpoints/EventsEndpoints.cs @@ -20,27 +20,24 @@ namespace WebApp.Endpoints // GET /events group.MapGet("/", - async (ApplicationDbContext dbContext, HttpContext httpContext) => + async (ApplicationDbContext dbContext, HttpContext httpContext, GeneralUseHelpers guhf) => { - var sort = httpContext.Request.Query["sort"].ToString(); - IOrderedQueryable res; - var r = dbContext.Events - .Include(Eve => Eve.Organisation); + // Sprawdź, czy lista powinna by posortowana rosnąco. Domyślnie: malejąco. + var sort = httpContext.Request.Query["sort"].ToString().ToUpper(); - if (sort is not null && sort.ToUpper() == "ASC") - { - res = r.OrderBy(Eve => Eve.EventId); - } - else - { - res = r.OrderByDescending(Eve => Eve.EventId); - } + // Sprawdź, czy token należy do organizacji, a jeżeli tak, to do której. + Token? token = await guhf.GetTokenFromHTTPContext(httpContext); + Organisation? org = await guhf.GetOrganisationFromToken(token); + + List result = await guhf.BuildSummaryEventsDto( + dbContext, + org, + (sort == "ASC") + ); + + return Results.Ok(result); - return await res - .Select(Eve => Eve.ToEventSummaryDto()) //EventSummaryDto - .AsNoTracking() - .ToListAsync(); }); @@ -64,7 +61,7 @@ namespace WebApp.Endpoints // puste pole. List result = await guhf.BuildDetailedEventsDto( dbContext, - (org is not null && Eve.Organisation == org) + org ); return Results.Ok(result.FirstOrDefault(e => e.EventId == id)); @@ -158,20 +155,14 @@ namespace WebApp.Endpoints { // Uzyskaj organizację z tokenu - var sort = httpContext.Request.Query["sort"].ToString(); + var sort = httpContext.Request.Query["sort"].ToString().ToUpper(); Token? token = await guhf.GetTokenFromHTTPContext(httpContext); Organisation? org = await guhf.GetOrganisationFromToken(token); + List SearchCandidates = await guhf.BuildSummaryEventsDto(dbContext, org, sort == "ASC"); List SearchResults = []; - - List AllEvents = await dbContext.Events.ToListAsync(); - if (sort is null || sort.ToUpper() != "ASC") - { - AllEvents.Reverse(); // aby wyświetlało od najnowszych wydarzeń - } - - foreach(Event e in AllEvents) + foreach(EventSummaryDto e in SearchCandidates) { bool matchFound = true; // Logika wyszukiwania @@ -184,19 +175,19 @@ namespace WebApp.Endpoints if (query.TitleOrDescription is not null) { - var TitleMatch = guhf.SearchString(e.Title, query.TitleOrDescription); + var TitleMatch = guhf.SearchString(e.Title, query.TitleOrDescription); var DescMatch = guhf.SearchString(e.Description, query.TitleOrDescription); if (!TitleMatch && !DescMatch) matchFound = false; } - //Zakres dat do wyszukiwania - if(query.EventDateFrom is not null) + // Zakres dat do wyszukiwania + if (query.EventDateFrom is not null) { if (e.EventDate < query.EventDateFrom) matchFound = false; } - if(query.EventDateTo is not null) + if (query.EventDateTo is not null) { if (e.EventDate > query.EventDateTo) matchFound = false; } @@ -210,19 +201,12 @@ namespace WebApp.Endpoints // Uwaga! Zanim to zrobisz, sprawdź, czy użytkownik // jest twórcą danego wydarzenia! Jeżeli nim nie jest, // wyzeruj EventRegistrations! - if (org is null || e.Organisation != org) + if (org is null || e.OrganisationId != org.OrganisationId) { e.EventRegistrations.Clear(); } - // UWAGA! TO NIE POWINNO TAK DZIAŁAĆ! - // KTOKOLWIEK WIDZIAŁ, KTOKOLWIEK WIE CZEMU Organisation JEST null? - // - // Odpowiedź: Bo pobieramy dane bez .Include(e => e.Organisation), - // co zapobiega masie innych problemów, m.in. rekurencyjnym importom. - e.Organisation = await guhf.GetOrganisationFromId(e.OrganisationId); - - if (matchFound) SearchResults.Add(e.ToEventSummaryDto()); + if (matchFound) SearchResults.Add(e); } return Results.Ok(SearchResults); diff --git a/WebApp/Endpoints/GeneralUseHelperFunctions.cs b/WebApp/Endpoints/GeneralUseHelperFunctions.cs index 7f0a2bf..987aa2b 100644 --- a/WebApp/Endpoints/GeneralUseHelperFunctions.cs +++ b/WebApp/Endpoints/GeneralUseHelperFunctions.cs @@ -36,12 +36,7 @@ public class GeneralUseHelpers User? user = await GetUserFromToken(t); if (user is not null && user.IsOrganisation) { - Organisation? org = await _context.Organisations.FirstOrDefaultAsync(o => o.UserId == t.UserId); - - if (org is null) - { - Console.WriteLine("!!!"); - } + Organisation? org = await _context.Organisations.FirstOrDefaultAsync(o => o.UserId == t!.UserId); return org; } @@ -114,36 +109,26 @@ public class GeneralUseHelpers return words.Any(word => word.Contains(searchTerm, StringComparison.OrdinalIgnoreCase)); } - public async Task> BuildDetailedEventsDto(ApplicationDbContext context, bool includeEventRegistrations = false) + public async Task> BuildDetailedEventsDto( + ApplicationDbContext context, + Organisation? org, + bool sortAscending = false) { // https://khalidabuhakmeh.com/ef-core-and-aspnet-core-cycle-issue-and-solution // Jeśli token należy do organizacji, która utworzyła to wydarzenie, // to zwróć także EventRegistrations. W przeciwnym razie niech będzie to // puste pole. - ICollection ERs = new List(); - if (includeEventRegistrations) - { - ERs = await context - .EventRegistrations - .Select(er => new EventRegistrationDto - { - EventId = er.EventId, - UserId = er.UserId, - UserName = er.User.FirstName + " " + er.User.LastName, - RegisteredAt = er.RegisteredAt - }).ToListAsync(); - } - List result = await context + IQueryable result_iq = context .Events .Select(e => new EventDetailsDto { EventId = e.EventId, OrganisationId = e.OrganisationId, - OrganisationName = e.Organisation.Name, + OrganisationName = e.Organisation!.Name, Title = e.Title, - Description = e.Description, + Description = e.Description ?? "", Location = e.Location, EventDate = e.EventDate, EventSkills = e @@ -151,11 +136,69 @@ public class GeneralUseHelpers .Select(es => new SkillSummaryDto { SkillId = es.SkillId, - SkillName = es.Skill.Name + SkillName = es.Skill!.Name }).ToList(), - EventRegistrations = ERs - }).ToListAsync(); + EventRegistrations = e.Organisation == org ? + e.EventRegistrations + .Select(er => new EventRegistrationDto + { + EventId = er.EventId, + UserId = er.UserId, + UserName = er.User!.FirstName + " " + er.User.LastName, + RegisteredAt = er.RegisteredAt + }).ToList() : null! + }); - return result; + if (sortAscending) result_iq = result_iq.OrderBy(e => e.EventId); + else result_iq = result_iq.OrderByDescending(e => e.EventId); + + + return await result_iq.ToListAsync(); } + + public async Task> BuildSummaryEventsDto( + ApplicationDbContext context, + Organisation? org, + bool sortAscending = false) + { + // https://khalidabuhakmeh.com/ef-core-and-aspnet-core-cycle-issue-and-solution + + // Jeśli token należy do organizacji, która utworzyła to wydarzenie, + // to zwróć także EventRegistrations. W przeciwnym razie niech będzie to + // puste pole. + IQueryable result_iq = context + .Events + .Select(e => new EventSummaryDto + { + EventId = e.EventId, + OrganisationId = e.OrganisationId, + Organisation = e.Organisation!.Name, + Title = e.Title, + Description = e.Description ?? "", + Location = e.Location, + EventDate = e.EventDate, + EventSkills = e + .EventSkills + .Select(es => new SkillSummaryDto + { + SkillId = es.SkillId, + SkillName = es.Skill!.Name + }).ToList(), + EventRegistrations = e.Organisation == org ? + e.EventRegistrations + .Select(er => new EventRegistrationDto + { + EventId = er.EventId, + UserId = er.UserId, + UserName = er.User!.FirstName + " " + er.User.LastName, + RegisteredAt = er.RegisteredAt + }).ToList() : null! + }); + + if (sortAscending) result_iq = result_iq.OrderBy(e => e.EventId); + else result_iq = result_iq.OrderByDescending(e => e.EventId); + + return await result_iq.ToListAsync(); + } + } diff --git a/WebApp/Mapping/EventMapping.cs b/WebApp/Mapping/EventMapping.cs index 52305a3..9ccdf85 100644 --- a/WebApp/Mapping/EventMapping.cs +++ b/WebApp/Mapping/EventMapping.cs @@ -34,16 +34,30 @@ public static class EventMapping public static EventSummaryDto ToEventSummaryDto(this Event myEvent) { + + List ssdto = new List(); + List erdto = new List(); + + foreach (EventSkill es in myEvent.EventSkills) + { + ssdto.Add(es.ToSkillSummaryDto()); + } + + foreach (EventRegistration er in myEvent.EventRegistrations) + { + erdto.Add(er.ToEventRegistrationDto()); + } + return new EventSummaryDto { EventId = myEvent.EventId, Organisation = myEvent.Organisation!.Name, OrganisationId = myEvent.OrganisationId, Title = myEvent.Title, - Description = myEvent.Description, + Description = myEvent.Description ?? "", Location = myEvent.Location, EventDate = myEvent.EventDate, - EventSkills = myEvent.EventSkills, - EventRegistrations = myEvent.EventRegistrations + EventSkills = ssdto, + EventRegistrations = erdto }; } public static EventSummaryNoErDto ToEventSummaryNoErDto(this Event myEvent) @@ -54,7 +68,7 @@ public static class EventMapping myEvent.Organisation!.Name, myEvent.OrganisationId, myEvent.Title, - myEvent.Description, + myEvent.Description ?? "", myEvent.Location, myEvent.EventDate, myEvent.EventSkills @@ -67,7 +81,7 @@ public static class EventMapping return new EventRegistrationDto { EventId = myER.EventId, UserId = myER.UserId, - UserName = myER.User.FirstName + " " + myER.User.LastName, + UserName = myER.User!.FirstName + " " + myER.User!.LastName, RegisteredAt = myER.RegisteredAt }; } @@ -90,9 +104,9 @@ public static class EventMapping return new EventDetailsDto { EventId = myEvent.EventId, OrganisationId = myEvent.OrganisationId, - OrganisationName = myEvent.Organisation.Name, + OrganisationName = myEvent.Organisation!.Name, Title = myEvent.Title, - Description = myEvent.Description, + Description = myEvent.Description ?? "", Location = myEvent.Location, EventDate = myEvent.EventDate, EventSkills = ssdto, diff --git a/WebApp/Mapping/EventRegistrationMapping.cs b/WebApp/Mapping/EventRegistrationMapping.cs deleted file mode 100644 index 5f76622..0000000 --- a/WebApp/Mapping/EventRegistrationMapping.cs +++ /dev/null @@ -1,17 +0,0 @@ -using WebApp.DTOs; -using WebApp.Entities; - -namespace WebApp.Mapping -{ - public static class EventRegistrationMapping - { - public static EventRegistrationDto ToEventRegistrationDto(this EventRegistration er) - { - return new EventRegistrationDto( - er.EventId, - er.UserId, - er.RegisteredAt - ); - } - } -}