diff --git a/BeReadyBackend/BeReadyBackend.csproj b/BeReadyBackend/BeReadyBackend.csproj index 61caa40..90499a8 100644 --- a/BeReadyBackend/BeReadyBackend.csproj +++ b/BeReadyBackend/BeReadyBackend.csproj @@ -27,7 +27,6 @@ - diff --git a/BeReadyBackend/DTO/Groups/CreateGroupDto.cs b/BeReadyBackend/DTO/Groups/CreateGroupDto.cs new file mode 100644 index 0000000..1730c64 --- /dev/null +++ b/BeReadyBackend/DTO/Groups/CreateGroupDto.cs @@ -0,0 +1,10 @@ +namespace BeReadyBackend.DTO.Groups; + +public class CreateGroupDto +{ + public string? Label { get; set; } + public string? Title { get; set; } + public string? Description { get; set; } + public int Duration { get; set; } + public List? UserGroups { get; set; } +} \ No newline at end of file diff --git a/BeReadyBackend/DTO/Groups/CreateUserGroupDto.cs b/BeReadyBackend/DTO/Groups/CreateUserGroupDto.cs new file mode 100644 index 0000000..094826a --- /dev/null +++ b/BeReadyBackend/DTO/Groups/CreateUserGroupDto.cs @@ -0,0 +1,6 @@ +namespace BeReadyBackend.DTO.Groups; + +public class CreateUserGroupDto +{ + public int UserId { get; set; } +} \ No newline at end of file diff --git a/BeReadyBackend/DTO/Groups/GetUserGroupDto.cs b/BeReadyBackend/DTO/Groups/GetUserGroupDto.cs new file mode 100644 index 0000000..61a9705 --- /dev/null +++ b/BeReadyBackend/DTO/Groups/GetUserGroupDto.cs @@ -0,0 +1,9 @@ +namespace BeReadyBackend.DTO.Groups; + +public class GetUserGroupDto +{ + public int Id { get; set; } + public string? Username { get; set; } + public string? Grade { get; set; } + public int Score { get; set; } +} \ No newline at end of file diff --git a/BeReadyBackend/Endpoints/Groups/CreateGroupEndpoint.cs b/BeReadyBackend/Endpoints/Groups/CreateGroupEndpoint.cs new file mode 100644 index 0000000..e77bb6d --- /dev/null +++ b/BeReadyBackend/Endpoints/Groups/CreateGroupEndpoint.cs @@ -0,0 +1,65 @@ +using BeReadyBackend.DTO.Groups; +using BeReadyBackend.Models; +using BeReadyBackend.Repositories; +using BeReadyBackend.Services; +using BeReadyBackend.Specifications.Users; +using FastEndpoints; +using Group = BeReadyBackend.Models.Group; + +namespace BeReadyBackend.Endpoints.Groups; + +public class CreateGroupEndpoint( + UserGroupsRepository userGroupsRepository, + GroupsRepository groupsRepository, + UsersRepository usersRepository, + UserService userService, + AutoMapper.IMapper mapper) : Endpoint +{ + public override void Configure() + { + Post("/Groups/"); + } + + public override async Task HandleAsync(CreateGroupDto req, CancellationToken ct) + { + int userId = userService.GetUserIdFromToken(); + + Group? group = new(); + mapper.Map(req, group); + group.IsFinished = false; + group.CreationDate = DateTime.Now; + group.UserGroups = []; + + await groupsRepository.AddAsync(group, ct); + await groupsRepository.SaveChangesAsync(ct); + + UserGroup userGroup; + foreach (CreateUserGroupDto user in req.UserGroups!) + { + User? userChecking = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(user.UserId), ct); + if (userChecking is null) continue; + userGroup = new UserGroup + { + UserId = user.UserId, + GroupId = group.Id, + Grade = "Member", + Score = 0 + }; + group.UserGroups?.Add(userGroup); + } + + userGroup = new UserGroup + { + UserId = userId, + GroupId = group.Id, + Grade = "Admin", + Score = 0 + }; + group.UserGroups?.Add(userGroup); + + await userGroupsRepository.AddRangeAsync(group.UserGroups!, ct); + await userGroupsRepository.SaveChangesAsync(ct); + + await Send.OkAsync(ct); + } +} \ No newline at end of file diff --git a/BeReadyBackend/Endpoints/Groups/DeleteGroupEndpoint.cs b/BeReadyBackend/Endpoints/Groups/DeleteGroupEndpoint.cs new file mode 100644 index 0000000..941e411 --- /dev/null +++ b/BeReadyBackend/Endpoints/Groups/DeleteGroupEndpoint.cs @@ -0,0 +1,49 @@ +using BeReadyBackend.Models; +using BeReadyBackend.Repositories; +using BeReadyBackend.Services; +using BeReadyBackend.Specifications.Groups; +using BeReadyBackend.Specifications.Users; +using FastEndpoints; +using Group = BeReadyBackend.Models.Group; + +namespace BeReadyBackend.Endpoints.Groups; + +public class GroupDeletedRequest +{ + public int Id { get; set; } +} + +public class DeleteGroupEndpoint(GroupsRepository groupsRepository, UserGroupsRepository userGroupsRepository, UserService userService) : Endpoint +{ + public override void Configure() + { + Delete("/Groups/{@Id}", x => new { x.Id }); + } + + public override async Task HandleAsync(GroupDeletedRequest req, CancellationToken ct) + { + int userId = userService.GetUserIdFromToken(); + Group? group = await groupsRepository.SingleOrDefaultAsync(new GetGroupByIdSpec(req.Id), ct); + + if (group is null) + { + await Send.NotFoundAsync(ct); + return; + } + + bool isAdmin = group.UserGroups?.Any(x => x.UserId == userId && x.Grade == "Admin") ?? false; + + if (!isAdmin) + { + await Send.StringAsync("Vous n'avez pas les droits pour supprimer ce groupe", 400, cancellation: ct); + return; + } + + if (group.UserGroups?.Count > 0) + await userGroupsRepository.DeleteRangeAsync(group.UserGroups, ct); + + await groupsRepository.DeleteAsync(group, ct); + await userGroupsRepository.SaveChangesAsync(ct); + await Send.OkAsync(ct); + } +} \ No newline at end of file diff --git a/BeReadyBackend/Endpoints/Groups/GetAllGroupUsersEndpoint.cs b/BeReadyBackend/Endpoints/Groups/GetAllGroupUsersEndpoint.cs new file mode 100644 index 0000000..0d8c731 --- /dev/null +++ b/BeReadyBackend/Endpoints/Groups/GetAllGroupUsersEndpoint.cs @@ -0,0 +1,28 @@ +using BeReadyBackend.DTO.Groups; +using BeReadyBackend.Repositories; +using BeReadyBackend.Services; +using BeReadyBackend.Specifications.Groups; +using FastEndpoints; + +namespace BeReadyBackend.Endpoints.Groups; + +public class UserGroupRequest +{ + public int Id { get; set; } +} + +public class GetAllGroupUsersEndpoint(UserGroupsRepository userGroupsRepository, UserService userService) : Endpoint> +{ + public override void Configure() + { + Get("/Groups/{@Id}/Users/", x => new { x.Id }); + } + + public override async Task HandleAsync(UserGroupRequest req, CancellationToken ct) + { + int userId = userService.GetUserIdFromToken(); + + List usersGroup = await userGroupsRepository.ProjectToListAsync(new GetUserGroupByIdSpec(req.Id, userId), ct); + await Send.OkAsync(usersGroup, ct); + } +} \ No newline at end of file diff --git a/BeReadyBackend/MappingProfiles/DtoToEntityMappings.cs b/BeReadyBackend/MappingProfiles/DtoToEntityMappings.cs index 0f3ed9a..dcaca0f 100644 --- a/BeReadyBackend/MappingProfiles/DtoToEntityMappings.cs +++ b/BeReadyBackend/MappingProfiles/DtoToEntityMappings.cs @@ -1,5 +1,6 @@ using AutoMapper; using BeReadyBackend.DTO.Achievements; +using BeReadyBackend.DTO.Groups; using BeReadyBackend.DTO.Users; using BeReadyBackend.Models; @@ -14,5 +15,8 @@ public class DtoToEntityMappings : Profile CreateMap(); CreateMap(); CreateMap(); + + CreateMap() + .ForMember(dest => dest.UserGroups, opt => opt.Ignore());; } } \ No newline at end of file diff --git a/BeReadyBackend/MappingProfiles/EntityToDtoMappings.cs b/BeReadyBackend/MappingProfiles/EntityToDtoMappings.cs index 26feab1..5b74d83 100644 --- a/BeReadyBackend/MappingProfiles/EntityToDtoMappings.cs +++ b/BeReadyBackend/MappingProfiles/EntityToDtoMappings.cs @@ -1,8 +1,10 @@ using AutoMapper; using BeReadyBackend.DTO.Achievements; using BeReadyBackend.DTO.Friends; +using BeReadyBackend.DTO.Groups; using BeReadyBackend.DTO.Users; using BeReadyBackend.Models; +using NSwag.Generation.Processors; namespace BeReadyBackend.MappingProfiles; @@ -44,5 +46,10 @@ public class EntityToDtoMappings : Profile CreateMap() .ForMember(dest => dest.Username, opt => opt.MapFrom(src => src.User!.Username)) .ForMember(dest => dest.Score, opt => opt.MapFrom(src => src.User!.Score)); + + CreateMap() + .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.UserId)) + .ForMember(dest => dest.Username, opt => opt.MapFrom(src => src.User!.Username)) + .ForMember(dest => dest.Score, opt => opt.MapFrom(src => src.User!.Score)); } } \ No newline at end of file diff --git a/BeReadyBackend/Specifications/Groups/GetGroupByIdSpec.cs b/BeReadyBackend/Specifications/Groups/GetGroupByIdSpec.cs new file mode 100644 index 0000000..12851ab --- /dev/null +++ b/BeReadyBackend/Specifications/Groups/GetGroupByIdSpec.cs @@ -0,0 +1,14 @@ +using Ardalis.Specification; +using BeReadyBackend.Models; + +namespace BeReadyBackend.Specifications.Groups; + +public class GetGroupByIdSpec : SingleResultSpecification +{ + public GetGroupByIdSpec(int groupId) + { + Query + .Include(x => x.UserGroups) + .Where(x => x.Id == groupId); + } +} \ No newline at end of file diff --git a/BeReadyBackend/Specifications/Groups/GetUserGroupByIdSpec.cs b/BeReadyBackend/Specifications/Groups/GetUserGroupByIdSpec.cs new file mode 100644 index 0000000..f9d9c4d --- /dev/null +++ b/BeReadyBackend/Specifications/Groups/GetUserGroupByIdSpec.cs @@ -0,0 +1,14 @@ +using Ardalis.Specification; +using BeReadyBackend.Models; + +namespace BeReadyBackend.Specifications.Groups; + +public class GetUserGroupByIdSpec : Specification +{ + public GetUserGroupByIdSpec(int groupId, int userId) + { + Query + .Include(x => x.User!) + .Where(x => x.GroupId == groupId && x.Group!.UserGroups!.Any(y => y.UserId == userId)); + } +} \ No newline at end of file