| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- using Application.Abstractions.Data;
- using Application.Abstractions.Messaging;
- using Domain.Entities.Store.ValueObject;
- using Microsoft.EntityFrameworkCore;
- using SharedKernel.Results;
- namespace Application.Features.Admin.Store.Shipment.UpdateStatus;
- public sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Result>
- {
- public async Task<Result> Handle(Command request, CancellationToken ct)
- {
- var shipment = await db.Shipment
- .Include(s => s.Order)
- .FirstOrDefaultAsync(s => s.ID == request.ShipmentID, ct);
- if (shipment is null)
- {
- return Result.Failure(Error.NotFound("Shipment.NotFound", "배송 정보를 찾을 수 없습니다."));
- }
- try
- {
- switch (request.Action)
- {
- case "RegisterTracking":
- if (string.IsNullOrWhiteSpace(request.Carrier) || string.IsNullOrWhiteSpace(request.TrackingNumber))
- {
- return Result.Failure(Error.Problem("Shipment.TrackingRequired", "택배사와 송장번호를 모두 입력해주세요."));
- }
- shipment.RegisterTracking(request.Carrier, request.TrackingNumber);
- if (shipment.Order is not null && shipment.Order.Status == OrderStatus.Paid)
- {
- shipment.Order.MarkPreparing();
- }
- break;
- case "InTransit":
- shipment.MarkInTransit();
- if (shipment.Order is not null && shipment.Order.Status is OrderStatus.Paid or OrderStatus.Preparing)
- {
- shipment.Order.MarkShipped();
- }
- break;
- case "Delivered":
- shipment.MarkDelivered();
- if (shipment.Order is not null && shipment.Order.Status is OrderStatus.Paid or OrderStatus.Preparing or OrderStatus.Shipped)
- {
- shipment.Order.MarkDelivered();
- }
- break;
- case "Failed":
- shipment.MarkFailed();
- break;
- case "UpdateBilling":
- if (request.ShippingFee is null)
- {
- return Result.Failure(Error.Problem("Shipment.ShippingFeeRequired", "배송비를 입력해주세요."));
- }
- if (request.ShippingFee < 0)
- {
- return Result.Failure(Error.Problem("Shipment.ShippingFeeNegative", "배송비는 0 이상이어야 합니다."));
- }
- if (request.AdminMemo is { Length: > 500 })
- {
- return Result.Failure(Error.Problem("Shipment.AdminMemoTooLong", "관리자 메모는 500자 이하여야 합니다."));
- }
- shipment.UpdateBillingInfo(request.ShippingFee.Value, request.AdminMemo);
- break;
- default:
- return Result.Failure(Error.Problem("Shipment.UnknownAction", $"알 수 없는 액션: {request.Action}"));
- }
- }
- catch (InvalidOperationException ex)
- {
- return Result.Failure(Error.Problem("Shipment.InvalidTransition", ex.Message));
- }
- await db.SaveChangesAsync(ct);
- return Result.Success();
- }
- }
|