feat: Add ClearCart command and response, implement CancelOrder command with validation, and enhance DeliveryStatus and User models
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
||||
namespace CMSMicroservice.Application.TransactionsCQ.Commands.RefundTransaction;
|
||||
|
||||
/// <summary>
|
||||
/// Command برای استرداد تراکنش
|
||||
/// </summary>
|
||||
public record RefundTransactionCommand : IRequest<RefundTransactionResponseDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// شناسه تراکنش برای استرداد
|
||||
/// </summary>
|
||||
public long TransactionId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// دلیل استرداد
|
||||
/// </summary>
|
||||
public string RefundReason { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// مبلغ استرداد (اگر null باشد، کل مبلغ استرداد میشود)
|
||||
/// </summary>
|
||||
public long? RefundAmount { get; init; }
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
using CMSMicroservice.Domain.Events;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.TransactionsCQ.Commands.RefundTransaction;
|
||||
|
||||
public class RefundTransactionCommandHandler : IRequestHandler<RefundTransactionCommand, RefundTransactionResponseDto>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
|
||||
public RefundTransactionCommandHandler(IApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<RefundTransactionResponseDto> Handle(RefundTransactionCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// پیدا کردن تراکنش اصلی
|
||||
var originalTransaction = await _context.Transactionss
|
||||
.FirstOrDefaultAsync(t => t.Id == request.TransactionId, cancellationToken);
|
||||
|
||||
if (originalTransaction == null)
|
||||
{
|
||||
throw new NotFoundException(nameof(Transactions), request.TransactionId);
|
||||
}
|
||||
|
||||
// چک کردن که تراکنش Success باشد
|
||||
if (originalTransaction.PaymentStatus != PaymentStatus.Success)
|
||||
{
|
||||
throw new InvalidOperationException($"فقط تراکنشهای موفق قابل استرداد هستند. وضعیت فعلی: {originalTransaction.PaymentStatus}");
|
||||
}
|
||||
|
||||
// محاسبه مبلغ استرداد
|
||||
var refundAmount = request.RefundAmount ?? originalTransaction.Amount;
|
||||
|
||||
if (refundAmount > originalTransaction.Amount)
|
||||
{
|
||||
throw new InvalidOperationException("مبلغ استرداد نمیتواند بیشتر از مبلغ اصلی باشد");
|
||||
}
|
||||
|
||||
// ایجاد تراکنش استرداد جدید
|
||||
var refundTransaction = new Transactions
|
||||
{
|
||||
Amount = -refundAmount, // مبلغ منفی برای استرداد
|
||||
Description = $"استرداد تراکنش {request.TransactionId}: {request.RefundReason}",
|
||||
PaymentStatus = PaymentStatus.Success,
|
||||
PaymentDate = DateTime.UtcNow,
|
||||
RefId = $"REFUND-{originalTransaction.RefId}",
|
||||
Type = TransactionType.Buy // یا میتونیم یک نوع جدید برای Refund تعریف کنیم
|
||||
};
|
||||
|
||||
await _context.Transactionss.AddAsync(refundTransaction, cancellationToken);
|
||||
refundTransaction.AddDomainEvent(new RefundTransactionEvent(refundTransaction, originalTransaction));
|
||||
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new RefundTransactionResponseDto
|
||||
{
|
||||
OriginalTransactionId = originalTransaction.Id,
|
||||
RefundTransactionId = refundTransaction.Id,
|
||||
RefundAmount = refundAmount,
|
||||
Message = "استرداد با موفقیت انجام شد"
|
||||
};
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
namespace CMSMicroservice.Application.TransactionsCQ.Commands.RefundTransaction;
|
||||
|
||||
public class RefundTransactionCommandValidator : AbstractValidator<RefundTransactionCommand>
|
||||
{
|
||||
public RefundTransactionCommandValidator()
|
||||
{
|
||||
RuleFor(v => v.TransactionId)
|
||||
.GreaterThan(0)
|
||||
.WithMessage("شناسه تراکنش باید بزرگتر از صفر باشد");
|
||||
|
||||
RuleFor(v => v.RefundReason)
|
||||
.NotEmpty()
|
||||
.WithMessage("دلیل استرداد الزامی است")
|
||||
.MaximumLength(500)
|
||||
.WithMessage("دلیل استرداد نباید بیش از 500 کاراکتر باشد");
|
||||
|
||||
RuleFor(v => v.RefundAmount)
|
||||
.GreaterThan(0)
|
||||
.When(v => v.RefundAmount.HasValue)
|
||||
.WithMessage("مبلغ استرداد باید بزرگتر از صفر باشد");
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
namespace CMSMicroservice.Application.TransactionsCQ.Commands.RefundTransaction;
|
||||
|
||||
public class RefundTransactionResponseDto
|
||||
{
|
||||
public long OriginalTransactionId { get; set; }
|
||||
public long RefundTransactionId { get; set; }
|
||||
public long RefundAmount { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.TransactionsCQ.Commands.VerifyTransaction;
|
||||
|
||||
/// <summary>
|
||||
/// Command برای تایید پرداخت (Callback از درگاه)
|
||||
/// </summary>
|
||||
public record VerifyTransactionCommand : IRequest<VerifyTransactionResponseDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// شناسه تراکنش در سیستم
|
||||
/// </summary>
|
||||
public long TransactionId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// کد رهگیری از درگاه پرداخت (RefId)
|
||||
/// </summary>
|
||||
public string RefId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// وضعیت پرداخت از درگاه
|
||||
/// </summary>
|
||||
public PaymentStatus Status { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// تاریخ پرداخت
|
||||
/// </summary>
|
||||
public DateTime PaymentDate { get; init; }
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
using CMSMicroservice.Domain.Events;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.TransactionsCQ.Commands.VerifyTransaction;
|
||||
|
||||
public class VerifyTransactionCommandHandler : IRequestHandler<VerifyTransactionCommand, VerifyTransactionResponseDto>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
|
||||
public VerifyTransactionCommandHandler(IApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<VerifyTransactionResponseDto> Handle(VerifyTransactionCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// پیدا کردن تراکنش
|
||||
var transaction = await _context.Transactionss
|
||||
.FirstOrDefaultAsync(t => t.Id == request.TransactionId, cancellationToken);
|
||||
|
||||
if (transaction == null)
|
||||
{
|
||||
throw new NotFoundException(nameof(Transactions), request.TransactionId);
|
||||
}
|
||||
|
||||
// چک کردن که تراکنش در وضعیت Pending باشد
|
||||
if (transaction.PaymentStatus != PaymentStatus.Pending)
|
||||
{
|
||||
throw new InvalidOperationException($"Transaction {request.TransactionId} is not in Pending status. Current status: {transaction.PaymentStatus}");
|
||||
}
|
||||
|
||||
// بهروزرسانی وضعیت تراکنش
|
||||
transaction.PaymentStatus = request.Status;
|
||||
transaction.RefId = request.RefId;
|
||||
transaction.PaymentDate = request.PaymentDate;
|
||||
|
||||
// ثبت Event
|
||||
transaction.AddDomainEvent(new VerifyTransactionEvent(transaction));
|
||||
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new VerifyTransactionResponseDto
|
||||
{
|
||||
TransactionId = transaction.Id,
|
||||
Status = transaction.PaymentStatus,
|
||||
RefId = transaction.RefId,
|
||||
Message = transaction.PaymentStatus == PaymentStatus.Success
|
||||
? "پرداخت با موفقیت انجام شد"
|
||||
: "پرداخت ناموفق بود"
|
||||
};
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
namespace CMSMicroservice.Application.TransactionsCQ.Commands.VerifyTransaction;
|
||||
|
||||
public class VerifyTransactionCommandValidator : AbstractValidator<VerifyTransactionCommand>
|
||||
{
|
||||
public VerifyTransactionCommandValidator()
|
||||
{
|
||||
RuleFor(v => v.TransactionId)
|
||||
.GreaterThan(0)
|
||||
.WithMessage("شناسه تراکنش باید بزرگتر از صفر باشد");
|
||||
|
||||
RuleFor(v => v.RefId)
|
||||
.NotEmpty()
|
||||
.WithMessage("کد رهگیری الزامی است")
|
||||
.MaximumLength(100)
|
||||
.WithMessage("کد رهگیری نباید بیش از 100 کاراکتر باشد");
|
||||
|
||||
RuleFor(v => v.PaymentDate)
|
||||
.NotEmpty()
|
||||
.WithMessage("تاریخ پرداخت الزامی است");
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
|
||||
namespace CMSMicroservice.Application.TransactionsCQ.Commands.VerifyTransaction;
|
||||
|
||||
public class VerifyTransactionResponseDto
|
||||
{
|
||||
public long TransactionId { get; set; }
|
||||
public PaymentStatus Status { get; set; }
|
||||
public string RefId { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using CMSMicroservice.Domain.Events;
|
||||
|
||||
namespace CMSMicroservice.Application.TransactionsCQ.EventHandlers.RefundTransactionEventHandlers;
|
||||
|
||||
public class RefundTransactionEventHandler : INotificationHandler<RefundTransactionEvent>
|
||||
{
|
||||
private readonly ILogger<RefundTransactionEventHandler> _logger;
|
||||
|
||||
public RefundTransactionEventHandler(ILogger<RefundTransactionEventHandler> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public Task Handle(RefundTransactionEvent notification, CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Transaction {OriginalId} refunded with new transaction {RefundId}. Amount: {Amount}",
|
||||
notification.OriginalTransaction.Id,
|
||||
notification.RefundTransaction.Id,
|
||||
notification.RefundTransaction.Amount);
|
||||
|
||||
// اینجا میتونیم اعلان به کاربر بفرستیم یا کارهای دیگه انجام بدیم
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using CMSMicroservice.Domain.Events;
|
||||
|
||||
namespace CMSMicroservice.Application.TransactionsCQ.EventHandlers.VerifyTransactionEventHandlers;
|
||||
|
||||
public class VerifyTransactionEventHandler : INotificationHandler<VerifyTransactionEvent>
|
||||
{
|
||||
private readonly ILogger<VerifyTransactionEventHandler> _logger;
|
||||
|
||||
public VerifyTransactionEventHandler(ILogger<VerifyTransactionEventHandler> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public Task Handle(VerifyTransactionEvent notification, CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Transaction {TransactionId} verified with status {Status} and RefId {RefId}",
|
||||
notification.Item.Id,
|
||||
notification.Item.PaymentStatus,
|
||||
notification.Item.RefId);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user