Files
pos-system/services/wallet-service-net/src/WalletService.API/Application/Commands/ExchangeCommandHandler.cs

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
);
}
}