namespace WalletService.API.Application.Commands; using MediatR; using WalletService.Domain.AggregatesModel.PointAccountAggregate; using WalletService.Domain.Exceptions; /// /// EN: Handler for EarnPointsCommand /// VI: Handler cho EarnPointsCommand /// public class EarnPointsCommandHandler : IRequestHandler { private readonly IPointAccountRepository _pointAccountRepository; private readonly ILogger _logger; public EarnPointsCommandHandler( IPointAccountRepository pointAccountRepository, ILogger logger) { _pointAccountRepository = pointAccountRepository; _logger = logger; } public async Task Handle( EarnPointsCommand request, CancellationToken cancellationToken) { var account = await _pointAccountRepository.GetByUserIdAsync(request.UserId) ?? throw new PointsDomainException($"Point account not found for user {request.UserId}"); // EN: Calculate expiry date // VI: Tính ngày hết hạn DateTime? expiresAt = request.ExpiryMonths.HasValue ? DateTime.UtcNow.AddMonths(request.ExpiryMonths.Value) : null; // EN: Earn points // VI: Tích điểm account.EarnPoints(request.Points, request.Source, request.Description, expiresAt); _pointAccountRepository.Update(account); await _pointAccountRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken); var transaction = account.Transactions.Last(); _logger.LogInformation( "Earned {Points} points for user {UserId}, source: {Source}", request.Points, request.UserId, request.Source); return new PointTransactionResult( transaction.Id, account.Id, transaction.Points, transaction.Type.Name, transaction.BalanceAfter, transaction.CreatedAt, transaction.ExpiresAt ); } }