From 78bc6d9714e80dcdf2e7416bb187f5c0059914a1 Mon Sep 17 00:00:00 2001 From: Eric <36512385+PhucNghi176@users.noreply.github.com> Date: Thu, 17 Oct 2024 02:34:50 +0700 Subject: [PATCH] Add slot generation for semester command and API endpoint Created/modified `GenerateSlotForSemesterCommandHandler.cs` to handle slot generation for a semester, interacting with `Slot`, `Semester`, and `User` repositories and using a unit of work for saving changes. Added `GenerateSlotForSemester` command to the static `Command` class in `Command.cs`. Updated `SlotApi.cs` with a new endpoint for generating slots for a semester, including a refactored `CreateSlot` method and a new `GenerateSlotForSemester` method. --- .../GenerateSlotForSemesterCommandHandler.cs | 56 +++++++++++++++++++ .../Services/Slots/Command.cs | 4 +- .../APIs/Slots/SlotApi.cs | 14 +++-- 3 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 MBS_COMMAND.Application/UserCases/Commands/Slots/GenerateSlotForSemesterCommandHandler.cs diff --git a/MBS_COMMAND.Application/UserCases/Commands/Slots/GenerateSlotForSemesterCommandHandler.cs b/MBS_COMMAND.Application/UserCases/Commands/Slots/GenerateSlotForSemesterCommandHandler.cs new file mode 100644 index 0000000..62e79fc --- /dev/null +++ b/MBS_COMMAND.Application/UserCases/Commands/Slots/GenerateSlotForSemesterCommandHandler.cs @@ -0,0 +1,56 @@ +using MBS_COMMAND.Contract.Abstractions.Messages; +using MBS_COMMAND.Contract.Abstractions.Shared; +using MBS_COMMAND.Contract.Services.Slots; +using MBS_COMMAND.Domain.Abstractions; +using MBS_COMMAND.Domain.Abstractions.Repositories; +using MBS_COMMAND.Domain.Entities; +using static MBS_COMMAND.Contract.Abstractions.Shared.Result; + +namespace MBS_COMMAND.Application.UserCases.Commands.Slots; + +public class GenerateSlotForSemesterCommandHandler( + IRepositoryBase slotRepository, + IRepositoryBase semesterRepository, + IRepositoryBase userRepository, + IUnitOfWork unitOfWork) + : ICommandHandler +{ + public async Task Handle(Command.GenerateSlotForSemester request, CancellationToken cancellationToken) + { + var currentSemester = await semesterRepository.FindSingleAsync(x => x.IsActive, cancellationToken); + if (currentSemester == null) + return Result.Failure(new Error("404", "No active semester found")); + + var mentors = userRepository.FindAll(x => x.Role == 2); + var newSlots = new List(); + + foreach (var mentor in mentors) + { + var firstWeekSlots = slotRepository.FindAll(x => + x.MentorId == mentor.Id && x.Date >= currentSemester.From && + x.Date <= currentSemester.From.AddDays(6)); + + newSlots.AddRange(GenerateNewSlots(firstWeekSlots, 10)); + } + + slotRepository.AddRange(newSlots); + await unitOfWork.SaveChangesAsync(cancellationToken); + return Success(); + } + + private static IEnumerable GenerateNewSlots(IEnumerable firstWeekSlots, int weeks) + { + return Enumerable.Range(1, weeks) + .SelectMany(i => firstWeekSlots.Select(x => new Slot + { + Id = Guid.NewGuid(), + MentorId = x.MentorId, + StartTime = x.StartTime, + EndTime = x.EndTime, + Date = x.Date.AddDays(7 * i), + Note = x.Note, + IsOnline = x.IsOnline, + Month = (short)x.Date.AddDays(7 * i).Month + })); + } +} \ No newline at end of file diff --git a/MBS_COMMAND.Contract/Services/Slots/Command.cs b/MBS_COMMAND.Contract/Services/Slots/Command.cs index aee33d1..5fe37ac 100644 --- a/MBS_COMMAND.Contract/Services/Slots/Command.cs +++ b/MBS_COMMAND.Contract/Services/Slots/Command.cs @@ -1,6 +1,8 @@ using MBS_COMMAND.Contract.Abstractions.Messages; namespace MBS_COMMAND.Contract.Services.Slots; -public class Command +public static class Command { public record CreateSlot(Guid MentorId, List SlotModels) : ICommand; + + public record GenerateSlotForSemester(): ICommand; } diff --git a/MBS_COMMAND.Presentation/APIs/Slots/SlotApi.cs b/MBS_COMMAND.Presentation/APIs/Slots/SlotApi.cs index f95185e..1b1626a 100644 --- a/MBS_COMMAND.Presentation/APIs/Slots/SlotApi.cs +++ b/MBS_COMMAND.Presentation/APIs/Slots/SlotApi.cs @@ -8,13 +8,17 @@ public void AddRoutes(IEndpointRouteBuilder app) { var gr1 = app.NewVersionedApi("Slots").MapGroup(BaseUrl).HasApiVersion(1); gr1.MapPost(string.Empty, CreateSlot).WithSummary("mm/dd/yyyy"); + gr1.MapGet("generate", GenerateSlotForSemester); } - public static async Task CreateSlot(ISender sender, Command.CreateSlot command) + + private static async Task CreateSlot(ISender sender,[FromBody] Command.CreateSlot command) { var result = await sender.Send(command); - if (result.IsFailure) - return HandlerFailure(result); - - return Results.Ok(result); + return result.IsFailure ? HandlerFailure(result) : Results.Ok(result); + } + private static async Task GenerateSlotForSemester(ISender sender) + { + var result = await sender.Send(new Command.GenerateSlotForSemester()); + return result.IsFailure ? HandlerFailure(result) : Results.Ok(result); } }