65 lines
2.3 KiB
C#
65 lines
2.3 KiB
C#
namespace WalletService.API.Application.Commands;
|
|
|
|
using MediatR;
|
|
using WalletService.Domain.AggregatesModel.WalletAggregate;
|
|
using WalletService.Domain.Exceptions;
|
|
using WalletService.Domain.SeedWork;
|
|
|
|
/// <summary>
|
|
/// EN: Handler for ExchangeCommand.
|
|
/// VI: Handler cho ExchangeCommand.
|
|
/// </summary>
|
|
public class ExchangeCommandHandler : IRequestHandler<ExchangeCommand, ExchangeResult>
|
|
{
|
|
private readonly IWalletRepository _walletRepository;
|
|
private readonly ILogger<ExchangeCommandHandler> _logger;
|
|
|
|
public ExchangeCommandHandler(
|
|
IWalletRepository walletRepository,
|
|
ILogger<ExchangeCommandHandler> logger)
|
|
{
|
|
_walletRepository = walletRepository;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task<ExchangeResult> Handle(
|
|
ExchangeCommand request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
// EN: Get wallet by user ID
|
|
// VI: Lấy ví theo user ID
|
|
var wallet = await _walletRepository.GetByUserIdAsync(request.UserId)
|
|
?? throw new WalletDomainException($"Wallet not found for user {request.UserId}");
|
|
|
|
// EN: Parse currency types from IDs
|
|
// VI: Parse loại tiền tệ từ IDs
|
|
var fromCurrency = Enumeration.FromValue<CurrencyType>(request.FromCurrencyTypeId);
|
|
var toCurrency = Enumeration.FromValue<CurrencyType>(request.ToCurrencyTypeId);
|
|
|
|
// EN: Calculate actual rate
|
|
// VI: Tính tỷ giá thực tế
|
|
var rate = request.CustomRate ?? fromCurrency.GetExchangeRateTo(toCurrency);
|
|
|
|
// EN: Perform exchange (atomic operation within aggregate)
|
|
// VI: Thực hiện quy đổi (thao tác atomic trong aggregate)
|
|
var receivedAmount = wallet.Exchange(request.FromAmount, fromCurrency, toCurrency, request.CustomRate);
|
|
|
|
_walletRepository.Update(wallet);
|
|
await _walletRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);
|
|
|
|
_logger.LogInformation(
|
|
"Exchanged {FromAmount} {FromCurrency} to {ToAmount} {ToCurrency} in wallet {WalletId}",
|
|
request.FromAmount, fromCurrency.Name, receivedAmount, toCurrency.Name, wallet.Id);
|
|
|
|
return new ExchangeResult(
|
|
wallet.Id,
|
|
request.FromAmount,
|
|
fromCurrency.Name,
|
|
receivedAmount,
|
|
toCurrency.Name,
|
|
rate,
|
|
DateTime.UtcNow
|
|
);
|
|
}
|
|
}
|