Files
pos-system/services/booking-service-net/src/BookingService.API/Controllers/SchedulesController.cs

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";
}