Handler.cs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Domain.Entities.Store.ValueObject;
  4. using Microsoft.EntityFrameworkCore;
  5. using SharedKernel.Results;
  6. namespace Application.Features.Admin.Store.Coupon.Delete;
  7. public sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Result>
  8. {
  9. public async Task<Result> Handle(Command request, CancellationToken ct)
  10. {
  11. if (request.IDs is null || request.IDs.Length == 0)
  12. {
  13. return Result.Failure(Error.Problem("Coupon.NoIDs", "삭제할 쿠폰을 선택해 주세요."));
  14. }
  15. // 발급(Issued)/사용(Used) 코드가 있으면 삭제 거부
  16. var issuedCodeCoupons = await db.CouponCode
  17. .Where(c => request.IDs.Contains(c.CouponID) && (c.Status == CouponCodeStatus.Issued || c.Status == CouponCodeStatus.Used))
  18. .Select(c => c.CouponID)
  19. .Distinct()
  20. .ToListAsync(ct);
  21. if (issuedCodeCoupons.Count > 0)
  22. {
  23. return Result.Failure(Error.Conflict("Coupon.InUse", $"이미 발급되거나 사용된 코드가 있는 쿠폰은 삭제할 수 없습니다. (쿠폰 ID: {string.Join(", ", issuedCodeCoupons)})"));
  24. }
  25. var coupons = await db.Coupon.Where(c => request.IDs.Contains(c.ID)).ToListAsync(ct);
  26. if (coupons.Count == 0)
  27. {
  28. return Result.Failure(Error.NotFound("Coupon.NotFound", "삭제할 쿠폰을 찾을 수 없습니다."));
  29. }
  30. // CouponCode 는 CASCADE 로 자동 삭제됨 (EF Configuration 에서 DeleteBehavior.Cascade)
  31. db.Coupon.RemoveRange(coupons);
  32. await db.SaveChangesAsync(ct);
  33. return Result.Success();
  34. }
  35. }