F2-F7: نوتیفیکیشنها+نامپکیج، ستون پکیج در CSV، مقادیر داینامیک کیفپول جادویی، ولیدیتور SystemConstants
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 8m29s
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 8m29s
F2: اضافه شدن packageName به SmsTemplates، IUserNotificationService، UserNotificationService
- DayaLoan، ClubActivated، CommissionDeposited حالا نام پکیج را نشان میدهند
F4: اضافه شدن ستون پکیج به CSV خروجیها
- commission.proto: package_name در WithdrawalRequestModel
- manualpayment.proto: package_name در ManualPaymentModel
- کوئریهندلرها UserPackagePurchases لوکاپ اضافه شد
F6: مقادیر داینامیک کیفپول جادویی از پکیج
- userwallet.proto: magic_multiplier + magic_max_credit
- UserWalletService: پاپیولیت فیلدهای جدید + فالبک به SystemConstants
F7: ولیدیتورها از SystemConstants استفاده میکنند
- WalletMaxSafeAmount (10B ریال) به عنوان حصار ایمنی
- MagicWalletMinCharge، DiscountWalletMinCharge ثابتهای مرکزی
- سقف واقعی per-package در هندلرها اعمال میشود
Proto: v0.0.189
This commit is contained in:
+11
-1
@@ -51,6 +51,15 @@ public class GetWithdrawalRequestsQueryHandler : IRequestHandler<GetWithdrawalRe
|
||||
.PaginatedListAsync(paginationState: request.PaginationState)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
// دریافت PackageName از آخرین خرید پکیج کاربران
|
||||
var userIds = models.Select(x => x.UserId).Distinct().ToList();
|
||||
var userPackageNames = await _context.UserPackagePurchases
|
||||
.Where(p => userIds.Contains(p.UserId))
|
||||
.Include(p => p.Package)
|
||||
.GroupBy(p => p.UserId)
|
||||
.Select(g => new { UserId = g.Key, PackageName = g.OrderByDescending(x => x.PurchasedAt).First().Package.Title })
|
||||
.ToDictionaryAsync(x => x.UserId, x => x.PackageName, cancellationToken);
|
||||
|
||||
var result = models.Select(x => new WithdrawalRequestModel
|
||||
{
|
||||
Id = x.Id,
|
||||
@@ -69,7 +78,8 @@ public class GetWithdrawalRequestsQueryHandler : IRequestHandler<GetWithdrawalRe
|
||||
BankReferenceId = x.BankReferenceId,
|
||||
BankTrackingCode = x.BankTrackingCode,
|
||||
PaymentFailureReason = x.PaymentFailureReason,
|
||||
Created = x.Created
|
||||
Created = x.Created,
|
||||
PackageName = userPackageNames.GetValueOrDefault(x.UserId)
|
||||
}).ToList();
|
||||
|
||||
return new GetWithdrawalRequestsResponseDto
|
||||
|
||||
+1
@@ -25,4 +25,5 @@ public class WithdrawalRequestModel
|
||||
public string? BankTrackingCode { get; set; }
|
||||
public string? PaymentFailureReason { get; set; }
|
||||
public DateTime Created { get; set; }
|
||||
public string? PackageName { get; set; }
|
||||
}
|
||||
|
||||
@@ -34,14 +34,16 @@ public interface IUserNotificationService
|
||||
Task SendCommissionReceivedNotificationAsync(
|
||||
long userId,
|
||||
decimal amount,
|
||||
int weekNumber,
|
||||
int weekNumber,
|
||||
string? packageName = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// ارسال اعلان فعالسازی عضویت باشگاه
|
||||
/// </summary>
|
||||
Task SendClubActivationNotificationAsync(
|
||||
long userId,
|
||||
long userId,
|
||||
string? packageName = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
@@ -49,6 +51,7 @@ public interface IUserNotificationService
|
||||
/// </summary>
|
||||
Task SendPayoutErrorNotificationAsync(
|
||||
long userId,
|
||||
string errorMessage,
|
||||
string errorMessage,
|
||||
string? packageName = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
+7
-6
@@ -122,6 +122,7 @@ public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndPr
|
||||
contract.IsProcessed = true;
|
||||
result.WasProcessed = true;
|
||||
result.NewWalletBalance = processResult.NewBalance;
|
||||
result.PackageName = processResult.PackageName;
|
||||
result.Message = "وام پردازش و کیف پول شارژ شد";
|
||||
processedCount++;
|
||||
|
||||
@@ -181,7 +182,7 @@ public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndPr
|
||||
/// <summary>
|
||||
/// پردازش مالی وام دایا
|
||||
/// </summary>
|
||||
private async Task<(long NewBalance, long TransactionId)> ProcessDayaLoanAsync(
|
||||
private async Task<(long NewBalance, long TransactionId, string PackageName)> ProcessDayaLoanAsync(
|
||||
User user,
|
||||
string contractNumber,
|
||||
CancellationToken cancellationToken)
|
||||
@@ -279,25 +280,25 @@ public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndPr
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// 8. ارسال SMS
|
||||
await SendDayaLoanSmsAsync(user);
|
||||
await SendDayaLoanSmsAsync(user, package.Title);
|
||||
|
||||
return (wallet.Balance, transaction.Id);
|
||||
return (wallet.Balance, transaction.Id, package.Title);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ارسال SMS اطلاعرسانی
|
||||
/// </summary>
|
||||
private async Task SendDayaLoanSmsAsync(User user)
|
||||
private async Task SendDayaLoanSmsAsync(User user, string packageName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var userName = SmsTemplates.GetUserName(user.FirstName+" "+user.LastName);
|
||||
var message = SmsTemplates.DayaLoanReceived(userName);
|
||||
var message = SmsTemplates.DayaLoanReceived(userName, packageName);
|
||||
|
||||
await _smsService.SendAsync(user.Mobile, message);
|
||||
|
||||
// ارسال SMS به ادمین برای اطلاع
|
||||
var adminMessage = $"وام دایا دریافت شد\nکاربر: {user.FirstName} {user.LastName}\nموبایل: {user.Mobile}\nکدملی: {user.NationalCode}";
|
||||
var adminMessage = $"وام دایا دریافت شد\nکاربر: {user.FirstName} {user.LastName}\nموبایل: {user.Mobile}\nکدملی: {user.NationalCode}\nپکیج: {packageName}";
|
||||
await _smsService.SendAsync("09199877503", adminMessage);
|
||||
|
||||
_logger.LogInformation("Daya loan SMS sent to User {UserId}", user.Id);
|
||||
|
||||
+5
@@ -63,6 +63,11 @@ public class DayaLoanProcessResult
|
||||
/// </summary>
|
||||
public long? NewWalletBalance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// نام پکیج
|
||||
/// </summary>
|
||||
public string? PackageName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// پیام
|
||||
/// </summary>
|
||||
|
||||
+4
-2
@@ -1,3 +1,4 @@
|
||||
using CMSMicroservice.Domain.Common;
|
||||
using FluentValidation;
|
||||
|
||||
namespace CMSMicroservice.Application.ManualPaymentCQ.Commands.CreateManualPayment;
|
||||
@@ -10,11 +11,12 @@ public class CreateManualPaymentCommandValidator : AbstractValidator<CreateManua
|
||||
.GreaterThan(0)
|
||||
.WithMessage("شناسه کاربر باید بزرگتر از صفر باشد");
|
||||
|
||||
// حصار ایمنی — مبلغ واقعی از پکیج کاربر خوانده میشود
|
||||
RuleFor(x => x.Amount)
|
||||
.GreaterThan(0)
|
||||
.WithMessage("مبلغ باید بزرگتر از صفر باشد")
|
||||
.LessThanOrEqualTo(1_000_000_000)
|
||||
.WithMessage("مبلغ نمیتواند بیشتر از 1 میلیارد ریال باشد");
|
||||
.LessThanOrEqualTo(SystemConstants.WalletMaxSafeAmount)
|
||||
.WithMessage("مبلغ وارد شده بیش از حد مجاز است");
|
||||
|
||||
RuleFor(x => x.Type)
|
||||
.IsInEnum()
|
||||
|
||||
+15
@@ -69,6 +69,14 @@ public class GetAllManualPaymentsQueryHandler
|
||||
|
||||
// Pagination
|
||||
var skip = (request.PageNumber - 1) * request.PageSize;
|
||||
|
||||
// دریافت PackageName از آخرین خرید پکیج کاربر
|
||||
var userPackageNames = await _context.UserPackagePurchases
|
||||
.Include(p => p.Package)
|
||||
.GroupBy(p => p.UserId)
|
||||
.Select(g => new { UserId = g.Key, PackageName = g.OrderByDescending(x => x.PurchasedAt).First().Package.Title })
|
||||
.ToDictionaryAsync(x => x.UserId, x => x.PackageName, cancellationToken);
|
||||
|
||||
var data = await query
|
||||
.Skip(skip)
|
||||
.Take(request.PageSize)
|
||||
@@ -95,6 +103,13 @@ public class GetAllManualPaymentsQueryHandler
|
||||
Created = m.Created
|
||||
})
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
// تکمیل PackageName
|
||||
foreach (var item in data)
|
||||
{
|
||||
if (userPackageNames.TryGetValue(item.UserId, out var pkgName))
|
||||
item.PackageName = pkgName;
|
||||
}
|
||||
|
||||
var metaData = new MetaData
|
||||
{
|
||||
|
||||
+1
@@ -30,4 +30,5 @@ public class ManualPaymentDto
|
||||
public string? RejectionReason { get; set; }
|
||||
public long? TransactionId { get; set; }
|
||||
public DateTime Created { get; set; }
|
||||
public string? PackageName { get; set; }
|
||||
}
|
||||
|
||||
+6
-4
@@ -1,3 +1,4 @@
|
||||
using CMSMicroservice.Domain.Common;
|
||||
using FluentValidation;
|
||||
|
||||
namespace CMSMicroservice.Application.WalletCQ.Commands.ChargeDiscountWallet;
|
||||
@@ -10,10 +11,11 @@ public class ChargeDiscountWalletCommandValidator : AbstractValidator<ChargeDisc
|
||||
.GreaterThan(0)
|
||||
.WithMessage("شناسه کاربر باید بزرگتر از صفر باشد");
|
||||
|
||||
// حصار ایمنی — سقف تخفیفی فعلاً سراسری است
|
||||
RuleFor(x => x.Amount)
|
||||
.GreaterThanOrEqualTo(10_000)
|
||||
.WithMessage("حداقل مبلغ شارژ 10,000 تومان است")
|
||||
.LessThanOrEqualTo(1_000_000_000)
|
||||
.WithMessage("حداکثر مبلغ شارژ 1,000,000,000 تومان است");
|
||||
.GreaterThanOrEqualTo(SystemConstants.DiscountWalletMinCharge)
|
||||
.WithMessage("حداقل مبلغ شارژ ۱,۰۰۰ تومان است")
|
||||
.LessThanOrEqualTo(SystemConstants.WalletMaxSafeAmount)
|
||||
.WithMessage("مبلغ وارد شده بیش از حد مجاز است");
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -1,3 +1,4 @@
|
||||
using CMSMicroservice.Domain.Common;
|
||||
using FluentValidation;
|
||||
|
||||
namespace CMSMicroservice.Application.WalletCQ.Commands.ChargeMagicWallet;
|
||||
@@ -10,10 +11,11 @@ public class ChargeMagicWalletCommandValidator : AbstractValidator<ChargeMagicWa
|
||||
.GreaterThan(0)
|
||||
.WithMessage("شناسه کاربر باید بزرگتر از صفر باشد");
|
||||
|
||||
// حصار ایمنی — سقف واقعی per-package در هندلر اعمال میشود
|
||||
RuleFor(x => x.Amount)
|
||||
.GreaterThanOrEqualTo(100_000)
|
||||
.GreaterThanOrEqualTo(SystemConstants.MagicWalletMinCharge)
|
||||
.WithMessage("حداقل مبلغ شارژ جادویی ۱۰,۰۰۰ تومان است")
|
||||
.LessThanOrEqualTo(1_000_000_000)
|
||||
.WithMessage("حداکثر مبلغ شارژ جادویی ۱۰۰,۰۰۰,۰۰۰ تومان است");
|
||||
.LessThanOrEqualTo(SystemConstants.WalletMaxSafeAmount)
|
||||
.WithMessage("مبلغ وارد شده بیش از حد مجاز است");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,14 +8,18 @@ public static class SmsTemplates
|
||||
/// <summary>
|
||||
/// پیام دریافت اعتبار دایا
|
||||
/// </summary>
|
||||
public static string DayaLoanReceived(string userName) =>
|
||||
$"{userName} عزیز، تامین اعتبار شما انجام شد. شما میتوانید با مراجعه به سامانه کارابازار فرایند فعالسازی خود را ادامه دهید. با تشکر از حسن انتخاب شما";
|
||||
public static string DayaLoanReceived(string userName, string? packageName = null) =>
|
||||
packageName != null
|
||||
? $"{userName} عزیز، تامین اعتبار {packageName} شما انجام شد. شما میتوانید با مراجعه به سامانه کارابازار فرایند فعالسازی خود را ادامه دهید. با تشکر از حسن انتخاب شما"
|
||||
: $"{userName} عزیز، تامین اعتبار شما انجام شد. شما میتوانید با مراجعه به سامانه کارابازار فرایند فعالسازی خود را ادامه دهید. با تشکر از حسن انتخاب شما";
|
||||
|
||||
/// <summary>
|
||||
/// پیام فعالسازی باشگاه مشتریان
|
||||
/// </summary>
|
||||
public static string ClubActivated(string userName) =>
|
||||
$"{userName} گرامی، عضویت شما در باشگاه مشتریان کارابازار با موفقیت فعال شد. با تشکر از حسن انتخاب شما";
|
||||
public static string ClubActivated(string userName, string? packageName = null) =>
|
||||
packageName != null
|
||||
? $"{userName} گرامی، عضویت شما در باشگاه مشتریان کارابازار با {packageName} فعال شد. با تشکر از حسن انتخاب شما"
|
||||
: $"{userName} گرامی، عضویت شما در باشگاه مشتریان کارابازار با موفقیت فعال شد. با تشکر از حسن انتخاب شما";
|
||||
|
||||
/// <summary>
|
||||
/// پیام خرید پکیج
|
||||
@@ -26,8 +30,10 @@ public static class SmsTemplates
|
||||
/// <summary>
|
||||
/// پیام واریز کمیسیون
|
||||
/// </summary>
|
||||
public static string CommissionDeposited(string userName, long amount) =>
|
||||
$"{userName} گرامی، مبلغ {amount:N0} ریال بابت کمیسیون به کیف پول شما واریز شد.";
|
||||
public static string CommissionDeposited(string userName, long amount, string? packageName = null) =>
|
||||
packageName != null
|
||||
? $"{userName} گرامی، مبلغ {amount:N0} ریال بابت کمیسیون {packageName} به کیف پول شما واریز شد."
|
||||
: $"{userName} گرامی، مبلغ {amount:N0} ریال بابت کمیسیون به کیف پول شما واریز شد.";
|
||||
|
||||
/// <summary>
|
||||
/// پیام برداشت موفق
|
||||
|
||||
@@ -66,6 +66,41 @@ public static class SystemConstants
|
||||
/// </summary>
|
||||
public const long MagicWalletEntryThreshold = 1_000_000;
|
||||
|
||||
/// <summary>
|
||||
/// مقدار پیشفرض ضریب جادویی وقتی پکیج یافت نشود (بازگشت به پایه)
|
||||
/// </summary>
|
||||
public const double MagicWalletDefaultMultiplier = 2.5;
|
||||
|
||||
/// <summary>
|
||||
/// مقدار پیشفرض حداکثر واریز جادویی وقتی پکیج یافت نشود (ریال)
|
||||
/// </summary>
|
||||
public const long MagicWalletDefaultMaxDeposit = 1_000_000_000;
|
||||
|
||||
/// <summary>
|
||||
/// مقدار پیشفرض حداکثر اعتبار جادویی وقتی پکیج یافت نشود (ریال)
|
||||
/// </summary>
|
||||
public const long MagicWalletDefaultMaxCredit = 2_500_000_000;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Wallet Validation Settings
|
||||
|
||||
/// <summary>
|
||||
/// حداکثر مبلغ مجاز در ولیدیتور (حصار ایمنی — مقدار واقعی از پکیج خوانده میشود).
|
||||
/// ۱۰ میلیارد ریال = ۱ میلیارد تومان
|
||||
/// </summary>
|
||||
public const long WalletMaxSafeAmount = 10_000_000_000;
|
||||
|
||||
/// <summary>
|
||||
/// حداقل مبلغ شارژ جادویی (ریال) — ۱۰۰٬۰۰۰ ریال = ۱۰ هزار تومان
|
||||
/// </summary>
|
||||
public const long MagicWalletMinCharge = 100_000;
|
||||
|
||||
/// <summary>
|
||||
/// حداقل مبلغ شارژ تخفیفی (ریال) — ۱۰٬۰۰۰ ریال = ۱ هزار تومان
|
||||
/// </summary>
|
||||
public const long DiscountWalletMinCharge = 10_000;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Shop Settings
|
||||
|
||||
@@ -49,6 +49,7 @@ public class UserNotificationService : IUserNotificationService
|
||||
long userId,
|
||||
decimal amount,
|
||||
int weekNumber,
|
||||
string? packageName = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
@@ -69,14 +70,15 @@ public class UserNotificationService : IUserNotificationService
|
||||
if (string.IsNullOrEmpty(userFullName)) userFullName = "کاربر عزیز";
|
||||
|
||||
var formattedAmount = amount.ToString("N0", new System.Globalization.CultureInfo("fa-IR"));
|
||||
var packageInfo = !string.IsNullOrEmpty(packageName) ? $" ({packageName})" : "";
|
||||
|
||||
// Send Email
|
||||
if (_emailSettings.Enabled && !string.IsNullOrEmpty(user.Email))
|
||||
{
|
||||
var emailSubject = $"واریز کمیسیون هفته {weekNumber}";
|
||||
var emailSubject = $"واریز کمیسیون هفته {weekNumber}{packageInfo}";
|
||||
var emailBody = "<div dir='rtl' style='font-family: Tahoma, Arial; text-align: right;'>" +
|
||||
$"<h2>سلام {userFullName}</h2>" +
|
||||
$"<p>کمیسیون هفته {weekNumber} شما به مبلغ <strong>{formattedAmount} ریال</strong> به کیف پول شما واریز شد.</p>" +
|
||||
$"<p>کمیسیون هفته {weekNumber} شما{packageInfo} به مبلغ <strong>{formattedAmount} ریال</strong> به کیف پول شما واریز شد.</p>" +
|
||||
"<p>از اعتماد شما سپاسگزاریم.</p>" +
|
||||
"<hr/>" +
|
||||
"<p style='color: #666; font-size: 12px;'>FourSat - سیستم مدیریت باشگاه مشتریان</p>" +
|
||||
@@ -95,7 +97,7 @@ public class UserNotificationService : IUserNotificationService
|
||||
{
|
||||
await SendSmsAsync(
|
||||
phoneNumber: user.Mobile,
|
||||
message: $"سلام {userFullName}\nکمیسیون هفته {weekNumber} شما به مبلغ {formattedAmount} ریال واریز شد.\nFourSat",
|
||||
message: $"سلام {userFullName}\nکمیسیون هفته {weekNumber} شما{packageInfo} به مبلغ {formattedAmount} ریال واریز شد.\nFourSat",
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
@@ -109,6 +111,7 @@ public class UserNotificationService : IUserNotificationService
|
||||
|
||||
public async Task SendClubActivationNotificationAsync(
|
||||
long userId,
|
||||
string? packageName = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
_logger.LogInformation("🎉 Sending club activation notification: User={UserId}", userId);
|
||||
@@ -120,6 +123,7 @@ public class UserNotificationService : IUserNotificationService
|
||||
|
||||
var userFullName = $"{user.FirstName} {user.LastName}".Trim();
|
||||
if (string.IsNullOrEmpty(userFullName)) userFullName = "کاربر عزیز";
|
||||
var packageInfo = !string.IsNullOrEmpty(packageName) ? $" با {packageName}" : "";
|
||||
|
||||
// Send Email
|
||||
if (_emailSettings.Enabled && !string.IsNullOrEmpty(user.Email))
|
||||
@@ -127,7 +131,7 @@ public class UserNotificationService : IUserNotificationService
|
||||
var emailSubject = "فعالسازی باشگاه مشتریان FourSat";
|
||||
var emailBody = "<div dir='rtl' style='font-family: Tahoma, Arial; text-align: right;'>" +
|
||||
$"<h2>تبریک {userFullName}!</h2>" +
|
||||
"<p>عضویت شما در <strong>باشگاه مشتریان FourSat</strong> با موفقیت فعال شد.</p>" +
|
||||
$"<p>عضویت شما در <strong>باشگاه مشتریان FourSat</strong>{packageInfo} با موفقیت فعال شد.</p>" +
|
||||
"<p>از این پس میتوانید از مزایای ویژه باشگاه بهرهمند شوید.</p>" +
|
||||
"<hr/>" +
|
||||
"<p style='color: #666; font-size: 12px;'>FourSat - سیستم مدیریت باشگاه مشتریان</p>" +
|
||||
@@ -146,7 +150,7 @@ public class UserNotificationService : IUserNotificationService
|
||||
{
|
||||
await SendSmsAsync(
|
||||
phoneNumber: user.Mobile,
|
||||
message: $"تبریک! عضویت شما در باشگاه مشتریان FourSat فعال شد.",
|
||||
message: $"تبریک! عضویت شما در باشگاه مشتریان FourSat{packageInfo} فعال شد.",
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -159,6 +163,7 @@ public class UserNotificationService : IUserNotificationService
|
||||
public async Task SendPayoutErrorNotificationAsync(
|
||||
long userId,
|
||||
string errorMessage,
|
||||
string? packageName = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>0.0.188</Version>
|
||||
<Version>0.0.189</Version>
|
||||
<DebugType>None</DebugType>
|
||||
<DebugSymbols>False</DebugSymbols>
|
||||
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
|
||||
|
||||
@@ -531,6 +531,7 @@ message WithdrawalRequestModel
|
||||
string bank_reference_id = 15;
|
||||
string bank_tracking_code = 16;
|
||||
string payment_failure_reason = 17;
|
||||
google.protobuf.StringValue package_name = 18; // نام پکیج کاربر
|
||||
}
|
||||
|
||||
// ============ Week Definitions (for dropdowns) ============
|
||||
|
||||
@@ -138,6 +138,7 @@ message ManualPaymentModel
|
||||
google.protobuf.Timestamp created = 19;
|
||||
google.protobuf.StringValue image_path = 20;
|
||||
google.protobuf.Int64Value image_document_id = 21;
|
||||
google.protobuf.StringValue package_name = 22; // نام پکیج کاربر
|
||||
}
|
||||
|
||||
message ProcessManualMembershipPaymentRequest
|
||||
|
||||
@@ -251,6 +251,8 @@ message GetMagicWalletStatusResponse
|
||||
int64 balance = 6;
|
||||
google.protobuf.Timestamp magic_activated_at = 7;
|
||||
int32 purchase_cycle_count = 8; // تعداد دورهای خرید پکیج (0 = هنوز هیچ دوری تکمیل نشده)
|
||||
double magic_multiplier = 9; // ضریب جادویی (مثلاً 2.5)
|
||||
int64 magic_max_credit = 10; // حداکثر اعتبار (ریال)
|
||||
}
|
||||
|
||||
// ============= Discount Wallet Messages =============
|
||||
|
||||
@@ -233,7 +233,9 @@ public class UserWalletService : UserWalletContract.UserWalletContractBase
|
||||
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 magicMaxDeposit = package?.MagicWalletMaxDeposit ?? SystemConstants.MagicWalletDefaultMaxDeposit;
|
||||
var magicMultiplier = package != null ? (double)package.MagicWalletMultiplier : SystemConstants.MagicWalletDefaultMultiplier;
|
||||
var magicMaxCredit = package?.MagicWalletMaxCredit ?? SystemConstants.MagicWalletDefaultMaxCredit;
|
||||
|
||||
var response = new GetMagicWalletStatusResponse
|
||||
{
|
||||
@@ -243,7 +245,9 @@ public class UserWalletService : UserWalletContract.UserWalletContractBase
|
||||
MagicMaxDeposit = magicMaxDeposit,
|
||||
MagicRemainingDeposit = Math.Max(0, magicMaxDeposit - wallet.MagicTotalDeposited),
|
||||
Balance = wallet.Balance,
|
||||
PurchaseCycleCount = cycleCount
|
||||
PurchaseCycleCount = cycleCount,
|
||||
MagicMultiplier = magicMultiplier,
|
||||
MagicMaxCredit = magicMaxCredit
|
||||
};
|
||||
|
||||
if (wallet.MagicActivatedAt.HasValue)
|
||||
|
||||
Reference in New Issue
Block a user