Phase 2: Replace all deprecated SystemConstants with Package entity reads
- ActivateClubMembership: Load Package, set First/Last fields, PackageId on Cycle+Pool - AcceptClubMembershipContract: Load Package, set First/Last fields, PackageId on Pool - CalculateWeeklyBalances: Load base package, use package.MaxBalancesPerLeg/MaxNetworkLevel, set PackageId on NetworkWeeklyBalance - ProcessUserPayouts: Load base package, use package.MaxNetworkLevel, set PackageId on UserCommissionPayout - CheckAndProcessDayaLoans: Load base package (IsBasePackage), replace DayaLoanAmount→package.Price, fix hardcoded p.Id==4 - CreateManualPayment: Load base package, replace BasePackageAmount→package.Price, use DiscountMultiplier - InitiateBasePackagePayment: Remove hardcoded BasePackageId=4, load from IsBasePackage, use package.Price/Id - VerifyBasePackagePayment: Load Package from order.PackageId, use package.Price+DiscountMultiplier - ChargeMagicWallet: Load user's package from current cycle, use package.MagicWalletMaxDeposit - VerifyMagicWalletCharge: Load user's package, use package.MagicWalletMultiplier/MagicWalletMaxDeposit - OrmCommissionCalculationStrategy: Load base package in both methods, set PackageId on Balance+Payout - ConfigurationService: Inject IApplicationDbContext, read package values from DB instead of SystemConstants - UserOrderService: Load user's package for EXIT trigger MagicWalletMaxDeposit check - UserWalletService: Load user's package for GetMagicWalletStatus display All 9 deprecated SystemConstants now have ZERO usages outside SystemConstants.cs Build: 0 errors, 521 warnings (all pre-existing)
This commit is contained in:
+25
-6
@@ -135,13 +135,25 @@ public class AcceptClubMembershipContractCommandHandler
|
|||||||
};
|
};
|
||||||
await _context.UserContracts.AddAsync(userContract, cancellationToken);
|
await _context.UserContracts.AddAsync(userContract, cancellationToken);
|
||||||
|
|
||||||
// 6. دریافت مقادیر از SystemConstants (استاتیک)
|
// 6. بارگذاری پکیج از آخرین خرید کاربر یا پکیج پایه
|
||||||
long giftValue = SystemConstants.ClubMembershipGiftValue;
|
var latestPurchase = await _context.UserPackagePurchases
|
||||||
long activationFeeValue = SystemConstants.ClubActivationFee;
|
.Where(p => p.UserId == userId)
|
||||||
|
.OrderByDescending(p => p.PurchasedAt)
|
||||||
|
.FirstOrDefaultAsync(cancellationToken);
|
||||||
|
|
||||||
|
var package = latestPurchase != null
|
||||||
|
? await _context.Packages.FirstOrDefaultAsync(p => p.Id == latestPurchase.PackageId && !p.IsDeleted, cancellationToken)
|
||||||
|
: await _context.Packages.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken);
|
||||||
|
|
||||||
|
if (package == null)
|
||||||
|
throw new NotFoundException("پکیج یافت نشد");
|
||||||
|
|
||||||
|
long giftValue = package.ActivationFee;
|
||||||
|
long activationFeeValue = package.ActivationFee;
|
||||||
|
|
||||||
_logger.LogInformation(
|
_logger.LogInformation(
|
||||||
"Using Club.MembershipGiftValue: {GiftValue}, Club.ActivationFee: {ActivationFee}",
|
"Using Package {PackageId} ({PackageName}): GiftValue={GiftValue}, ActivationFee={ActivationFee}",
|
||||||
giftValue, activationFeeValue
|
package.Id, package.Title, giftValue, activationFeeValue
|
||||||
);
|
);
|
||||||
|
|
||||||
// 7. فعالسازی باشگاه مشتریان
|
// 7. فعالسازی باشگاه مشتریان
|
||||||
@@ -156,6 +168,10 @@ public class AcceptClubMembershipContractCommandHandler
|
|||||||
UserId = user.Id,
|
UserId = user.Id,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
ActivatedAt = activationDate,
|
ActivatedAt = activationDate,
|
||||||
|
FirstActivationDate = activationDate,
|
||||||
|
FirstPackageId = package.Id,
|
||||||
|
LastActivationDate = activationDate,
|
||||||
|
LastPackageId = package.Id,
|
||||||
InitialContribution = activationFeeValue,
|
InitialContribution = activationFeeValue,
|
||||||
GiftValue = giftValue,
|
GiftValue = giftValue,
|
||||||
TotalEarned = 0,
|
TotalEarned = 0,
|
||||||
@@ -175,6 +191,8 @@ public class AcceptClubMembershipContractCommandHandler
|
|||||||
clubMembership = user.ClubMembership!;
|
clubMembership = user.ClubMembership!;
|
||||||
clubMembership.IsActive = true;
|
clubMembership.IsActive = true;
|
||||||
clubMembership.ActivatedAt = activationDate;
|
clubMembership.ActivatedAt = activationDate;
|
||||||
|
clubMembership.LastActivationDate = activationDate;
|
||||||
|
clubMembership.LastPackageId = package.Id;
|
||||||
clubMembership.PurchaseMethod = user.PackagePurchaseMethod;
|
clubMembership.PurchaseMethod = user.PackagePurchaseMethod;
|
||||||
_context.ClubMemberships.Update(clubMembership);
|
_context.ClubMemberships.Update(clubMembership);
|
||||||
|
|
||||||
@@ -206,13 +224,14 @@ public class AcceptClubMembershipContractCommandHandler
|
|||||||
// 9. اضافه کردن مبلغ به Pool هفته جاری
|
// 9. اضافه کردن مبلغ به Pool هفته جاری
|
||||||
var currentWeekDefinitionId = GetCurrentWeekDefinitionId();
|
var currentWeekDefinitionId = GetCurrentWeekDefinitionId();
|
||||||
var weeklyPool = await _context.WeeklyCommissionPools
|
var weeklyPool = await _context.WeeklyCommissionPools
|
||||||
.FirstOrDefaultAsync(p => p.WeekDefinitionId == currentWeekDefinitionId, cancellationToken);
|
.FirstOrDefaultAsync(p => p.WeekDefinitionId == currentWeekDefinitionId && p.PackageId == package.Id, cancellationToken);
|
||||||
|
|
||||||
if (weeklyPool == null)
|
if (weeklyPool == null)
|
||||||
{
|
{
|
||||||
weeklyPool = new WeeklyCommissionPool
|
weeklyPool = new WeeklyCommissionPool
|
||||||
{
|
{
|
||||||
WeekDefinitionId = currentWeekDefinitionId,
|
WeekDefinitionId = currentWeekDefinitionId,
|
||||||
|
PackageId = package.Id,
|
||||||
TotalPoolAmount = activationFeeValue,
|
TotalPoolAmount = activationFeeValue,
|
||||||
TotalBalances = 0,
|
TotalBalances = 0,
|
||||||
ValuePerBalance = 0,
|
ValuePerBalance = 0,
|
||||||
|
|||||||
+43
-23
@@ -54,6 +54,9 @@ public class ActivateClubMembershipCommandHandler : IRequestHandler<ActivateClub
|
|||||||
throw new NotFoundException(nameof(User), request.UserId);
|
throw new NotFoundException(nameof(User), request.UserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// متغیر پکیج — در هر دو مسیر (عادی و Force) مقداردهی میشود
|
||||||
|
Package package;
|
||||||
|
|
||||||
// 2-5: بررسیهای مالی — در حالت ForceActivation (ادمین) رد میشود
|
// 2-5: بررسیهای مالی — در حالت ForceActivation (ادمین) رد میشود
|
||||||
if (!request.ForceActivation)
|
if (!request.ForceActivation)
|
||||||
{
|
{
|
||||||
@@ -79,17 +82,8 @@ public class ActivateClubMembershipCommandHandler : IRequestHandler<ActivateClub
|
|||||||
throw new NotFoundException("کیف پول کاربر یافت نشد");
|
throw new NotFoundException("کیف پول کاربر یافت نشد");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wallet.Balance < SystemConstants.BasePackageAmount)
|
// NOTE: balance check uses package.Price — loaded after finding order (step 4)
|
||||||
{
|
// Moved to after package loading
|
||||||
_logger.LogWarning(
|
|
||||||
"User {UserId} has insufficient balance: {Balance}",
|
|
||||||
request.UserId,
|
|
||||||
wallet.Balance
|
|
||||||
);
|
|
||||||
throw new BadRequestException(
|
|
||||||
$"برای فعالسازی باشگاه مشتریان باید حداقل {SystemConstants.BasePackageAmount:N0} ریال موجودی اصلی داشته باشید"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3.5. بررسی وضعیت کیفپول جادویی — اگر در حالت Magic است، فعالسازی مجاز نیست
|
// 3.5. بررسی وضعیت کیفپول جادویی — اگر در حالت Magic است، فعالسازی مجاز نیست
|
||||||
if (wallet.WalletMode == WalletMode.Magic)
|
if (wallet.WalletMode == WalletMode.Magic)
|
||||||
@@ -146,6 +140,19 @@ public class ActivateClubMembershipCommandHandler : IRequestHandler<ActivateClub
|
|||||||
"تراکنش معتبر برای فعالسازی باشگاه یافت نشد"
|
"تراکنش معتبر برای فعالسازی باشگاه یافت نشد"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5.5. بارگذاری پکیج از سفارش
|
||||||
|
package = await _context.Packages
|
||||||
|
.FirstOrDefaultAsync(p => p.Id == packageOrder.PackageId && !p.IsDeleted, cancellationToken)
|
||||||
|
?? throw new NotFoundException("پکیج یافت نشد");
|
||||||
|
|
||||||
|
// بررسی موجودی با مبلغ پکیج واقعی
|
||||||
|
if (wallet.Balance < package.Price)
|
||||||
|
{
|
||||||
|
throw new BadRequestException(
|
||||||
|
$"برای فعالسازی باشگاه مشتریان باید حداقل {package.Price:N0} ریال موجودی اصلی داشته باشید"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -161,19 +168,24 @@ public class ActivateClubMembershipCommandHandler : IRequestHandler<ActivateClub
|
|||||||
_context.Users.Update(user);
|
_context.Users.Update(user);
|
||||||
await _context.SaveChangesAsync(cancellationToken);
|
await _context.SaveChangesAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// بارگذاری پکیج پایه برای فعالسازی اجباری
|
||||||
|
package = await _context.Packages
|
||||||
|
.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken)
|
||||||
|
?? throw new NotFoundException("پکیج پایه یافت نشد");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. بررسی عضویت فعلی
|
// 6. بررسی عضویت فعلی
|
||||||
var existingMembership = await _context.ClubMemberships
|
var existingMembership = await _context.ClubMemberships
|
||||||
.FirstOrDefaultAsync(c => c.UserId == user.Id, cancellationToken);
|
.FirstOrDefaultAsync(c => c.UserId == user.Id, cancellationToken);
|
||||||
|
|
||||||
// 6.1. دریافت مبلغ هدیه و هزینه فعالسازی از SystemConstants
|
// 6.1. دریافت مبلغ هدیه و هزینه فعالسازی از پکیج
|
||||||
long giftValue = SystemConstants.ClubMembershipGiftValue;
|
long giftValue = package.ActivationFee;
|
||||||
long activationFeeValue = SystemConstants.ClubActivationFee;
|
long activationFeeValue = package.ActivationFee;
|
||||||
|
|
||||||
_logger.LogInformation(
|
_logger.LogInformation(
|
||||||
"Using Club.MembershipGiftValue: {GiftValue}, Club.ActivationFee: {ActivationFee}",
|
"Using Package {PackageId} ({PackageName}): GiftValue={GiftValue}, ActivationFee={ActivationFee}, Price={Price}",
|
||||||
giftValue, activationFeeValue
|
package.Id, package.Title, giftValue, activationFeeValue, package.Price
|
||||||
);
|
);
|
||||||
|
|
||||||
ClubMembership entity;
|
ClubMembership entity;
|
||||||
@@ -188,8 +200,12 @@ public class ActivateClubMembershipCommandHandler : IRequestHandler<ActivateClub
|
|||||||
UserId = user.Id,
|
UserId = user.Id,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
ActivatedAt = activationDate,
|
ActivatedAt = activationDate,
|
||||||
InitialContribution =activationFeeValue,
|
FirstActivationDate = activationDate,
|
||||||
GiftValue = giftValue, // مقدار از تنظیمات
|
FirstPackageId = package.Id,
|
||||||
|
LastActivationDate = activationDate,
|
||||||
|
LastPackageId = package.Id,
|
||||||
|
InitialContribution = activationFeeValue,
|
||||||
|
GiftValue = giftValue,
|
||||||
TotalEarned = 0,
|
TotalEarned = 0,
|
||||||
PurchaseMethod = user.PackagePurchaseMethod
|
PurchaseMethod = user.PackagePurchaseMethod
|
||||||
};
|
};
|
||||||
@@ -214,9 +230,11 @@ public class ActivateClubMembershipCommandHandler : IRequestHandler<ActivateClub
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// فعالسازی مجدد — ActivatedAt حفظ میشه (overwrite نمیشه)
|
// فعالسازی مجدد — FirstActivation حفظ میشه (Q21), Last بروزرسانی میشه
|
||||||
entity = existingMembership;
|
entity = existingMembership;
|
||||||
entity.IsActive = true;
|
entity.IsActive = true;
|
||||||
|
entity.LastActivationDate = activationDate;
|
||||||
|
entity.LastPackageId = package.Id;
|
||||||
entity.PurchaseMethod = user.PackagePurchaseMethod;
|
entity.PurchaseMethod = user.PackagePurchaseMethod;
|
||||||
|
|
||||||
_context.ClubMemberships.Update(entity);
|
_context.ClubMemberships.Update(entity);
|
||||||
@@ -250,7 +268,8 @@ public class ActivateClubMembershipCommandHandler : IRequestHandler<ActivateClub
|
|||||||
CycleNumber = maxCycleNumber + 1,
|
CycleNumber = maxCycleNumber + 1,
|
||||||
PackagePurchasedAt = activationDate,
|
PackagePurchasedAt = activationDate,
|
||||||
PurchaseMethod = user.PackagePurchaseMethod,
|
PurchaseMethod = user.PackagePurchaseMethod,
|
||||||
PackageAmount = SystemConstants.BasePackageAmount,
|
PackageAmount = package.Price,
|
||||||
|
PackageId = package.Id,
|
||||||
IsCurrentCycle = true
|
IsCurrentCycle = true
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -284,15 +303,16 @@ public class ActivateClubMembershipCommandHandler : IRequestHandler<ActivateClub
|
|||||||
// ⭐ 8. اضافه کردن مبلغ به Pool هفته جاری
|
// ⭐ 8. اضافه کردن مبلغ به Pool هفته جاری
|
||||||
var currentWeekDefinitionId = GetCurrentWeekDefinitionId();
|
var currentWeekDefinitionId = GetCurrentWeekDefinitionId();
|
||||||
var weeklyPool = await _context.WeeklyCommissionPools
|
var weeklyPool = await _context.WeeklyCommissionPools
|
||||||
.FirstOrDefaultAsync(p => p.WeekDefinitionId == currentWeekDefinitionId, cancellationToken);
|
.FirstOrDefaultAsync(p => p.WeekDefinitionId == currentWeekDefinitionId && p.PackageId == package.Id, cancellationToken);
|
||||||
|
|
||||||
if (weeklyPool == null)
|
if (weeklyPool == null)
|
||||||
{
|
{
|
||||||
// ایجاد Pool جدید برای این هفته
|
// ایجاد Pool جدید برای این هفته × این پکیج
|
||||||
weeklyPool = new WeeklyCommissionPool
|
weeklyPool = new WeeklyCommissionPool
|
||||||
{
|
{
|
||||||
WeekDefinitionId = currentWeekDefinitionId,
|
WeekDefinitionId = currentWeekDefinitionId,
|
||||||
TotalPoolAmount = activationFeeValue, // مبلغ هدیه به Pool اضافه میشه
|
PackageId = package.Id,
|
||||||
|
TotalPoolAmount = activationFeeValue,
|
||||||
TotalBalances = 0, // در CalculateWeeklyBalances محاسبه میشه
|
TotalBalances = 0, // در CalculateWeeklyBalances محاسبه میشه
|
||||||
ValuePerBalance = 0, // در CalculateWeeklyCommissionPool محاسبه میشه
|
ValuePerBalance = 0, // در CalculateWeeklyCommissionPool محاسبه میشه
|
||||||
IsCalculated = false,
|
IsCalculated = false,
|
||||||
|
|||||||
+9
-5
@@ -82,11 +82,14 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
|||||||
var balancesList = new List<NetworkWeeklyBalance>();
|
var balancesList = new List<NetworkWeeklyBalance>();
|
||||||
var calculatedAt = DateTime.Now;
|
var calculatedAt = DateTime.Now;
|
||||||
|
|
||||||
// استفاده از SystemConstants (استاتیک - بدون کوئری به دیتابیس)
|
// بارگذاری پکیج پایه برای خواندن سقفها
|
||||||
// سقف تعادل هفتگی برای هر دست (نه کل) - 300 برای چپ + 300 برای راست = حداکثر 600 تعادل
|
var package = await _context.Packages
|
||||||
var maxBalancesPerLeg = SystemConstants.CommissionMaxWeeklyBalancesPerLeg;
|
.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken)
|
||||||
// حداکثر عمق شبکه برای شمارش اعضا (15 لول)
|
?? throw new InvalidOperationException("پکیج پایه یافت نشد");
|
||||||
var maxNetworkLevel = SystemConstants.CommissionMaxNetworkLevel;
|
|
||||||
|
// خواندن سقفها از پکیج (قبلاً از SystemConstants بود)
|
||||||
|
var maxBalancesPerLeg = package.MaxBalancesPerLeg;
|
||||||
|
var maxNetworkLevel = package.MaxNetworkLevel;
|
||||||
|
|
||||||
foreach (var user in usersInNetwork.OrderBy(o=>o.Id))
|
foreach (var user in usersInNetwork.OrderBy(o=>o.Id))
|
||||||
{
|
{
|
||||||
@@ -140,6 +143,7 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
|||||||
{
|
{
|
||||||
UserId = user.Id,
|
UserId = user.Id,
|
||||||
WeekDefinitionId = request.WeekDefinitionId,
|
WeekDefinitionId = request.WeekDefinitionId,
|
||||||
|
PackageId = package.Id,
|
||||||
|
|
||||||
// اطلاعات جدید
|
// اطلاعات جدید
|
||||||
LeftLegNewMembers = leftNewMembers,
|
LeftLegNewMembers = leftNewMembers,
|
||||||
|
|||||||
+6
-2
@@ -49,8 +49,11 @@ public class ProcessUserPayoutsCommandHandler : IRequestHandler<ProcessUserPayou
|
|||||||
await _context.SaveChangesAsync(cancellationToken);
|
await _context.SaveChangesAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ⭐ خواندن MaxNetworkLevel از SystemConstants (استاتیک)
|
// بارگذاری پکیج پایه برای خواندن سقفها
|
||||||
var maxNetworkLevel = SystemConstants.CommissionMaxNetworkLevel;
|
var package = await _context.Packages
|
||||||
|
.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken)
|
||||||
|
?? throw new InvalidOperationException("پکیج پایه یافت نشد");
|
||||||
|
var maxNetworkLevel = package.MaxNetworkLevel;
|
||||||
|
|
||||||
// دریافت همه تعادلهای هفتگی (شامل صفرها هم برای محاسبه زیرمجموعه)
|
// دریافت همه تعادلهای هفتگی (شامل صفرها هم برای محاسبه زیرمجموعه)
|
||||||
var allWeeklyBalances = await _context.NetworkWeeklyBalances
|
var allWeeklyBalances = await _context.NetworkWeeklyBalances
|
||||||
@@ -113,6 +116,7 @@ public class ProcessUserPayoutsCommandHandler : IRequestHandler<ProcessUserPayou
|
|||||||
UserId = userId,
|
UserId = userId,
|
||||||
WeekDefinitionId = request.WeekDefinitionId,
|
WeekDefinitionId = request.WeekDefinitionId,
|
||||||
WeeklyPoolId = pool.Id,
|
WeeklyPoolId = pool.Id,
|
||||||
|
PackageId = package.Id,
|
||||||
BalancesEarned = totalBalancesWithSubordinates, // ⭐ شامل زیرمجموعه
|
BalancesEarned = totalBalancesWithSubordinates, // ⭐ شامل زیرمجموعه
|
||||||
ValuePerBalance = pool.ValuePerBalance,
|
ValuePerBalance = pool.ValuePerBalance,
|
||||||
TotalAmount = totalAmount,
|
TotalAmount = totalAmount,
|
||||||
|
|||||||
+20
-24
@@ -186,10 +186,15 @@ public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndPr
|
|||||||
string contractNumber,
|
string contractNumber,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
// بارگذاری پکیج پایه
|
||||||
|
var package = await _context.Packages
|
||||||
|
.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken)
|
||||||
|
?? throw new InvalidOperationException("پکیج پایه یافت نشد");
|
||||||
|
|
||||||
// 1. ایجاد تراکنش
|
// 1. ایجاد تراکنش
|
||||||
var transaction = new Transaction
|
var transaction = new Transaction
|
||||||
{
|
{
|
||||||
Amount = SystemConstants.DayaLoanAmount,
|
Amount = package.Price,
|
||||||
Description = $"دریافت اعتبار دایا - قرارداد {contractNumber}",
|
Description = $"دریافت اعتبار دایا - قرارداد {contractNumber}",
|
||||||
PaymentStatus = PaymentStatus.Success,
|
PaymentStatus = PaymentStatus.Success,
|
||||||
PaymentDate = DateTime.Now,
|
PaymentDate = DateTime.Now,
|
||||||
@@ -216,13 +221,13 @@ public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. شارژ کیف پول عادی
|
// 3. شارژ کیف پول عادی
|
||||||
wallet.Balance += SystemConstants.DayaLoanAmount;
|
wallet.Balance += package.Price;
|
||||||
|
|
||||||
var mainLog = new UserWalletChangeLog
|
var mainLog = new UserWalletChangeLog
|
||||||
{
|
{
|
||||||
WalletId = wallet.Id,
|
WalletId = wallet.Id,
|
||||||
CurrentBalance = 0,
|
CurrentBalance = 0,
|
||||||
ChangeValue = SystemConstants.DayaLoanAmount,
|
ChangeValue = package.Price,
|
||||||
CurrentNetworkBalance = wallet.NetworkBalance,
|
CurrentNetworkBalance = wallet.NetworkBalance,
|
||||||
ChangeNerworkValue = 0,
|
ChangeNerworkValue = 0,
|
||||||
IsIncrease = true,
|
IsIncrease = true,
|
||||||
@@ -230,8 +235,8 @@ public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndPr
|
|||||||
};
|
};
|
||||||
await _context.UserWalletChangeLogs.AddAsync(mainLog, cancellationToken);
|
await _context.UserWalletChangeLogs.AddAsync(mainLog, cancellationToken);
|
||||||
|
|
||||||
// 4. شارژ کیف پول تخفیف (دو برابر)
|
// 4. شارژ کیف پول تخفیف
|
||||||
var discountAmount = SystemConstants.DayaLoanAmount * 2;
|
var discountAmount = (long)(package.Price * package.DiscountMultiplier);
|
||||||
wallet.DiscountBalance += discountAmount;
|
wallet.DiscountBalance += discountAmount;
|
||||||
|
|
||||||
var discountLog = new UserWalletChangeLog
|
var discountLog = new UserWalletChangeLog
|
||||||
@@ -253,27 +258,18 @@ public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndPr
|
|||||||
user.DayaCreditReceivedAt = DateTime.Now;
|
user.DayaCreditReceivedAt = DateTime.Now;
|
||||||
user.PackagePurchaseMethod = PackagePurchaseMethod.DayaLoan;
|
user.PackagePurchaseMethod = PackagePurchaseMethod.DayaLoan;
|
||||||
|
|
||||||
// 6. ثبت Order پکیج پایه
|
// 6. ثبت UserPackagePurchase برای پکیج پایه
|
||||||
var goldenPackage = await _context.Packages
|
var packagePurchase = new UserPackagePurchase
|
||||||
.FirstOrDefaultAsync(p => p.Id == 4, cancellationToken);
|
|
||||||
|
|
||||||
if (goldenPackage != null)
|
|
||||||
{
|
{
|
||||||
// 6. ثبت UserPackagePurchase برای پکیج پایه
|
UserId = user.Id,
|
||||||
var goldenPackageId =goldenPackage.Id;
|
PackageId = package.Id,
|
||||||
var packagePurchase = new UserPackagePurchase
|
PurchaseMethod = PackagePurchaseMethod.DayaLoan,
|
||||||
{
|
PurchasedAt = DateTime.Now,
|
||||||
UserId = user.Id,
|
Amount = package.Price,
|
||||||
PackageId = goldenPackageId,
|
TransactionId = transaction.Id
|
||||||
PurchaseMethod = PackagePurchaseMethod.DayaLoan,
|
};
|
||||||
PurchasedAt = DateTime.Now,
|
|
||||||
Amount = SystemConstants.DayaLoanAmount,
|
|
||||||
TransactionId = transaction.Id
|
|
||||||
};
|
|
||||||
|
|
||||||
await _context.UserPackagePurchases.AddAsync(packagePurchase, cancellationToken);
|
await _context.UserPackagePurchases.AddAsync(packagePurchase, cancellationToken);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. Domain Event
|
// 7. Domain Event
|
||||||
user.AddDomainEvent(new DayaLoanApprovedEvent(user, transaction, contractNumber));
|
user.AddDomainEvent(new DayaLoanApprovedEvent(user, transaction, contractNumber));
|
||||||
|
|||||||
+7
-3
@@ -70,9 +70,13 @@ public class CreateManualPaymentCommandHandler : IRequestHandler<CreateManualPay
|
|||||||
throw new NotFoundException($"کیف پول کاربر {request.UserId} یافت نشد");
|
throw new NotFoundException($"کیف پول کاربر {request.UserId} یافت نشد");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. محاسبه مبالغ
|
// 4. بارگذاری پکیج پایه و محاسبه مبالغ
|
||||||
var balanceAmount = SystemConstants.BasePackageAmount; // 56M
|
var package = await _context.Packages
|
||||||
var discountBalanceAmount = SystemConstants.BasePackageAmount * 2; // 112M
|
.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken)
|
||||||
|
?? throw new NotFoundException("پکیج پایه یافت نشد");
|
||||||
|
|
||||||
|
var balanceAmount = package.Price;
|
||||||
|
var discountBalanceAmount = (long)(package.Price * package.DiscountMultiplier);
|
||||||
|
|
||||||
|
|
||||||
// 5. ثبت تراکنش
|
// 5. ثبت تراکنش
|
||||||
|
|||||||
+13
-11
@@ -20,10 +20,7 @@ public class InitiateBasePackagePaymentCommandHandler : IRequestHandler<Initiate
|
|||||||
private readonly IApplicationDbContext _context;
|
private readonly IApplicationDbContext _context;
|
||||||
private readonly ILogger<InitiateBasePackagePaymentCommandHandler> _logger;
|
private readonly ILogger<InitiateBasePackagePaymentCommandHandler> _logger;
|
||||||
|
|
||||||
/// <summary>
|
// شناسه پکیج پایه از دیتابیس خوانده میشود (Package.IsBasePackage)
|
||||||
/// شناسه پکیج پایه در دیتابیس
|
|
||||||
/// </summary>
|
|
||||||
private const long BasePackageId = 4;
|
|
||||||
|
|
||||||
public InitiateBasePackagePaymentCommandHandler(
|
public InitiateBasePackagePaymentCommandHandler(
|
||||||
IApplicationDbContext context,
|
IApplicationDbContext context,
|
||||||
@@ -68,12 +65,17 @@ public class InitiateBasePackagePaymentCommandHandler : IRequestHandler<Initiate
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2.5. بارگذاری پکیج پایه
|
||||||
|
var package = await _context.Packages
|
||||||
|
.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken)
|
||||||
|
?? throw new NotFoundException("پکیج پایه یافت نشد");
|
||||||
|
|
||||||
// 3. بررسی عدم وجود سفارش Pending
|
// 3. بررسی عدم وجود سفارش Pending
|
||||||
var pendingOrder = await _context.UserOrders
|
var pendingOrder = await _context.UserOrders
|
||||||
.FirstOrDefaultAsync(o =>
|
.FirstOrDefaultAsync(o =>
|
||||||
o.UserId == request.UserId &&
|
o.UserId == request.UserId &&
|
||||||
o.PaymentStatus == PaymentStatus.Pending &&
|
o.PaymentStatus == PaymentStatus.Pending &&
|
||||||
o.PackageId == BasePackageId,
|
o.PackageId == package.Id,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
if (pendingOrder != null)
|
if (pendingOrder != null)
|
||||||
@@ -93,7 +95,7 @@ public class InitiateBasePackagePaymentCommandHandler : IRequestHandler<Initiate
|
|||||||
Message = "سفارش قبلی در انتظار پرداخت یافت شد.",
|
Message = "سفارش قبلی در انتظار پرداخت یافت شد.",
|
||||||
OrderId = pendingOrder.Id,
|
OrderId = pendingOrder.Id,
|
||||||
TransactionId = existingTransaction?.Id ?? 0,
|
TransactionId = existingTransaction?.Id ?? 0,
|
||||||
Amount = SystemConstants.BasePackageAmount
|
Amount = package.Price
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,8 +114,8 @@ public class InitiateBasePackagePaymentCommandHandler : IRequestHandler<Initiate
|
|||||||
// 5. ایجاد Transaction با وضعیت Pending
|
// 5. ایجاد Transaction با وضعیت Pending
|
||||||
var transaction = new Transaction
|
var transaction = new Transaction
|
||||||
{
|
{
|
||||||
Amount = SystemConstants.BasePackageAmount,
|
Amount = package.Price,
|
||||||
Description = $"خرید پکیج پایه ۵۶ میلیونی - کاربر #{user.Id}",
|
Description = $"خرید پکیج {package.Title} - کاربر #{user.Id}",
|
||||||
PaymentStatus = PaymentStatus.Pending,
|
PaymentStatus = PaymentStatus.Pending,
|
||||||
Type = TransactionType.DepositIpg
|
Type = TransactionType.DepositIpg
|
||||||
};
|
};
|
||||||
@@ -130,8 +132,8 @@ public class InitiateBasePackagePaymentCommandHandler : IRequestHandler<Initiate
|
|||||||
var order = new UserOrder
|
var order = new UserOrder
|
||||||
{
|
{
|
||||||
UserId = user.Id,
|
UserId = user.Id,
|
||||||
PackageId = BasePackageId,
|
PackageId = package.Id,
|
||||||
Amount = SystemConstants.BasePackageAmount,
|
Amount = package.Price,
|
||||||
PaymentStatus = PaymentStatus.Pending,
|
PaymentStatus = PaymentStatus.Pending,
|
||||||
DeliveryStatus = DeliveryStatus.None,
|
DeliveryStatus = DeliveryStatus.None,
|
||||||
UserAddressId = defaultAddress.Id,
|
UserAddressId = defaultAddress.Id,
|
||||||
@@ -154,7 +156,7 @@ public class InitiateBasePackagePaymentCommandHandler : IRequestHandler<Initiate
|
|||||||
Message = "تراکنش و سفارش با موفقیت ثبت شد.",
|
Message = "تراکنش و سفارش با موفقیت ثبت شد.",
|
||||||
OrderId = order.Id,
|
OrderId = order.Id,
|
||||||
TransactionId = transaction.Id,
|
TransactionId = transaction.Id,
|
||||||
Amount = SystemConstants.BasePackageAmount
|
Amount = package.Price
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
+13
-5
@@ -128,12 +128,20 @@ public class VerifyBasePackagePaymentCommandHandler : IRequestHandler<VerifyBase
|
|||||||
await _context.SaveChangesAsync(cancellationToken);
|
await _context.SaveChangesAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5.5. بارگذاری پکیج از سفارش
|
||||||
|
var package = order.PackageId.HasValue
|
||||||
|
? await _context.Packages.FirstOrDefaultAsync(p => p.Id == order.PackageId.Value, cancellationToken)
|
||||||
|
: await _context.Packages.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken);
|
||||||
|
|
||||||
|
if (package == null)
|
||||||
|
throw new NotFoundException("پکیج یافت نشد");
|
||||||
|
|
||||||
// 6. شارژ کیف پول (هم Balance و هم DiscountBalance)
|
// 6. شارژ کیف پول (هم Balance و هم DiscountBalance)
|
||||||
var oldBalance = userWallet.Balance;
|
var oldBalance = userWallet.Balance;
|
||||||
var oldDiscountBalance = userWallet.DiscountBalance;
|
var oldDiscountBalance = userWallet.DiscountBalance;
|
||||||
|
|
||||||
userWallet.Balance += SystemConstants.BasePackageAmount;
|
userWallet.Balance += package.Price;
|
||||||
userWallet.DiscountBalance += SystemConstants.BasePackageAmount * 2;
|
userWallet.DiscountBalance += (long)(package.Price * package.DiscountMultiplier);
|
||||||
|
|
||||||
_logger.LogInformation(
|
_logger.LogInformation(
|
||||||
"Charging wallet for user {UserId}. Balance: {OldBalance} -> {NewBalance}, DiscountBalance: {OldDiscount} -> {NewDiscount}",
|
"Charging wallet for user {UserId}. Balance: {OldBalance} -> {NewBalance}, DiscountBalance: {OldDiscount} -> {NewDiscount}",
|
||||||
@@ -153,11 +161,11 @@ public class VerifyBasePackagePaymentCommandHandler : IRequestHandler<VerifyBase
|
|||||||
{
|
{
|
||||||
WalletId = userWallet.Id,
|
WalletId = userWallet.Id,
|
||||||
CurrentBalance = userWallet.Balance,
|
CurrentBalance = userWallet.Balance,
|
||||||
ChangeValue = SystemConstants.BasePackageAmount,
|
ChangeValue = package.Price,
|
||||||
CurrentNetworkBalance = userWallet.NetworkBalance,
|
CurrentNetworkBalance = userWallet.NetworkBalance,
|
||||||
ChangeNerworkValue = 0,
|
ChangeNerworkValue = 0,
|
||||||
CurrentDiscountBalance = userWallet.DiscountBalance,
|
CurrentDiscountBalance = userWallet.DiscountBalance,
|
||||||
ChangeDiscountValue = SystemConstants.BasePackageAmount * 2,
|
ChangeDiscountValue = (long)(package.Price * package.DiscountMultiplier),
|
||||||
IsIncrease = true,
|
IsIncrease = true,
|
||||||
RefrenceId = transaction.Id
|
RefrenceId = transaction.Id
|
||||||
};
|
};
|
||||||
@@ -173,7 +181,7 @@ public class VerifyBasePackagePaymentCommandHandler : IRequestHandler<VerifyBase
|
|||||||
PackageId = order.PackageId.Value,
|
PackageId = order.PackageId.Value,
|
||||||
PurchaseMethod = PackagePurchaseMethod.DirectPurchase,
|
PurchaseMethod = PackagePurchaseMethod.DirectPurchase,
|
||||||
PurchasedAt = DateTime.Now,
|
PurchasedAt = DateTime.Now,
|
||||||
Amount = SystemConstants.BasePackageAmount,
|
Amount = package.Price,
|
||||||
OrderId = order.Id,
|
OrderId = order.Id,
|
||||||
TransactionId = transaction.Id
|
TransactionId = transaction.Id
|
||||||
};
|
};
|
||||||
|
|||||||
+10
-1
@@ -76,8 +76,17 @@ public class ChargeMagicWalletCommandHandler
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3.5. بارگذاری پکیج کاربر برای سقف کیفپول جادویی
|
||||||
|
var currentCycle = await _context.ClubMembershipCycles
|
||||||
|
.FirstOrDefaultAsync(c => c.UserId == request.UserId && c.IsCurrentCycle, cancellationToken);
|
||||||
|
var package = currentCycle != null
|
||||||
|
? await _context.Packages.FirstOrDefaultAsync(p => p.Id == currentCycle.PackageId, cancellationToken)
|
||||||
|
: await _context.Packages.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken);
|
||||||
|
if (package == null)
|
||||||
|
throw new NotFoundException("پکیج یافت نشد");
|
||||||
|
|
||||||
// 4. بررسی سقف واریزی (per-cycle)
|
// 4. بررسی سقف واریزی (per-cycle)
|
||||||
var remainingDeposit = SystemConstants.MagicWalletMaxDeposit - wallet.MagicTotalDeposited;
|
var remainingDeposit = package.MagicWalletMaxDeposit - wallet.MagicTotalDeposited;
|
||||||
|
|
||||||
if (remainingDeposit <= 0)
|
if (remainingDeposit <= 0)
|
||||||
{
|
{
|
||||||
|
|||||||
+14
-5
@@ -121,8 +121,17 @@ public class VerifyMagicWalletChargeCommandHandler
|
|||||||
throw new BadRequestException("کیفپول در حالت جادویی نیست");
|
throw new BadRequestException("کیفپول در حالت جادویی نیست");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. محاسبه اعتبار ×2.5
|
// 4.5. بارگذاری پکیج کاربر برای ضریب جادویی
|
||||||
var creditAmount = (long)(depositAmount * SystemConstants.MagicWalletMultiplier); // مبلغ × 2.5
|
var currentCycle = await _context.ClubMembershipCycles
|
||||||
|
.FirstOrDefaultAsync(c => c.UserId == userId && c.IsCurrentCycle, cancellationToken);
|
||||||
|
var package = currentCycle != null
|
||||||
|
? await _context.Packages.FirstOrDefaultAsync(p => p.Id == currentCycle.PackageId, cancellationToken)
|
||||||
|
: await _context.Packages.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken);
|
||||||
|
if (package == null)
|
||||||
|
throw new NotFoundException("پکیج یافت نشد");
|
||||||
|
|
||||||
|
// 5. محاسبه اعتبار
|
||||||
|
var creditAmount = (long)(depositAmount * package.MagicWalletMultiplier); // مبلغ × 2.5
|
||||||
var bonusAmount = creditAmount - depositAmount; // بونوس = مبلغ × 1.5
|
var bonusAmount = creditAmount - depositAmount; // بونوس = مبلغ × 1.5
|
||||||
|
|
||||||
// 6. ثبت تراکنش واریز واقعی (MagicWalletDeposit)
|
// 6. ثبت تراکنش واریز واقعی (MagicWalletDeposit)
|
||||||
@@ -143,7 +152,7 @@ public class VerifyMagicWalletChargeCommandHandler
|
|||||||
var bonusTransaction = new Transaction
|
var bonusTransaction = new Transaction
|
||||||
{
|
{
|
||||||
Amount = bonusAmount,
|
Amount = bonusAmount,
|
||||||
Description = $"شارژ کیفپول جادویی - بونوس ×{SystemConstants.MagicWalletMultiplier - 1} - کاربر {userId}",
|
Description = $"شارژ کیفپول جادویی - بونوس ×{package.MagicWalletMultiplier - 1} - کاربر {userId}",
|
||||||
PaymentStatus = PaymentStatus.Success,
|
PaymentStatus = PaymentStatus.Success,
|
||||||
PaymentDate = DateTime.UtcNow,
|
PaymentDate = DateTime.UtcNow,
|
||||||
RefId = $"MAGIC_BONUS_{depositTransaction.Id}",
|
RefId = $"MAGIC_BONUS_{depositTransaction.Id}",
|
||||||
@@ -186,10 +195,10 @@ public class VerifyMagicWalletChargeCommandHandler
|
|||||||
userId,
|
userId,
|
||||||
depositAmount,
|
depositAmount,
|
||||||
creditAmount,
|
creditAmount,
|
||||||
SystemConstants.MagicWalletMultiplier,
|
package.MagicWalletMultiplier,
|
||||||
bonusAmount,
|
bonusAmount,
|
||||||
wallet.MagicTotalDeposited,
|
wallet.MagicTotalDeposited,
|
||||||
SystemConstants.MagicWalletMaxDeposit,
|
package.MagicWalletMaxDeposit,
|
||||||
wallet.Balance
|
wallet.Balance
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
+13
-3
@@ -94,9 +94,12 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
|
|||||||
var balancesList = new List<NetworkWeeklyBalance>();
|
var balancesList = new List<NetworkWeeklyBalance>();
|
||||||
var calculatedAt = DateTime.Now;
|
var calculatedAt = DateTime.Now;
|
||||||
|
|
||||||
// استفاده از SystemConstants به جای دیتابیس
|
// بارگذاری پکیج پایه برای خواندن سقفها
|
||||||
var maxBalancesPerLeg = SystemConstants.CommissionMaxWeeklyBalancesPerLeg;
|
var package = await _context.Packages
|
||||||
var maxNetworkLevel = SystemConstants.CommissionMaxNetworkLevel;
|
.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken)
|
||||||
|
?? throw new InvalidOperationException("پکیج پایه یافت نشد");
|
||||||
|
var maxBalancesPerLeg = package.MaxBalancesPerLeg;
|
||||||
|
var maxNetworkLevel = package.MaxNetworkLevel;
|
||||||
|
|
||||||
foreach (var user in usersInNetwork.OrderBy(o => o.Id))
|
foreach (var user in usersInNetwork.OrderBy(o => o.Id))
|
||||||
{
|
{
|
||||||
@@ -135,6 +138,7 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
|
|||||||
{
|
{
|
||||||
UserId = user.Id,
|
UserId = user.Id,
|
||||||
WeekDefinitionId = weekDefinitionId,
|
WeekDefinitionId = weekDefinitionId,
|
||||||
|
PackageId = package.Id,
|
||||||
LeftLegNewMembers = leftNewMembers,
|
LeftLegNewMembers = leftNewMembers,
|
||||||
RightLegNewMembers = rightNewMembers,
|
RightLegNewMembers = rightNewMembers,
|
||||||
LeftLegCarryover = leftCarryover,
|
LeftLegCarryover = leftCarryover,
|
||||||
@@ -189,6 +193,11 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
|
|||||||
bool forceRecalculate,
|
bool forceRecalculate,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
|
// بارگذاری پکیج پایه برای تعیین PackageId روی پرداختها
|
||||||
|
var package = await _context.Packages
|
||||||
|
.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken)
|
||||||
|
?? throw new InvalidOperationException("پکیج پایه یافت نشد");
|
||||||
|
|
||||||
var weekDefinition = _weekRepository.GetGregorianWeekNumber(weekDefinitionId);
|
var weekDefinition = _weekRepository.GetGregorianWeekNumber(weekDefinitionId);
|
||||||
if (weekDefinition == null)
|
if (weekDefinition == null)
|
||||||
{
|
{
|
||||||
@@ -284,6 +293,7 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
|
|||||||
UserId = balance.UserId,
|
UserId = balance.UserId,
|
||||||
WeekDefinitionId = weekDefinitionId,
|
WeekDefinitionId = weekDefinitionId,
|
||||||
WeeklyPoolId = existingPool.Id,
|
WeeklyPoolId = existingPool.Id,
|
||||||
|
PackageId = package.Id,
|
||||||
BalancesEarned = userBalance,
|
BalancesEarned = userBalance,
|
||||||
ValuePerBalance = valuePerBalance,
|
ValuePerBalance = valuePerBalance,
|
||||||
TotalAmount = totalAmount,
|
TotalAmount = totalAmount,
|
||||||
|
|||||||
@@ -2,37 +2,42 @@ using CMSMicroservice.Application.ClubFeatureCQ.Queries.GetUserClubFeatures;
|
|||||||
using CMSMicroservice.Application.Common.Authorization;
|
using CMSMicroservice.Application.Common.Authorization;
|
||||||
using CMSMicroservice.Application.Common.Interfaces;
|
using CMSMicroservice.Application.Common.Interfaces;
|
||||||
using CMSMicroservice.Domain.Common;
|
using CMSMicroservice.Domain.Common;
|
||||||
|
using CMSMicroservice.Domain.Entities;
|
||||||
using CMSMicroservice.Protobuf.Protos.Configuration;
|
using CMSMicroservice.Protobuf.Protos.Configuration;
|
||||||
using Google.Protobuf.WellKnownTypes;
|
using Google.Protobuf.WellKnownTypes;
|
||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace CMSMicroservice.WebApi.Services;
|
namespace CMSMicroservice.WebApi.Services;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// سرویس تنظیمات سیستم - خواندن از SystemConstants
|
/// سرویس تنظیمات سیستم — مقادیر پکیجی از Package entity خوانده میشوند
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ConfigurationService : ConfigurationContract.ConfigurationContractBase
|
public class ConfigurationService : ConfigurationContract.ConfigurationContractBase
|
||||||
{
|
{
|
||||||
private readonly ILogger<ConfigurationService> _logger;
|
private readonly ILogger<ConfigurationService> _logger;
|
||||||
private readonly ICurrentUserService _currentUserService;
|
private readonly ICurrentUserService _currentUserService;
|
||||||
private readonly IMediator _mediator;
|
private readonly IMediator _mediator;
|
||||||
|
private readonly IApplicationDbContext _context;
|
||||||
|
|
||||||
public ConfigurationService(
|
public ConfigurationService(
|
||||||
ILogger<ConfigurationService> logger,
|
ILogger<ConfigurationService> logger,
|
||||||
ICurrentUserService currentUserService,
|
ICurrentUserService currentUserService,
|
||||||
IMediator mediator)
|
IMediator mediator,
|
||||||
|
IApplicationDbContext context)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_currentUserService = currentUserService;
|
_currentUserService = currentUserService;
|
||||||
_mediator = mediator;
|
_mediator = mediator;
|
||||||
|
_context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// دریافت تنظیمات با کلید خاص
|
/// دریافت تنظیمات با کلید خاص
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override Task<GetConfigurationByKeyResponse> GetConfigurationByKey(GetConfigurationByKeyRequest request, ServerCallContext context)
|
public override async Task<GetConfigurationByKeyResponse> GetConfigurationByKey(GetConfigurationByKeyRequest request, ServerCallContext context)
|
||||||
{
|
{
|
||||||
var response = new GetConfigurationByKeyResponse
|
var response = new GetConfigurationByKeyResponse
|
||||||
{
|
{
|
||||||
@@ -43,30 +48,33 @@ public class ConfigurationService : ConfigurationContract.ConfigurationContractB
|
|||||||
LastModified = Timestamp.FromDateTime(DateTime.UtcNow)
|
LastModified = Timestamp.FromDateTime(DateTime.UtcNow)
|
||||||
};
|
};
|
||||||
|
|
||||||
// خواندن مقدار از SystemConstants بر اساس کلید
|
// برای کلیدهای پکیجی، از دیتابیس میخوانیم
|
||||||
response.Value = GetConfigurationValue(request.Key);
|
var package = await GetBasePackageAsync(context.CancellationToken);
|
||||||
|
response.Value = GetConfigurationValue(request.Key, package);
|
||||||
response.Description = GetConfigurationDescription(request.Key);
|
response.Description = GetConfigurationDescription(request.Key);
|
||||||
|
|
||||||
_logger.LogDebug("Configuration requested: Key={Key}, Value={Value}", request.Key, response.Value);
|
_logger.LogDebug("Configuration requested: Key={Key}, Value={Value}", request.Key, response.Value);
|
||||||
|
|
||||||
return Task.FromResult(response);
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// دریافت تنظیمات باشگاه مشتریان
|
/// دریافت تنظیمات باشگاه مشتریان
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override Task<GetClubConfigurationResponse> GetClubConfiguration(Empty request, ServerCallContext context)
|
public override async Task<GetClubConfigurationResponse> GetClubConfiguration(Empty request, ServerCallContext context)
|
||||||
{
|
{
|
||||||
|
var package = await GetBasePackageAsync(context.CancellationToken);
|
||||||
|
|
||||||
var response = new GetClubConfigurationResponse
|
var response = new GetClubConfigurationResponse
|
||||||
{
|
{
|
||||||
ActivationFee = SystemConstants.ClubActivationFee,
|
ActivationFee = package.ActivationFee,
|
||||||
MembershipGiftValue = SystemConstants.ClubMembershipGiftValue
|
MembershipGiftValue = package.ActivationFee
|
||||||
};
|
};
|
||||||
|
|
||||||
_logger.LogDebug("Club configuration requested: ActivationFee={ActivationFee}, GiftValue={GiftValue}",
|
_logger.LogDebug("Club configuration requested: ActivationFee={ActivationFee}, GiftValue={GiftValue}",
|
||||||
response.ActivationFee, response.MembershipGiftValue);
|
response.ActivationFee, response.MembershipGiftValue);
|
||||||
|
|
||||||
return Task.FromResult(response);
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -111,18 +119,19 @@ public class ConfigurationService : ConfigurationContract.ConfigurationContractB
|
|||||||
/// دریافت تمام تنظیمات
|
/// دریافت تمام تنظیمات
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RequiresPermission(PermissionNames.SettingsView)]
|
[RequiresPermission(PermissionNames.SettingsView)]
|
||||||
public override Task<GetAllConfigurationsResponse> GetAllConfigurations(GetAllConfigurationsRequest request, ServerCallContext context)
|
public override async Task<GetAllConfigurationsResponse> GetAllConfigurations(GetAllConfigurationsRequest request, ServerCallContext context)
|
||||||
{
|
{
|
||||||
|
var package = await GetBasePackageAsync(context.CancellationToken);
|
||||||
var response = new GetAllConfigurationsResponse();
|
var response = new GetAllConfigurationsResponse();
|
||||||
|
|
||||||
// Club Settings
|
// Club Settings (از Package)
|
||||||
response.Models.Add(CreateConfigModel("Club.ActivationFee", SystemConstants.ClubActivationFee.ToString(), "هزینه فعالسازی عضویت باشگاه", 2));
|
response.Models.Add(CreateConfigModel("Club.ActivationFee", package.ActivationFee.ToString(), "هزینه فعالسازی عضویت باشگاه", 2));
|
||||||
response.Models.Add(CreateConfigModel("Club.MembershipGiftValue", SystemConstants.ClubMembershipGiftValue.ToString(), "مبلغ هدیه حق عضویت باشگاه", 2));
|
response.Models.Add(CreateConfigModel("Club.MembershipGiftValue", package.ActivationFee.ToString(), "مبلغ هدیه حق عضویت باشگاه", 2));
|
||||||
|
|
||||||
// Commission Settings
|
// Commission Settings (سقفها از Package)
|
||||||
response.Models.Add(CreateConfigModel("Commission.MinWithdrawalAmount", SystemConstants.CommissionMinWithdrawalAmount.ToString(), "حداقل مبلغ برداشت", 3));
|
response.Models.Add(CreateConfigModel("Commission.MinWithdrawalAmount", SystemConstants.CommissionMinWithdrawalAmount.ToString(), "حداقل مبلغ برداشت", 3));
|
||||||
response.Models.Add(CreateConfigModel("Commission.MaxWeeklyBalancesPerLeg", SystemConstants.CommissionMaxWeeklyBalancesPerLeg.ToString(), "سقف تعادل هفتگی برای هر دست", 3));
|
response.Models.Add(CreateConfigModel("Commission.MaxWeeklyBalancesPerLeg", package.MaxBalancesPerLeg.ToString(), "سقف تعادل هفتگی برای هر دست", 3));
|
||||||
response.Models.Add(CreateConfigModel("Commission.MaxNetworkLevel", SystemConstants.CommissionMaxNetworkLevel.ToString(), "حداکثر عمق شبکه برای محاسبه کمیسیون", 3));
|
response.Models.Add(CreateConfigModel("Commission.MaxNetworkLevel", package.MaxNetworkLevel.ToString(), "حداکثر عمق شبکه برای محاسبه کمیسیون", 3));
|
||||||
response.Models.Add(CreateConfigModel("Commission.CashWithdrawalEnabled", SystemConstants.CommissionCashWithdrawalEnabled.ToString(), "امکان برداشت نقدی", 3));
|
response.Models.Add(CreateConfigModel("Commission.CashWithdrawalEnabled", SystemConstants.CommissionCashWithdrawalEnabled.ToString(), "امکان برداشت نقدی", 3));
|
||||||
response.Models.Add(CreateConfigModel("Commission.CalculationStrategy", SystemConstants.CommissionCalculationStrategy, "روش محاسبه کمیسیون", 3));
|
response.Models.Add(CreateConfigModel("Commission.CalculationStrategy", SystemConstants.CommissionCalculationStrategy, "روش محاسبه کمیسیون", 3));
|
||||||
|
|
||||||
@@ -130,9 +139,9 @@ public class ConfigurationService : ConfigurationContract.ConfigurationContractB
|
|||||||
response.Models.Add(CreateConfigModel("Network.AllowOrphanNodes", SystemConstants.NetworkAllowOrphanNodes.ToString(), "اجازه حذف والدین با فرزند", 1));
|
response.Models.Add(CreateConfigModel("Network.AllowOrphanNodes", SystemConstants.NetworkAllowOrphanNodes.ToString(), "اجازه حذف والدین با فرزند", 1));
|
||||||
response.Models.Add(CreateConfigModel("Network.MaxChildrenPerLeg", SystemConstants.NetworkMaxChildrenPerLeg.ToString(), "حداکثر تعداد فرزند مستقیم در هر پا", 1));
|
response.Models.Add(CreateConfigModel("Network.MaxChildrenPerLeg", SystemConstants.NetworkMaxChildrenPerLeg.ToString(), "حداکثر تعداد فرزند مستقیم در هر پا", 1));
|
||||||
|
|
||||||
// Package Settings
|
// Package Settings (از Package)
|
||||||
response.Models.Add(CreateConfigModel("Package.BasePackageAmount", SystemConstants.BasePackageAmount.ToString(), "مبلغ پکیج پایه", 0));
|
response.Models.Add(CreateConfigModel("Package.BasePackageAmount", package.Price.ToString(), "مبلغ پکیج پایه", 0));
|
||||||
response.Models.Add(CreateConfigModel("Package.DayaLoanAmount", SystemConstants.DayaLoanAmount.ToString(), "مبلغ وام دایا", 0));
|
response.Models.Add(CreateConfigModel("Package.DayaLoanAmount", package.Price.ToString(), "مبلغ وام دایا", 0));
|
||||||
|
|
||||||
// System Settings
|
// System Settings
|
||||||
response.Models.Add(CreateConfigModel("System.MaintenanceMode", SystemConstants.SystemMaintenanceMode.ToString(), "حالت تعمیر و نگهداری", 0));
|
response.Models.Add(CreateConfigModel("System.MaintenanceMode", SystemConstants.SystemMaintenanceMode.ToString(), "حالت تعمیر و نگهداری", 0));
|
||||||
@@ -141,7 +150,7 @@ public class ConfigurationService : ConfigurationContract.ConfigurationContractB
|
|||||||
// Shop Settings
|
// Shop Settings
|
||||||
response.Models.Add(CreateConfigModel("Shop.VAT", SystemConstants.ShopVAT.ToString(), "مالیات بر ارزش افزوده", 0));
|
response.Models.Add(CreateConfigModel("Shop.VAT", SystemConstants.ShopVAT.ToString(), "مالیات بر ارزش افزوده", 0));
|
||||||
|
|
||||||
return Task.FromResult(response);
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -173,21 +182,21 @@ public class ConfigurationService : ConfigurationContract.ConfigurationContractB
|
|||||||
|
|
||||||
#region Private Helpers
|
#region Private Helpers
|
||||||
|
|
||||||
private static string GetConfigurationValue(string key)
|
private static string GetConfigurationValue(string key, Package? package)
|
||||||
{
|
{
|
||||||
return key switch
|
return key switch
|
||||||
{
|
{
|
||||||
"Club.ActivationFee" => SystemConstants.ClubActivationFee.ToString(),
|
"Club.ActivationFee" => (package?.ActivationFee ?? 0).ToString(),
|
||||||
"Club.MembershipGiftValue" => SystemConstants.ClubMembershipGiftValue.ToString(),
|
"Club.MembershipGiftValue" => (package?.ActivationFee ?? 0).ToString(),
|
||||||
"Commission.MinWithdrawalAmount" => SystemConstants.CommissionMinWithdrawalAmount.ToString(),
|
"Commission.MinWithdrawalAmount" => SystemConstants.CommissionMinWithdrawalAmount.ToString(),
|
||||||
"Commission.MaxWeeklyBalancesPerLeg" => SystemConstants.CommissionMaxWeeklyBalancesPerLeg.ToString(),
|
"Commission.MaxWeeklyBalancesPerLeg" => (package?.MaxBalancesPerLeg ?? 0).ToString(),
|
||||||
"Commission.MaxNetworkLevel" => SystemConstants.CommissionMaxNetworkLevel.ToString(),
|
"Commission.MaxNetworkLevel" => (package?.MaxNetworkLevel ?? 0).ToString(),
|
||||||
"Commission.CashWithdrawalEnabled" => SystemConstants.CommissionCashWithdrawalEnabled.ToString(),
|
"Commission.CashWithdrawalEnabled" => SystemConstants.CommissionCashWithdrawalEnabled.ToString(),
|
||||||
"Commission.CalculationStrategy" => SystemConstants.CommissionCalculationStrategy,
|
"Commission.CalculationStrategy" => SystemConstants.CommissionCalculationStrategy,
|
||||||
"Network.AllowOrphanNodes" => SystemConstants.NetworkAllowOrphanNodes.ToString(),
|
"Network.AllowOrphanNodes" => SystemConstants.NetworkAllowOrphanNodes.ToString(),
|
||||||
"Network.MaxChildrenPerLeg" => SystemConstants.NetworkMaxChildrenPerLeg.ToString(),
|
"Network.MaxChildrenPerLeg" => SystemConstants.NetworkMaxChildrenPerLeg.ToString(),
|
||||||
"Package.BasePackageAmount" => SystemConstants.BasePackageAmount.ToString(),
|
"Package.BasePackageAmount" => (package?.Price ?? 0).ToString(),
|
||||||
"Package.DayaLoanAmount" => SystemConstants.DayaLoanAmount.ToString(),
|
"Package.DayaLoanAmount" => (package?.Price ?? 0).ToString(),
|
||||||
"System.MaintenanceMode" => SystemConstants.SystemMaintenanceMode.ToString(),
|
"System.MaintenanceMode" => SystemConstants.SystemMaintenanceMode.ToString(),
|
||||||
"System.EnableAuditLog" => SystemConstants.SystemEnableAuditLog.ToString(),
|
"System.EnableAuditLog" => SystemConstants.SystemEnableAuditLog.ToString(),
|
||||||
"Shop.VAT" => SystemConstants.ShopVAT.ToString(),
|
"Shop.VAT" => SystemConstants.ShopVAT.ToString(),
|
||||||
@@ -195,6 +204,13 @@ public class ConfigurationService : ConfigurationContract.ConfigurationContractB
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<Package> GetBasePackageAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return await _context.Packages
|
||||||
|
.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken)
|
||||||
|
?? throw new RpcException(new Status(StatusCode.Internal, "پکیج پایه یافت نشد"));
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetConfigurationDescription(string key)
|
private static string GetConfigurationDescription(string key)
|
||||||
{
|
{
|
||||||
return key switch
|
return key switch
|
||||||
|
|||||||
@@ -344,9 +344,18 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
|
|||||||
.Include(u => u.ClubMembership)
|
.Include(u => u.ClubMembership)
|
||||||
.FirstOrDefaultAsync(u => u.Id == userId, context.CancellationToken);
|
.FirstOrDefaultAsync(u => u.Id == userId, context.CancellationToken);
|
||||||
|
|
||||||
if (wallet.WalletMode == WalletMode.Magic
|
if (wallet.WalletMode == WalletMode.Magic)
|
||||||
&& wallet.MagicTotalDeposited >= SystemConstants.MagicWalletMaxDeposit)
|
|
||||||
{
|
{
|
||||||
|
// بارگذاری پکیج کاربر برای سقف کیفپول جادویی
|
||||||
|
var userCycle = await _context.ClubMembershipCycles
|
||||||
|
.FirstOrDefaultAsync(c => c.UserId == userId && c.IsCurrentCycle, context.CancellationToken);
|
||||||
|
var userPackage = userCycle != null
|
||||||
|
? await _context.Packages.FirstOrDefaultAsync(p => p.Id == userCycle.PackageId, context.CancellationToken)
|
||||||
|
: await _context.Packages.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, context.CancellationToken);
|
||||||
|
var magicMaxDeposit = userPackage?.MagicWalletMaxDeposit ?? 1_000_000_000;
|
||||||
|
|
||||||
|
if (wallet.MagicTotalDeposited >= magicMaxDeposit)
|
||||||
|
{
|
||||||
// ── EXIT Magic Mode ──
|
// ── EXIT Magic Mode ──
|
||||||
// هر دو شرط: Balance=0 و سقف 100M پر شده
|
// هر دو شرط: Balance=0 و سقف 100M پر شده
|
||||||
wallet.WalletMode = WalletMode.Normal;
|
wallet.WalletMode = WalletMode.Normal;
|
||||||
@@ -366,6 +375,7 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
|
|||||||
{
|
{
|
||||||
user.PackagePurchaseMethod = PackagePurchaseMethod.None;
|
user.PackagePurchaseMethod = PackagePurchaseMethod.None;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (wallet.WalletMode == WalletMode.Normal
|
else if (wallet.WalletMode == WalletMode.Normal
|
||||||
&& user != null
|
&& user != null
|
||||||
|
|||||||
@@ -227,13 +227,21 @@ public class UserWalletService : UserWalletContract.UserWalletContractBase
|
|||||||
var cycleCount = await _context.ClubMembershipCycles
|
var cycleCount = await _context.ClubMembershipCycles
|
||||||
.CountAsync(c => c.UserId == userId, context.CancellationToken);
|
.CountAsync(c => c.UserId == userId, context.CancellationToken);
|
||||||
|
|
||||||
|
// بارگذاری پکیج کاربر برای سقف کیفپول جادویی
|
||||||
|
var currentCycle = await _context.ClubMembershipCycles
|
||||||
|
.FirstOrDefaultAsync(c => c.UserId == userId && c.IsCurrentCycle, context.CancellationToken);
|
||||||
|
var package = currentCycle != null
|
||||||
|
? await _context.Packages.FirstOrDefaultAsync(p => p.Id == currentCycle.PackageId, context.CancellationToken)
|
||||||
|
: await _context.Packages.FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, context.CancellationToken);
|
||||||
|
var magicMaxDeposit = package?.MagicWalletMaxDeposit ?? 1_000_000_000;
|
||||||
|
|
||||||
var response = new GetMagicWalletStatusResponse
|
var response = new GetMagicWalletStatusResponse
|
||||||
{
|
{
|
||||||
WalletMode = (int)wallet.WalletMode,
|
WalletMode = (int)wallet.WalletMode,
|
||||||
MagicTotalDeposited = wallet.MagicTotalDeposited,
|
MagicTotalDeposited = wallet.MagicTotalDeposited,
|
||||||
MagicTotalCredited = wallet.MagicTotalCredited,
|
MagicTotalCredited = wallet.MagicTotalCredited,
|
||||||
MagicMaxDeposit = SystemConstants.MagicWalletMaxDeposit,
|
MagicMaxDeposit = magicMaxDeposit,
|
||||||
MagicRemainingDeposit = Math.Max(0, SystemConstants.MagicWalletMaxDeposit - wallet.MagicTotalDeposited),
|
MagicRemainingDeposit = Math.Max(0, magicMaxDeposit - wallet.MagicTotalDeposited),
|
||||||
Balance = wallet.Balance,
|
Balance = wallet.Balance,
|
||||||
PurchaseCycleCount = cycleCount
|
PurchaseCycleCount = cycleCount
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user