Handler.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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.Shipment.UpdateStatus;
  7. public sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Result>
  8. {
  9. public async Task<Result> Handle(Command request, CancellationToken ct)
  10. {
  11. var shipment = await db.Shipment
  12. .Include(s => s.Order)
  13. .FirstOrDefaultAsync(s => s.ID == request.ShipmentID, ct);
  14. if (shipment is null)
  15. {
  16. return Result.Failure(Error.NotFound("Shipment.NotFound", "배송 정보를 찾을 수 없습니다."));
  17. }
  18. try
  19. {
  20. switch (request.Action)
  21. {
  22. case "RegisterTracking":
  23. if (string.IsNullOrWhiteSpace(request.Carrier) || string.IsNullOrWhiteSpace(request.TrackingNumber))
  24. {
  25. return Result.Failure(Error.Problem("Shipment.TrackingRequired", "택배사와 송장번호를 모두 입력해주세요."));
  26. }
  27. shipment.RegisterTracking(request.Carrier, request.TrackingNumber);
  28. if (shipment.Order is not null && shipment.Order.Status == OrderStatus.Paid)
  29. {
  30. shipment.Order.MarkPreparing();
  31. }
  32. break;
  33. case "InTransit":
  34. shipment.MarkInTransit();
  35. if (shipment.Order is not null && shipment.Order.Status is OrderStatus.Paid or OrderStatus.Preparing)
  36. {
  37. shipment.Order.MarkShipped();
  38. }
  39. break;
  40. case "Delivered":
  41. shipment.MarkDelivered();
  42. if (shipment.Order is not null && shipment.Order.Status is OrderStatus.Paid or OrderStatus.Preparing or OrderStatus.Shipped)
  43. {
  44. shipment.Order.MarkDelivered();
  45. }
  46. break;
  47. case "Failed":
  48. shipment.MarkFailed();
  49. break;
  50. case "UpdateBilling":
  51. if (request.ShippingFee is null)
  52. {
  53. return Result.Failure(Error.Problem("Shipment.ShippingFeeRequired", "배송비를 입력해주세요."));
  54. }
  55. if (request.ShippingFee < 0)
  56. {
  57. return Result.Failure(Error.Problem("Shipment.ShippingFeeNegative", "배송비는 0 이상이어야 합니다."));
  58. }
  59. if (request.AdminMemo is { Length: > 500 })
  60. {
  61. return Result.Failure(Error.Problem("Shipment.AdminMemoTooLong", "관리자 메모는 500자 이하여야 합니다."));
  62. }
  63. shipment.UpdateBillingInfo(request.ShippingFee.Value, request.AdminMemo);
  64. break;
  65. default:
  66. return Result.Failure(Error.Problem("Shipment.UnknownAction", $"알 수 없는 액션: {request.Action}"));
  67. }
  68. }
  69. catch (InvalidOperationException ex)
  70. {
  71. return Result.Failure(Error.Problem("Shipment.InvalidTransition", ex.Message));
  72. }
  73. await db.SaveChangesAsync(ct);
  74. return Result.Success();
  75. }
  76. }