da1a2fcf8e
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 10m35s
- commission.proto: add BulkCreditPayouts rpc + request/response messages; bump version to 0.0.198 - BulkCreditPayoutsCommand + Handler: load all Pending payouts for given week, credit UserWallet.Balance for each user, create UserWalletHistory + CommissionPayoutHistory records, set Status=Paid + PaidAt - CommissionService: wire up BulkCreditPayouts gRPC method - CommissionProfile: add Mapster mappings for request/result ↔ proto types Previously ProcessUserPayouts created records with Status=Pending but never credited wallets, making CustomerWithdrawBalance unreachable (it requires Status==Paid). Co-authored-by: Cursor <cursoragent@cursor.com>
120 lines
4.7 KiB
C#
120 lines
4.7 KiB
C#
using CMSMicroservice.Application.Common.Interfaces;
|
|
using CMSMicroservice.Domain.Entities;
|
|
using CMSMicroservice.Domain.Entities.Commission;
|
|
using CMSMicroservice.Domain.Entities.History;
|
|
using CMSMicroservice.Domain.Enums;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace CMSMicroservice.Application.CommissionCQ.Commands.BulkCreditPayouts;
|
|
|
|
public class BulkCreditPayoutsCommandHandler : IRequestHandler<BulkCreditPayoutsCommand, BulkCreditPayoutsResult>
|
|
{
|
|
private readonly IApplicationDbContext _context;
|
|
private readonly ICurrentUserService _currentUser;
|
|
private readonly ILogger<BulkCreditPayoutsCommandHandler> _logger;
|
|
|
|
public BulkCreditPayoutsCommandHandler(
|
|
IApplicationDbContext context,
|
|
ICurrentUserService currentUser,
|
|
ILogger<BulkCreditPayoutsCommandHandler> logger)
|
|
{
|
|
_context = context;
|
|
_currentUser = currentUser;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task<BulkCreditPayoutsResult> Handle(BulkCreditPayoutsCommand request, CancellationToken cancellationToken)
|
|
{
|
|
// بارگذاری همه پرداختهای Pending این هفته
|
|
var pendingPayouts = await _context.UserCommissionPayouts
|
|
.Where(p => p.WeekDefinitionId == request.WeekDefinitionId
|
|
&& p.Status == CommissionPayoutStatus.Pending
|
|
&& !p.IsDeleted)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
if (!pendingPayouts.Any())
|
|
{
|
|
return new BulkCreditPayoutsResult { CreditedCount = 0, TotalCredited = 0 };
|
|
}
|
|
|
|
// بارگذاری کیف پول همه کاربران مربوطه (یک query)
|
|
var userIds = pendingPayouts.Select(p => p.UserId).Distinct().ToList();
|
|
var wallets = await _context.UserWallets
|
|
.Where(w => userIds.Contains(w.UserId) && !w.IsDeleted)
|
|
.ToDictionaryAsync(w => w.UserId, cancellationToken);
|
|
|
|
var performedBy = _currentUser.GetPerformedBy() ?? "System";
|
|
var now = DateTime.UtcNow;
|
|
|
|
var walletHistories = new List<UserWalletHistory>();
|
|
var payoutHistories = new List<CommissionPayoutHistory>();
|
|
var creditedCount = 0;
|
|
long totalCredited = 0;
|
|
|
|
foreach (var payout in pendingPayouts)
|
|
{
|
|
if (!wallets.TryGetValue(payout.UserId, out var wallet))
|
|
{
|
|
_logger.LogWarning(
|
|
"Wallet not found for UserId={UserId}, PayoutId={PayoutId} — skipping",
|
|
payout.UserId, payout.Id);
|
|
continue;
|
|
}
|
|
|
|
var oldBalance = wallet.Balance;
|
|
|
|
// واریز مبلغ به کیف پول
|
|
wallet.Balance += payout.TotalAmount;
|
|
|
|
walletHistories.Add(new UserWalletHistory
|
|
{
|
|
WalletId = wallet.Id,
|
|
CurrentBalance = wallet.Balance,
|
|
CurrentNetworkBalance = wallet.NetworkBalance,
|
|
CurrentDiscountBalance = wallet.DiscountBalance,
|
|
ChangeValue = payout.TotalAmount,
|
|
ChangeNerworkValue = 0,
|
|
ChangeDiscountValue = 0,
|
|
IsIncrease = true,
|
|
RefrenceId = payout.Id
|
|
});
|
|
|
|
// بهروزرسانی وضعیت پرداخت
|
|
payout.Status = CommissionPayoutStatus.Paid;
|
|
payout.PaidAt = now;
|
|
payout.LastModified = now;
|
|
|
|
payoutHistories.Add(new CommissionPayoutHistory
|
|
{
|
|
UserCommissionPayoutId = payout.Id,
|
|
UserId = payout.UserId,
|
|
WeekDefinitionId = payout.WeekDefinitionId,
|
|
AmountBefore = 0,
|
|
AmountAfter = payout.TotalAmount,
|
|
OldStatus = CommissionPayoutStatus.Pending,
|
|
NewStatus = CommissionPayoutStatus.Paid,
|
|
Action = CommissionPayoutAction.Paid,
|
|
PerformedBy = performedBy,
|
|
Reason = $"واریز دستهجمعی کمیسیون هفته {payout.WeekDefinitionId} توسط {performedBy}"
|
|
});
|
|
|
|
creditedCount++;
|
|
totalCredited += payout.TotalAmount;
|
|
}
|
|
|
|
await _context.UserWalletHistories.AddRangeAsync(walletHistories, cancellationToken);
|
|
await _context.CommissionPayoutHistories.AddRangeAsync(payoutHistories, cancellationToken);
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
|
|
_logger.LogInformation(
|
|
"BulkCreditPayouts completed: Week={WeekId}, Credited={Count}, TotalAmount={Total}, By={By}",
|
|
request.WeekDefinitionId, creditedCount, totalCredited, performedBy);
|
|
|
|
return new BulkCreditPayoutsResult
|
|
{
|
|
CreditedCount = creditedCount,
|
|
TotalCredited = totalCredited
|
|
};
|
|
}
|
|
}
|