From 670d04e3388a80a4043c196160fd8a005050ec61 Mon Sep 17 00:00:00 2001 From: snemeckayova <514641@mail.muni.cz> Date: Tue, 5 Nov 2024 17:32:13 +0100 Subject: [PATCH] Implement event related interfaces --- .../EventCommentService.cs | 146 ++++++++++++++++++ .../EventParticipantService.cs | 128 +++++++++++++++ .../Services/EventService/EventService.cs | 123 +++++++++++++++ 3 files changed, 397 insertions(+) create mode 100644 BusinessLayer/Services/EventCommentService/EventCommentService.cs create mode 100644 BusinessLayer/Services/EventParticipantService/EventParticipantService.cs create mode 100644 BusinessLayer/Services/EventService/EventService.cs diff --git a/BusinessLayer/Services/EventCommentService/EventCommentService.cs b/BusinessLayer/Services/EventCommentService/EventCommentService.cs new file mode 100644 index 0000000..942bbfe --- /dev/null +++ b/BusinessLayer/Services/EventCommentService/EventCommentService.cs @@ -0,0 +1,146 @@ +using BusinessLayer.DTOs.EventComment; +using BusinessLayer.Utils.Filters; +using BusinessLayer.Utils.Pagination; +using DAL.Data; +using DAL.Models; +using Mapster; +using Microsoft.EntityFrameworkCore; + +namespace BusinessLayer.Services.EventCommentService +{ + public class EventCommentService : BaseService, IEventCommentService + { + private readonly RestaurantDBContext _dbContext; + + public EventCommentService(RestaurantDBContext dbContext) : base(dbContext) + { + _dbContext = dbContext; + } + + public async Task<EventCommentDTO?> CreateCommentAsync(EventCommentCreateDTO data, bool save = true) + { + var poster = await _dbContext.Users.FindAsync(data.PosterId); + if (poster is null || poster.DeletedAt is not null) + { + return null; + } + + var eventEntity = await _dbContext.Events.FindAsync(data.EventId); + if (eventEntity is null || eventEntity.DeletedAt is not null) + { + return null; + } + + if (data.ParentCommentId is not null) + { + var parentComment = await _dbContext.EventComments.FindAsync(data.ParentCommentId); + if (parentComment is null || parentComment.DeletedAt is not null) + { + return null; + } + } + + var comment = data.Adapt<EventComment>(); + comment.Id = Guid.NewGuid(); + comment.CreatedAt = DateTime.UtcNow; + comment.UpdatedAt = DateTime.UtcNow; + + await _dbContext.EventComments.AddAsync(comment); + await SaveAsync(save); + return comment.Adapt<EventCommentDTO?>(); + } + + public async Task<bool> DeleteCommentAsync(Guid id, bool save = true) + { + var comment = await _dbContext.EventComments.FindAsync(id); + if (comment is null || comment.DeletedAt is not null) + { + return false; + } + + comment.UpdatedAt = DateTime.UtcNow; + comment.DeletedAt = DateTime.UtcNow; + + _dbContext.EventComments.Update(comment); + await SaveAsync(save); + return true; + } + + public async Task<bool> DoesCommentExistAsync(params Guid[] ids) + { + return await _dbContext.EventComments.AnyAsync(c => ids.Contains(c.Id) && c.DeletedAt == null); + } + + public async Task<EventCommentDTO?> GetByIdAsync(Guid id, bool includeUser = true, bool includeEvent = false, bool includeChildren = false) + { + var query = BuildQuery(includeUser, includeEvent, includeChildren); + + var result = await query.SingleOrDefaultAsync(c => c.Id == id && c.DeletedAt == null); + if (result == null + || (includeUser && result.Poster.DeletedAt != null) + || (includeEvent && result.Event.DeletedAt != null)) + { + return null; + } + + return result.Adapt<EventCommentDTO?>(); + } + + public async Task<List<EventCommentDTO>> GetCommentsAsync(EventCommentFilter filter, + int limit = 0, + int offset = 0, + Guid[]? ids = null, + bool includeUser = true, + bool includeEvent = false, + bool includeChildren = false) + { + IQueryable<EventComment> query = BuildQuery(includeUser, includeEvent, includeChildren); + + return await query + .Where(filter.ComposeFilterFunction(ids)) + .OrderByDescending(c => c.CreatedAt) + .ApplyPagination(limit, offset) + .Select(c => c.Adapt<EventCommentDTO>()) + .ToListAsync(); + } + + public async Task<EventCommentDTO?> UpdateCommentAsync(Guid id, EventCommentUpdateDTO data, bool save = true) + { + var comment = await _dbContext.EventComments.FindAsync(id); + if (comment is null || comment.DeletedAt is not null) + { + return null; + } + + comment.Content = data.Content ?? comment.Content; + comment.UpdatedAt = DateTime.UtcNow; + + _dbContext.EventComments.Update(comment); + await SaveAsync(save); + + return comment.Adapt<EventCommentDTO?>(); + } + + private IQueryable<EventComment> BuildQuery(bool includeUser, bool includeEvent, bool includeChildren) + { + IQueryable<EventComment> query = _dbContext.EventComments; + + if (includeUser) + { + query = query.Include(c => c.Poster); + } + + if (includeEvent) + { + query = query.Include(c => c.Event); + } + + if (includeChildren) + { + query = query.Include(c => c.ChildComments); + } + + return query; + } + } +} diff --git a/BusinessLayer/Services/EventParticipantService/EventParticipantService.cs b/BusinessLayer/Services/EventParticipantService/EventParticipantService.cs new file mode 100644 index 0000000..8488849 --- /dev/null +++ b/BusinessLayer/Services/EventParticipantService/EventParticipantService.cs @@ -0,0 +1,128 @@ +using BusinessLayer.DTOs.EventParticipant; +using BusinessLayer.Utils.Filters; +using DAL.Data; +using DAL.Models; +using Mapster; +using Microsoft.EntityFrameworkCore; + +namespace BusinessLayer.Services.EventParticipantService +{ + public class EventParticipantService : BaseService, IEventParticipantService + { + private readonly RestaurantDBContext _dbContext; + + public EventParticipantService(RestaurantDBContext dbContext) : base(dbContext) + { + _dbContext = dbContext; + } + + public async Task<EventParticipantDTO?> GetParticipantByIdAsync(Guid userId, Guid eventId) + { + var participant = await _dbContext.EventParticipants + .Include(p => p.User) + .Include(p => p.Event) + .FirstOrDefaultAsync(p => p.UserId == userId && p.EventId == eventId && p.DeletedAt == null); + + return participant?.Adapt<EventParticipantDTO>(); + } + + public async Task<List<EventParticipantDTO>> GetParticipantsAsync(EventParticipantFilter filter, int limit = 0, int offset = 0) + { + var query = _dbContext.EventParticipants + .Include(p => p.User) + .Include(p => p.Event) + .Where(filter.ComposeFilterFunction()) + .OrderBy(p => p.User!.Name) + .Skip(offset); + + var participants = limit > 0 + ? await query.Take(limit).ToListAsync() + : await query.ToListAsync(); + + return participants.Adapt<List<EventParticipantDTO>>(); + } + + public async Task<EventParticipantDTO?> CreateParticipantAsync(EventParticipantCreateDTO data, bool save = true) + { + var user = await _dbContext.Users.FindAsync(data.UserId); + if (user == null || user.DeletedAt != null) + { + return null; + } + + var eventEntity = await _dbContext.Events.FindAsync(data.EventId); + if (eventEntity == null || eventEntity.DeletedAt != null) + { + return null; + } + + var oldParticipant = await _dbContext.EventParticipants + .FirstOrDefaultAsync(p => p.UserId == data.UserId && p.EventId == data.EventId); + + if (oldParticipant != null) + { + if (oldParticipant.DeletedAt != null) + { + oldParticipant.CreatedAt = DateTime.UtcNow; + oldParticipant.UpdatedAt = DateTime.UtcNow; + oldParticipant.DeletedAt = null; + oldParticipant.Attendance = data.Attendance; + + _dbContext.EventParticipants.Update(oldParticipant); + await SaveAsync(save); + return oldParticipant.Adapt<EventParticipantDTO>(); + } + + return null; + } + + var participant = new EventParticipant + { + UserId = data.UserId, + EventId = data.EventId, + Attendance = data.Attendance, + CreatedAt = DateTime.UtcNow, + UpdatedAt = DateTime.UtcNow + }; + + await _dbContext.EventParticipants.AddAsync(participant); + await SaveAsync(save); + + return participant.Adapt<EventParticipantDTO>(); + } + + public async Task<EventParticipantDTO?> UpdateParticipantAsync(Guid participantId, EventParticipantUpdateDTO data, bool save = true) + { + var participant = await _dbContext.EventParticipants.FindAsync(participantId); + if (participant == null || participant.DeletedAt != null) + { + return null; + } + + participant.Attendance = data.Attendance; + participant.UpdatedAt = DateTime.UtcNow; + + _dbContext.EventParticipants.Update(participant); + await SaveAsync(save); + + return participant.Adapt<EventParticipantDTO>(); + } + + public async Task<bool> DeleteParticipantAsync(Guid participantId, bool save = true) + { + var participant = await _dbContext.EventParticipants.FindAsync(participantId); + if (participant == null || participant.DeletedAt != null) + { + return false; + } + + participant.UpdatedAt = DateTime.UtcNow; + participant.DeletedAt = DateTime.UtcNow; + + _dbContext.EventParticipants.Update(participant); + await SaveAsync(save); + + return true; + } + } +} diff --git a/BusinessLayer/Services/EventService/EventService.cs b/BusinessLayer/Services/EventService/EventService.cs new file mode 100644 index 0000000..09ade8c --- /dev/null +++ b/BusinessLayer/Services/EventService/EventService.cs @@ -0,0 +1,123 @@ +using BusinessLayer.DTOs.Event; +using BusinessLayer.Utils.Filters; +using DAL.Data; +using DAL.Models; +using Mapster; +using Microsoft.EntityFrameworkCore; + +namespace BusinessLayer.Services.EventService +{ + public class EventService : BaseService, IEventService + { + private readonly RestaurantDBContext _dbContext; + + public EventService(RestaurantDBContext dbContext) : base(dbContext) + { + _dbContext = dbContext; + } + + public async Task<EventDTO?> GetEventByIdAsync(Guid eventId, bool includeRestaurant = true) + { + var query = _dbContext.Events.AsQueryable(); + if (includeRestaurant) + { + query = query.Include(e => e.Restaurant); + } + + var eventEntity = await query + .SingleOrDefaultAsync(e => e.Id == eventId && e.DeletedAt == null); + + return eventEntity?.Adapt<EventDTO>(); + } + + public async Task<List<EventDTO>> GetEventsAsync(EventFilter filter, int limit = 0, int offset = 0) + { + var eventsQuery = _dbContext.Events + .Include(e => e.Restaurant) + .Where(filter.ComposeFilterFunction()) + .OrderBy(e => e.Date) + .Skip(offset); + + var events = limit > 0 + ? await eventsQuery.Take(limit).ToListAsync() + : await eventsQuery.ToListAsync(); + + return events.Adapt<List<EventDTO>>(); + } + + public async Task<EventDTO?> CreateEventAsync(EventCreateDTO data, bool save = true) + { + var user = await _dbContext.Users.FindAsync(data.CreatorId); + if (user == null || user.DeletedAt != null) + { + return null; + } + + var restaurant = await _dbContext.Restaurants.FindAsync(data.RestaurantId); + if (restaurant == null || restaurant.DeletedAt != null) + { + return null; + } + + var eventEntity = new Event + { + Id = Guid.NewGuid(), + Title = data.Title, + RestaurantId = data.RestaurantId, + Content = data.Content, + Date = data.Date, + CreatedAt = DateTime.UtcNow, + UpdatedAt = DateTime.UtcNow, + }; + + var creator = new EventParticipant + { + EventId = eventEntity.Id, + UserId = data.CreatorId, + Attendance = DAL.Enums.ParticipantType.Creator + }; + + await _dbContext.Events.AddAsync(eventEntity); + await _dbContext.EventParticipants.AddAsync(creator); + await SaveAsync(save); + + return eventEntity.Adapt<EventDTO>(); + } + + public async Task<EventDTO?> UpdateEventAsync(Guid eventId, EventUpdateDTO data, bool save = true) + { + var eventEntity = await _dbContext.Events.FindAsync(eventId); + if (eventEntity == null || eventEntity.DeletedAt != null) + { + return null; + } + + eventEntity.Title = data.Title ?? eventEntity.Title; + eventEntity.Content = data.Content ?? eventEntity.Content; + eventEntity.Date = data.Date ?? eventEntity.Date; + eventEntity.UpdatedAt = DateTime.UtcNow; + + _dbContext.Events.Update(eventEntity); + await SaveAsync(save); + + return eventEntity.Adapt<EventDTO>(); + } + + public async Task<bool> DeleteEventAsync(Guid eventId, bool save = true) + { + var eventEntity = await _dbContext.Events.FindAsync(eventId); + if (eventEntity == null || eventEntity.DeletedAt != null) + { + return false; + } + + eventEntity.UpdatedAt = DateTime.UtcNow; + eventEntity.DeletedAt = DateTime.UtcNow; + + _dbContext.Events.Update(eventEntity); + await SaveAsync(save); + + return true; + } + } +} -- GitLab