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