feat: implement user wallet charging and transaction logging for Daya loan processing
This commit is contained in:
+138
-2
@@ -84,7 +84,10 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
|
||||
{
|
||||
var oldPayoutIds = oldPayouts.Select(p => p.Id).ToList();
|
||||
|
||||
// ⭐ اول باید تاریخچهها حذف بشن (به خاطر FK constraint)
|
||||
// ⭐ ۱. برگرداندن NetworkBalance به حالت قبل (Revert)
|
||||
await RevertUserWalletsAsync(oldPayoutIds, cancellationToken);
|
||||
|
||||
// ⭐ ۲. حذف تاریخچهها (به خاطر FK constraint)
|
||||
var oldHistories = await _context.CommissionPayoutHistories
|
||||
.Where(h => oldPayoutIds.Contains(h.UserCommissionPayoutId))
|
||||
.ToListAsync(cancellationToken);
|
||||
@@ -94,7 +97,7 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
|
||||
_context.CommissionPayoutHistories.RemoveRange(oldHistories);
|
||||
}
|
||||
|
||||
// بعد پرداختها حذف میشن
|
||||
// ⭐ ۳. حذف پرداختها
|
||||
_context.UserCommissionPayouts.RemoveRange(oldPayouts);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
@@ -164,8 +167,141 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
|
||||
|
||||
await _context.CommissionPayoutHistories.AddRangeAsync(historyList, cancellationToken);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// ⭐ شارژ کیف پول کاربران (NetworkBalance) و ثبت لاگ
|
||||
await ChargeUserWalletsAsync(payouts, request.WeekDefinitionId, cancellationToken);
|
||||
}
|
||||
|
||||
return existingPool.Id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// شارژ کیف پول کاربران با مبلغ کمیسیون (به NetworkBalance اضافه میشود)
|
||||
/// و ثبت لاگ تغییرات کیف پول
|
||||
/// </summary>
|
||||
private async Task ChargeUserWalletsAsync(
|
||||
List<UserCommissionPayout> payouts,
|
||||
long weekDefinitionId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var userIds = payouts.Select(p => p.UserId).Distinct().ToList();
|
||||
|
||||
// دریافت کیف پولهای موجود
|
||||
var existingWallets = await _context.UserWallets
|
||||
.Where(w => userIds.Contains(w.UserId))
|
||||
.ToDictionaryAsync(w => w.UserId, cancellationToken);
|
||||
|
||||
var newWallets = new List<UserWallet>();
|
||||
var walletLogs = new List<UserWalletChangeLog>();
|
||||
|
||||
foreach (var payout in payouts)
|
||||
{
|
||||
if (payout.TotalAmount <= 0) continue;
|
||||
|
||||
UserWallet wallet;
|
||||
|
||||
// پیدا کردن یا ایجاد کیف پول
|
||||
if (existingWallets.TryGetValue(payout.UserId, out var existingWallet))
|
||||
{
|
||||
wallet = existingWallet;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ایجاد کیف پول جدید
|
||||
wallet = new UserWallet
|
||||
{
|
||||
UserId = payout.UserId,
|
||||
Balance = 0,
|
||||
NetworkBalance = 0,
|
||||
DiscountBalance = 0
|
||||
};
|
||||
newWallets.Add(wallet);
|
||||
existingWallets[payout.UserId] = wallet; // برای جلوگیری از تکرار
|
||||
}
|
||||
}
|
||||
|
||||
// ذخیره کیف پولهای جدید
|
||||
if (newWallets.Any())
|
||||
{
|
||||
await _context.UserWallets.AddRangeAsync(newWallets, cancellationToken);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
// شارژ کیف پولها و ثبت لاگ
|
||||
foreach (var payout in payouts)
|
||||
{
|
||||
if (payout.TotalAmount <= 0) continue;
|
||||
|
||||
var wallet = existingWallets[payout.UserId];
|
||||
|
||||
// ذخیره موجودی قبلی برای لاگ
|
||||
var previousNetworkBalance = wallet.NetworkBalance;
|
||||
|
||||
// شارژ NetworkBalance
|
||||
wallet.NetworkBalance += payout.TotalAmount;
|
||||
|
||||
// ایجاد لاگ تغییر کیف پول
|
||||
var walletLog = new UserWalletChangeLog
|
||||
{
|
||||
WalletId = wallet.Id,
|
||||
CurrentBalance = wallet.Balance,
|
||||
ChangeValue = 0, // Balance اصلی تغییر نمیکند
|
||||
CurrentNetworkBalance = wallet.NetworkBalance,
|
||||
ChangeNerworkValue = payout.TotalAmount,
|
||||
CurrentDiscountBalance = wallet.DiscountBalance,
|
||||
ChangeDiscountValue = 0,
|
||||
IsIncrease = true,
|
||||
RefrenceId = payout.Id // ارجاع به UserCommissionPayout
|
||||
};
|
||||
|
||||
walletLogs.Add(walletLog);
|
||||
}
|
||||
|
||||
// ذخیره تغییرات کیف پول و لاگها
|
||||
await _context.UserWalletChangeLogs.AddRangeAsync(walletLogs, cancellationToken);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// برگرداندن NetworkBalance به حالت قبل از شارژ کمیسیون
|
||||
/// این متد قبل از محاسبه مجدد (ForceRecalculate) اجرا میشود
|
||||
/// </summary>
|
||||
private async Task RevertUserWalletsAsync(
|
||||
List<long> oldPayoutIds,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// پیدا کردن لاگهای کیف پول مرتبط با پرداختهای قبلی
|
||||
var oldWalletLogs = await _context.UserWalletChangeLogs
|
||||
.Where(l => l.RefrenceId.HasValue && oldPayoutIds.Contains(l.RefrenceId.Value))
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
if (!oldWalletLogs.Any()) return;
|
||||
|
||||
// پیدا کردن کیف پولهای مرتبط
|
||||
var walletIds = oldWalletLogs.Select(l => l.WalletId).Distinct().ToList();
|
||||
var wallets = await _context.UserWallets
|
||||
.Where(w => walletIds.Contains(w.Id))
|
||||
.ToDictionaryAsync(w => w.Id, cancellationToken);
|
||||
|
||||
// برگرداندن NetworkBalance
|
||||
foreach (var log in oldWalletLogs)
|
||||
{
|
||||
if (wallets.TryGetValue(log.WalletId, out var wallet))
|
||||
{
|
||||
// کم کردن مبلغ شارژ شده قبلی از NetworkBalance
|
||||
wallet.NetworkBalance -= log.ChangeNerworkValue;
|
||||
|
||||
// اطمینان از منفی نشدن
|
||||
if (wallet.NetworkBalance < 0)
|
||||
{
|
||||
wallet.NetworkBalance = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// حذف لاگهای قبلی
|
||||
_context.UserWalletChangeLogs.RemoveRange(oldWalletLogs);
|
||||
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user