feat: Add ClearCart command and response, implement CancelOrder command with validation, and enhance DeliveryStatus and User models
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Commands.CancelOrder;
|
||||
|
||||
/// <summary>
|
||||
/// Command برای لغو سفارش
|
||||
/// </summary>
|
||||
public record CancelOrderCommand : IRequest<CancelOrderResponseDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// شناسه سفارش
|
||||
/// </summary>
|
||||
public long OrderId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// دلیل لغو سفارش
|
||||
/// </summary>
|
||||
public string CancelReason { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// آیا مبلغ باید بازگردانده شود؟
|
||||
/// </summary>
|
||||
public bool RefundPayment { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using CMSMicroservice.Domain.Events;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Commands.CancelOrder;
|
||||
|
||||
public class CancelOrderCommandHandler : IRequestHandler<CancelOrderCommand, CancelOrderResponseDto>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
|
||||
public CancelOrderCommandHandler(IApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<CancelOrderResponseDto> Handle(CancelOrderCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// پیدا کردن سفارش
|
||||
var order = await _context.UserOrders
|
||||
.Include(o => o.Transaction)
|
||||
.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
|
||||
|
||||
if (order == null)
|
||||
{
|
||||
throw new NotFoundException(nameof(UserOrder), request.OrderId);
|
||||
}
|
||||
|
||||
// چک کردن که سفارش قابل لغو باشد
|
||||
if (order.DeliveryStatus == DeliveryStatus.Delivered)
|
||||
{
|
||||
throw new InvalidOperationException("سفارش تحویل داده شده قابل لغو نیست");
|
||||
}
|
||||
|
||||
if (order.DeliveryStatus == DeliveryStatus.Cancelled)
|
||||
{
|
||||
throw new InvalidOperationException("این سفارش قبلاً لغو شده است");
|
||||
}
|
||||
|
||||
// تغییر وضعیت سفارش
|
||||
order.DeliveryStatus = DeliveryStatus.Cancelled;
|
||||
order.DeliveryDescription = $"لغو شده: {request.CancelReason}";
|
||||
|
||||
// اگر درخواست بازگشت پول داریم و پرداخت موفق بوده
|
||||
if (request.RefundPayment &&
|
||||
order.Transaction != null &&
|
||||
order.Transaction.PaymentStatus == PaymentStatus.Success)
|
||||
{
|
||||
// ایجاد تراکنش استرداد
|
||||
var refundTransaction = new Transactions
|
||||
{
|
||||
Amount = -order.Amount,
|
||||
Description = $"بازگشت وجه سفارش {request.OrderId}: {request.CancelReason}",
|
||||
PaymentStatus = PaymentStatus.Success,
|
||||
PaymentDate = DateTime.UtcNow,
|
||||
RefId = $"REFUND-ORDER-{order.Id}",
|
||||
Type = TransactionType.Buy
|
||||
};
|
||||
|
||||
await _context.Transactionss.AddAsync(refundTransaction, cancellationToken);
|
||||
}
|
||||
|
||||
// ثبت Event
|
||||
order.AddDomainEvent(new CancelOrderEvent(order, request.CancelReason));
|
||||
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new CancelOrderResponseDto
|
||||
{
|
||||
OrderId = order.Id,
|
||||
Status = order.DeliveryStatus,
|
||||
Message = "سفارش با موفقیت لغو شد",
|
||||
RefundProcessed = request.RefundPayment && order.Transaction != null
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Commands.CancelOrder;
|
||||
|
||||
public class CancelOrderCommandValidator : AbstractValidator<CancelOrderCommand>
|
||||
{
|
||||
public CancelOrderCommandValidator()
|
||||
{
|
||||
RuleFor(v => v.OrderId)
|
||||
.GreaterThan(0)
|
||||
.WithMessage("شناسه سفارش باید بزرگتر از صفر باشد");
|
||||
|
||||
RuleFor(v => v.CancelReason)
|
||||
.NotEmpty()
|
||||
.WithMessage("دلیل لغو سفارش الزامی است")
|
||||
.MaximumLength(500)
|
||||
.WithMessage("دلیل لغو نباید بیش از 500 کاراکتر باشد");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.Commands.CancelOrder;
|
||||
|
||||
public class CancelOrderResponseDto
|
||||
{
|
||||
public long OrderId { get; set; }
|
||||
public DeliveryStatus Status { get; set; }
|
||||
public string Message { get; set; }
|
||||
public bool RefundProcessed { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using CMSMicroservice.Domain.Events;
|
||||
|
||||
namespace CMSMicroservice.Application.UserOrderCQ.EventHandlers.CancelOrderEventHandlers;
|
||||
|
||||
public class CancelOrderEventHandler : INotificationHandler<CancelOrderEvent>
|
||||
{
|
||||
private readonly ILogger<CancelOrderEventHandler> _logger;
|
||||
|
||||
public CancelOrderEventHandler(ILogger<CancelOrderEventHandler> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public Task Handle(CancelOrderEvent notification, CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Order {OrderId} cancelled. Reason: {Reason}",
|
||||
notification.Order.Id,
|
||||
notification.CancelReason);
|
||||
|
||||
// اینجا میتونیم اعلان به کاربر بفرستیم
|
||||
// یا موجودی محصولات رو بازگردانیم به انبار
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user