117 lines
4.8 KiB
C#
117 lines
4.8 KiB
C#
// EN: Schedules Controller - Shop-wide staff schedule queries.
|
|
// VI: Controller Schedules - Truy vấn lịch làm việc nhân viên theo shop.
|
|
|
|
using Asp.Versioning;
|
|
using BookingService.API.Application.DTOs;
|
|
using BookingService.API.Application.Queries;
|
|
using BookingService.API.Models.Responses;
|
|
using BookingService.Domain.AggregatesModel.StaffAggregate;
|
|
using BookingService.Infrastructure.Repositories;
|
|
using MediatR;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace BookingService.API.Controllers;
|
|
|
|
[ApiController]
|
|
[ApiVersion("1.0")]
|
|
[Route("api/v{version:apiVersion}/schedules")]
|
|
[Produces("application/json")]
|
|
public class SchedulesController : ControllerBase
|
|
{
|
|
private readonly IMediator _mediator;
|
|
private readonly IStaffScheduleRepository _scheduleRepository;
|
|
private readonly ILogger<SchedulesController> _logger;
|
|
|
|
public SchedulesController(IMediator mediator, IStaffScheduleRepository scheduleRepository, ILogger<SchedulesController> logger)
|
|
{
|
|
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
|
|
_scheduleRepository = scheduleRepository ?? throw new ArgumentNullException(nameof(scheduleRepository));
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
}
|
|
|
|
/// <summary>
|
|
/// EN: Get all staff schedules for a shop.
|
|
/// VI: Lấy tất cả lịch làm việc nhân viên cho một shop.
|
|
/// </summary>
|
|
[HttpGet]
|
|
[ProducesResponseType(typeof(ApiResponse<List<StaffScheduleDto>>), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
public async Task<ActionResult<ApiResponse<List<StaffScheduleDto>>>> GetSchedulesByShop(
|
|
[FromQuery] Guid shopId,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (shopId == Guid.Empty)
|
|
return BadRequest(ApiResponse<List<StaffScheduleDto>>.Fail("Shop ID is required"));
|
|
|
|
var query = new GetSchedulesByShopQuery(shopId);
|
|
var result = await _mediator.Send(query, cancellationToken);
|
|
|
|
return Ok(ApiResponse<List<StaffScheduleDto>>.Ok(result));
|
|
}
|
|
|
|
/// <summary>
|
|
/// EN: Create a single schedule entry.
|
|
/// VI: Tạo một entry lịch làm việc.
|
|
/// </summary>
|
|
[HttpPost]
|
|
[ProducesResponseType(typeof(ApiResponse<StaffScheduleDto>), StatusCodes.Status201Created)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
public async Task<ActionResult<ApiResponse<StaffScheduleDto>>> CreateSchedule(
|
|
[FromBody] CreateScheduleRequest request,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (request.ShopId == Guid.Empty || request.StaffId == Guid.Empty)
|
|
return BadRequest(ApiResponse<StaffScheduleDto>.Fail("ShopId and StaffId are required"));
|
|
|
|
if (!TimeOnly.TryParse(request.StartTime, out var startTime) ||
|
|
!TimeOnly.TryParse(request.EndTime, out var endTime))
|
|
return BadRequest(ApiResponse<StaffScheduleDto>.Fail("Invalid time format. Use HH:mm"));
|
|
|
|
var schedule = new StaffSchedule(request.StaffId, request.ShopId, request.DayOfWeek, startTime, endTime);
|
|
_scheduleRepository.Add(schedule);
|
|
await _scheduleRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);
|
|
|
|
_logger.LogInformation("Schedule created: {Id} for staff {StaffId}", schedule.Id, request.StaffId);
|
|
|
|
var dto = new StaffScheduleDto
|
|
{
|
|
Id = schedule.Id,
|
|
StaffId = schedule.StaffId,
|
|
ShopId = schedule.ShopId,
|
|
DayOfWeek = schedule.DayOfWeek,
|
|
StartTime = schedule.StartTime,
|
|
EndTime = schedule.EndTime
|
|
};
|
|
return Created($"/api/v1/schedules/{schedule.Id}", ApiResponse<StaffScheduleDto>.Ok(dto));
|
|
}
|
|
|
|
/// <summary>
|
|
/// EN: Delete a schedule entry by ID.
|
|
/// VI: Xóa một entry lịch làm việc theo ID.
|
|
/// </summary>
|
|
[HttpDelete("{id:guid}")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> DeleteSchedule(Guid id, CancellationToken cancellationToken = default)
|
|
{
|
|
var schedule = await _scheduleRepository.GetByIdAsync(id, cancellationToken);
|
|
if (schedule == null)
|
|
return NotFound(ApiResponse<object>.Fail("Schedule not found"));
|
|
|
|
_scheduleRepository.Remove(schedule);
|
|
await _scheduleRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);
|
|
|
|
_logger.LogInformation("Schedule deleted: {Id}", id);
|
|
return Ok(new { success = true, message = "Schedule deleted" });
|
|
}
|
|
}
|
|
|
|
public record CreateScheduleRequest
|
|
{
|
|
public Guid ShopId { get; init; }
|
|
public Guid StaffId { get; init; }
|
|
public int DayOfWeek { get; init; }
|
|
public string StartTime { get; init; } = "08:00";
|
|
public string EndTime { get; init; } = "17:00";
|
|
}
|