From a2e1e1fead1e6098e75ea0c28d32175093053312 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sun, 22 Feb 2026 20:04:44 +0330 Subject: [PATCH 1/9] feat: Magic Wallet Phase 6 UI + purchase cycle controls - FrontOffice.Main.csproj: switch to ProjectReference for CMS Protobuf - MagicWallet.razor.cs: update default record with PurchaseCycleCount - WalletService.cs: add PurchaseCycleCount to MagicWalletStatus record - Profile/Index.razor.cs: load _purchaseCycleCount from MagicWalletStatus - Profile/Index.razor: conditional purchase dialog (IPG vs Daya by cycle) - Licenses.razor: fix grid column size xs=6 --- src/FrontOffice.Main/FrontOffice.Main.csproj | 4 +- src/FrontOffice.Main/Pages/Licenses.razor | 2 +- .../Pages/Profile/Index.razor | 51 +++++++++++++------ .../Pages/Profile/Index.razor.cs | 6 +++ .../Pages/Profile/MagicWallet.razor.cs | 2 +- .../Utilities/WalletService.cs | 8 +-- 6 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/FrontOffice.Main/FrontOffice.Main.csproj b/src/FrontOffice.Main/FrontOffice.Main.csproj index 0e2ce06..414aa55 100644 --- a/src/FrontOffice.Main/FrontOffice.Main.csproj +++ b/src/FrontOffice.Main/FrontOffice.Main.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/src/FrontOffice.Main/Pages/Licenses.razor b/src/FrontOffice.Main/Pages/Licenses.razor index bef2351..658cec4 100644 --- a/src/FrontOffice.Main/Pages/Licenses.razor +++ b/src/FrontOffice.Main/Pages/Licenses.razor @@ -37,7 +37,7 @@ else @foreach (var license in _licenseImages) { - + diff --git a/src/FrontOffice.Main/Pages/Profile/Index.razor b/src/FrontOffice.Main/Pages/Profile/Index.razor index 0a0761b..5a8606b 100644 --- a/src/FrontOffice.Main/Pages/Profile/Index.razor +++ b/src/FrontOffice.Main/Pages/Profile/Index.razor @@ -214,26 +214,45 @@ پرداخت مستقیم پرداخت آنی از طریق درگاه بانکی - - پرداخت با کارت بانکی(بزودی) - + @if (_purchaseCycleCount > 0) + { + + پرداخت با کارت بانکی + + } + else + { + + پرداخت با کارت بانکی(بزودی) + + } - - - - - اعتبار الماسی دایا + @if (_purchaseCycleCount == 0) + { + + + + + اعتبار الماسی دایا + + تأمین اعتبار از طریق خرید توکن الماس و دریافت وام + + تأمین اعتبار الماسی + - تأمین اعتبار از طریق خرید توکن الماس و دریافت وام - - تأمین اعتبار الماسی - - - + + } + else + { + + از دور دوم به بعد، خرید پکیج فقط از طریق درگاه بانکی امکان‌پذیر است. + + } بستن diff --git a/src/FrontOffice.Main/Pages/Profile/Index.razor.cs b/src/FrontOffice.Main/Pages/Profile/Index.razor.cs index 2b47695..f64e0d5 100644 --- a/src/FrontOffice.Main/Pages/Profile/Index.razor.cs +++ b/src/FrontOffice.Main/Pages/Profile/Index.razor.cs @@ -45,6 +45,7 @@ public partial class Index // Purchase Options Bottom Sheet private bool _showPurchaseBottomSheet; private bool _isProcessingPayment; + private int _purchaseCycleCount; // تعداد دورهای خرید — اگر > 0 فقط IPG مجاز // Dashboard Tiles private readonly List _dashTiles = new() @@ -148,6 +149,11 @@ public partial class Index var discount = FormatPrice(b.DiscountBalance); _walletNetwork = FormatPrice(b.NetworkBalance); _walletDiscount = discount; + + // بارگذاری تعداد دورهای خرید برای کنترل روش‌های پرداخت + var magicStatus = await WalletService.GetMagicWalletStatusAsync(); + _purchaseCycleCount = magicStatus.PurchaseCycleCount; + StateHasChanged(); } diff --git a/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor.cs b/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor.cs index d5bf1d8..1b26077 100644 --- a/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor.cs +++ b/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor.cs @@ -7,7 +7,7 @@ namespace FrontOffice.Main.Pages.Profile; public partial class MagicWallet : ComponentBase { - private MagicWalletStatus _status = new(0, 0, 0, 0, 0, 0, null); + private MagicWalletStatus _status = new(0, 0, 0, 0, 0, 0, null, 0); private bool _isLoading = true; private bool _isProcessing; private long _chargeAmount; diff --git a/src/FrontOffice.Main/Utilities/WalletService.cs b/src/FrontOffice.Main/Utilities/WalletService.cs index ea77c60..9d21f05 100644 --- a/src/FrontOffice.Main/Utilities/WalletService.cs +++ b/src/FrontOffice.Main/Utilities/WalletService.cs @@ -32,7 +32,8 @@ public record MagicWalletStatus( long MagicMaxDeposit, long MagicRemainingDeposit, long Balance, - DateTime? MagicActivatedAt + DateTime? MagicActivatedAt, + int PurchaseCycleCount ); public class WalletService @@ -212,12 +213,13 @@ public class WalletService response.MagicMaxDeposit, response.MagicRemainingDeposit, response.Balance, - activatedAt + activatedAt, + response.PurchaseCycleCount ); } catch { - return new MagicWalletStatus(0, 0, 0, 0, 0, 0, null); + return new MagicWalletStatus(0, 0, 0, 0, 0, 0, null, 0); } } From 28695a88f80f1908817597e5181a5d428ef54098 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sun, 22 Feb 2026 20:22:52 +0330 Subject: [PATCH 2/9] feat: ChargeDiscountWallet UI - page, route, client method & wallet link - Add ChargeDiscountWallet.razor page with charge form and preset amounts - Add ChargeDiscountWallet.razor.cs code-behind with gateway redirect logic - Add InitiateDiscountChargeAsync client method in WalletService - Add ChargeDiscountWallet route constant - Add charge button link on main Wallet page --- .../Pages/Profile/ChargeDiscountWallet.razor | 121 ++++++++++++++++++ .../Profile/ChargeDiscountWallet.razor.cs | 59 +++++++++ .../Pages/Profile/Wallet.razor | 11 ++ .../Utilities/RouteConstants.cs | 1 + .../Utilities/WalletService.cs | 20 +++ 5 files changed, 212 insertions(+) create mode 100644 src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor create mode 100644 src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor.cs diff --git a/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor b/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor new file mode 100644 index 0000000..6016d2f --- /dev/null +++ b/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor @@ -0,0 +1,121 @@ +@attribute [Route(RouteConstants.Profile.ChargeDiscountWallet)] +@attribute [Authorize] + +شارژ کیف‌پول اعتباری + + + + + + @* ─── نتیجه پرداخت (اگه از callback برگشته) ─── *@ + @if (_paymentResult != null) + { + + @if (_paymentResult == "success") + { + شارژ اعتباری با موفقیت انجام شد! ✅ + } + else if (_paymentResult == "cancelled") + { + پرداخت توسط شما لغو شد. + } + else + { + پرداخت ناموفق بود. لطفاً دوباره تلاش کنید. + } + + } + + @* ─── فرم شارژ ─── *@ + + + + شارژ موجودی اعتباری + + + + مبلغ وارد شده (به تومان) از طریق درگاه پرداخت به موجودی اعتباری شما اضافه می‌شود. + از موجودی اعتباری فقط برای خرید از فروشگاه تخفیفی می‌توانید استفاده کنید. + + + + + + @* دکمه‌های مبلغ سریع *@ + + @foreach (var preset in _presetAmounts) + { + + @FormatToman(preset) + + } + + + @if (_chargeAmount > 0) + { + + + مبلغ پرداخت: + @FormatToman(_chargeAmount) + + + اعتبار دریافتی: + @FormatToman(_chargeAmount) + + + } + + + @if (_isProcessing) + { + + در حال انتقال به درگاه... + } + else + { + پرداخت از درگاه + } + + + + + @* ─── قوانین ─── *@ + + + + + موجودی اعتباری فقط قابل استفاده در فروشگاه تخفیفی است + + + حداقل مبلغ شارژ: ۱۰,۰۰۰ تومان + + + مبلغ واریزی بدون ضریب به موجودی اضافه می‌شود (۱:۱) + + + پرداخت از طریق درگاه بانکی انجام می‌شود + + + + + + diff --git a/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor.cs b/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor.cs new file mode 100644 index 0000000..1d3ffaf --- /dev/null +++ b/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor.cs @@ -0,0 +1,59 @@ +using FrontOffice.Main.Utilities; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace FrontOffice.Main.Pages.Profile; + +public partial class ChargeDiscountWallet : ComponentBase +{ + private bool _isProcessing; + private long _chargeAmount; + private string? _paymentResult; + + private readonly long[] _presetAmounts = { 500_000, 1_000_000, 5_000_000, 10_000_000, 20_000_000, 50_000_000 }; + + [SupplyParameterFromQuery(Name = "payment")] + public string? PaymentQueryParam { get; set; } + + protected override void OnInitialized() + { + _paymentResult = PaymentQueryParam; + } + + private async Task StartDiscountCharge() + { + if (_chargeAmount <= 0 || _isProcessing) return; + + _isProcessing = true; + StateHasChanged(); + + try + { + // تبدیل تومان به ریال + var amountInRial = _chargeAmount * 10; + + var (success, gatewayUrl, error) = await WalletService.InitiateDiscountChargeAsync(amountInRial); + + if (success && !string.IsNullOrEmpty(gatewayUrl)) + { + Navigation.NavigateTo(gatewayUrl, forceLoad: true); + } + else + { + Snackbar.Add(error ?? "خطا در ایجاد درخواست پرداخت", Severity.Error); + } + } + catch (Exception ex) + { + Snackbar.Add($"خطا: {ex.Message}", Severity.Error); + } + finally + { + _isProcessing = false; + StateHasChanged(); + } + } + + private static string FormatToman(long toman) + => string.Format("{0:N0} تومان", toman); +} diff --git a/src/FrontOffice.Main/Pages/Profile/Wallet.razor b/src/FrontOffice.Main/Pages/Profile/Wallet.razor index 5c79048..8cdcbad 100644 --- a/src/FrontOffice.Main/Pages/Profile/Wallet.razor +++ b/src/FrontOffice.Main/Pages/Profile/Wallet.razor @@ -38,6 +38,17 @@ درخواست‌های برداشت + + + شارژ کیف‌پول اعتباری + + تراکنش‌ها و مسیرهای شارژ diff --git a/src/FrontOffice.Main/Utilities/RouteConstants.cs b/src/FrontOffice.Main/Utilities/RouteConstants.cs index a1de966..0c57869 100644 --- a/src/FrontOffice.Main/Utilities/RouteConstants.cs +++ b/src/FrontOffice.Main/Utilities/RouteConstants.cs @@ -23,6 +23,7 @@ public static class RouteConstants public const string Tree = "/profile/tree"; public const string Wallet = "/profile/wallet"; public const string MagicWallet = "/profile/magic-wallet"; + public const string ChargeDiscountWallet = "/profile/charge-discount-wallet"; public const string WithdrawalRequests = "/profile/withdrawal-requests"; } diff --git a/src/FrontOffice.Main/Utilities/WalletService.cs b/src/FrontOffice.Main/Utilities/WalletService.cs index 9d21f05..5b0bcfb 100644 --- a/src/FrontOffice.Main/Utilities/WalletService.cs +++ b/src/FrontOffice.Main/Utilities/WalletService.cs @@ -243,6 +243,26 @@ public class WalletService } } + public async Task<(bool Success, string? GatewayUrl, string? Error)> InitiateDiscountChargeAsync(long amount) + { + try + { + var response = await _client.InitiateDiscountChargeAsync(new InitiateDiscountChargeRequest + { + Amount = amount + }); + + if (response.IsSuccess) + return (true, response.GatewayUrl, null); + + return (false, null, response.ErrorMessage); + } + catch (Grpc.Core.RpcException ex) + { + return (false, null, ex.Status.Detail ?? "خطا در ارتباط با سرور"); + } + } + public int GetWalletMode() { try From 8cef475877c16d8c6ccbe9cf9864c26a39989894 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sun, 22 Feb 2026 20:44:22 +0330 Subject: [PATCH 3/9] =?UTF-8?q?temp:=20disable=20gateway=20payment=20butto?= =?UTF-8?q?ns=20-=20show=20'=D8=A8=D8=B2=D9=88=D8=AF=DB=8C'=20until=20gate?= =?UTF-8?q?way=20is=20activated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MagicWallet.razor: disable charge button - ChargeDiscountWallet.razor: disable charge button - Profile/Index.razor: disable IPG package purchase button for all cycles --- .../Pages/Profile/ChargeDiscountWallet.razor | 17 ++++------------- src/FrontOffice.Main/Pages/Profile/Index.razor | 8 ++++---- .../Pages/Profile/MagicWallet.razor | 17 ++++------------- 3 files changed, 12 insertions(+), 30 deletions(-) diff --git a/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor b/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor index 6016d2f..e0b12b8 100644 --- a/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor +++ b/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor @@ -78,22 +78,13 @@ } - @if (_isProcessing) - { - - در حال انتقال به درگاه... - } - else - { - پرداخت از درگاه - } + بزودی diff --git a/src/FrontOffice.Main/Pages/Profile/Index.razor b/src/FrontOffice.Main/Pages/Profile/Index.razor index 5a8606b..93bc593 100644 --- a/src/FrontOffice.Main/Pages/Profile/Index.razor +++ b/src/FrontOffice.Main/Pages/Profile/Index.razor @@ -216,15 +216,15 @@ پرداخت آنی از طریق درگاه بانکی @if (_purchaseCycleCount > 0) { - - پرداخت با کارت بانکی + + پرداخت با کارت بانکی(بزودی) } else { + StartIcon="@Icons.Material.Filled.Payment"> پرداخت با کارت بانکی(بزودی) } diff --git a/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor b/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor index a5fd7de..dd8c5ee 100644 --- a/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor +++ b/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor @@ -138,22 +138,13 @@ - @if (_isProcessing) - { - - در حال انتقال به درگاه... - } - else - { - پرداخت از درگاه - } + بزودی From 214fe9efbd597ac8af586a3d26983b6c8b9eaa9b Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sun, 22 Feb 2026 20:48:08 +0330 Subject: [PATCH 4/9] refactor: update CMS protobuf package to version 0.0.182 --- src/FrontOffice.Main/FrontOffice.Main.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FrontOffice.Main/FrontOffice.Main.csproj b/src/FrontOffice.Main/FrontOffice.Main.csproj index 414aa55..cbd5f4e 100644 --- a/src/FrontOffice.Main/FrontOffice.Main.csproj +++ b/src/FrontOffice.Main/FrontOffice.Main.csproj @@ -11,8 +11,8 @@ - - + + From 7371a263e8dd0c04741e7465beb91d7f4d579619 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sun, 22 Feb 2026 20:56:38 +0330 Subject: [PATCH 5/9] =?UTF-8?q?refactor:=20rename=20'=D8=AA=D8=AE=D9=81?= =?UTF-8?q?=DB=8C=D9=81=DB=8C'=20to=20'=D8=A7=D8=B9=D8=AA=D8=A8=D8=A7?= =?UTF-8?q?=D8=B1=DB=8C'=20in=20all=20user-facing=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ChargeDiscountWallet.razor: فروشگاه تخفیفی → فروشگاه اعتباری - PaymentCallback.razor: اعتبار تخفیف → کیف پول اعتباری - Profile/Index.razor: تخفیف باشگاه → کیف اعتباری --- src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor | 4 ++-- src/FrontOffice.Main/Pages/Profile/Index.razor | 2 +- src/FrontOffice.Main/Pages/Profile/PaymentCallback.razor | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor b/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor index e0b12b8..37feab8 100644 --- a/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor +++ b/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor @@ -36,7 +36,7 @@ مبلغ وارد شده (به تومان) از طریق درگاه پرداخت به موجودی اعتباری شما اضافه می‌شود. - از موجودی اعتباری فقط برای خرید از فروشگاه تخفیفی می‌توانید استفاده کنید. + از موجودی اعتباری فقط برای خرید از فروشگاه اعتباری می‌توانید استفاده کنید. @@ -94,7 +94,7 @@ - موجودی اعتباری فقط قابل استفاده در فروشگاه تخفیفی است + موجودی اعتباری فقط قابل استفاده در فروشگاه اعتباری است حداقل مبلغ شارژ: ۱۰,۰۰۰ تومان diff --git a/src/FrontOffice.Main/Pages/Profile/Index.razor b/src/FrontOffice.Main/Pages/Profile/Index.razor index 93bc593..da4b228 100644 --- a/src/FrontOffice.Main/Pages/Profile/Index.razor +++ b/src/FrontOffice.Main/Pages/Profile/Index.razor @@ -53,7 +53,7 @@
- تخفیف باشگاه + کیف اعتباری
@_walletDiscount
diff --git a/src/FrontOffice.Main/Pages/Profile/PaymentCallback.razor b/src/FrontOffice.Main/Pages/Profile/PaymentCallback.razor index 89e42ae..952d7f1 100644 --- a/src/FrontOffice.Main/Pages/Profile/PaymentCallback.razor +++ b/src/FrontOffice.Main/Pages/Profile/PaymentCallback.razor @@ -34,7 +34,7 @@ موجودی کیف پول: @FormatPrice(_walletBalance) - موجودی اعتبار تخفیف: @FormatPrice(_discountBalance) + موجودی کیف پول اعتباری: @FormatPrice(_discountBalance) Date: Sun, 22 Feb 2026 21:03:10 +0330 Subject: [PATCH 6/9] =?UTF-8?q?refactor:=20rename=20'=D8=AA=D8=AE=D9=81?= =?UTF-8?q?=DB=8C=D9=81'=20to=20'=D8=A7=D8=B9=D8=AA=D8=A8=D8=A7=D8=B1'=20i?= =?UTF-8?q?n=20DiscountStore=20pages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Products.razor: X% تخفیف → X% اعتبار - ProductDetail.razor: تخفیف از کیف اعتباری → اعتبار از کیف اعتباری - Cart.razor: سقف تخفیف/تخفیف → سقف اعتبار/اعتبار (desktop + mobile) - Checkout.razor: تخفیف از کیف اعتباری → اعتبار، مبلغ پس از تخفیف → مبلغ پس از اعتبار - OrderDetail.razor: سقف تخفیف/تخفیف → سقف اعتبار/اعتبار --- .../Pages/DiscountStore/Cart.razor | 14 +++++++------- .../Pages/DiscountStore/Checkout.razor | 6 +++--- .../Pages/DiscountStore/Checkout.razor.cs | 2 +- .../Pages/DiscountStore/OrderDetail.razor | 6 +++--- .../Pages/DiscountStore/ProductDetail.razor | 2 +- .../Pages/DiscountStore/Products.razor | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/FrontOffice.Main/Pages/DiscountStore/Cart.razor b/src/FrontOffice.Main/Pages/DiscountStore/Cart.razor index 23d468b..84af3d8 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/Cart.razor +++ b/src/FrontOffice.Main/Pages/DiscountStore/Cart.razor @@ -23,9 +23,9 @@ محصول قیمت واحد - سقف تخفیف + سقف اعتبار تعداد - تخفیف + اعتبار قیمت نهایی @@ -40,7 +40,7 @@ @FormatPrice(context.UnitPrice) - @context.MaxDiscountPercent% تخفیف + @context.MaxDiscountPercent% اعتبار @@ -86,7 +86,7 @@ @item.Title
- @item.MaxDiscountPercent% تخفیف + @item.MaxDiscountPercent% اعتبار @@ -107,7 +107,7 @@ @if (item.DiscountAmount > 0) { - تخفیف: @FormatPrice(item.DiscountAmount)- + اعتبار: @FormatPrice(item.DiscountAmount)- } جمع: @FormatPrice(item.FinalPrice) 0) { - سقف تخفیف قابل اعمال: + سقف اعتبار قابل اعمال: @FormatPrice(DiscountCart.TotalDiscount)- تومان } @@ -161,7 +161,7 @@ @if (DiscountCart.TotalDiscount > 0) { - سقف تخفیف قابل اعمال: + سقف اعتبار قابل اعمال: @FormatPrice(DiscountCart.TotalDiscount)- تومان } diff --git a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor index 6158341..185d7c8 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor +++ b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor @@ -90,7 +90,7 @@ @if (item.MaxDiscountPercent > 0) { - @item.MaxDiscountPercent% تخفیف + @item.MaxDiscountPercent% اعتبار } @@ -108,12 +108,12 @@ - تخفیف از کیف اعتباری: + اعتبار از کیف اعتباری: @FormatPrice(DiscountCart.TotalDiscount)- تومان - مبلغ پس از تخفیف: + مبلغ پس از اعتبار: @FormatPrice(NetGatewayAmount) تومان diff --git a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs index 9995b32..11e971b 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs +++ b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs @@ -20,7 +20,7 @@ public partial class Checkout private const decimal VAT_RATE = 0.10m; - /// مبلغ درگاه قبل از مالیات (جمع کل - تخفیف) + /// مبلغ درگاه قبل از مالیات (جمع کل - اعتبار) private long NetGatewayAmount => DiscountCart.TotalPrice - DiscountCart.TotalDiscount; /// مالیات بر ارزش افزوده ۱۰٪ diff --git a/src/FrontOffice.Main/Pages/DiscountStore/OrderDetail.razor b/src/FrontOffice.Main/Pages/DiscountStore/OrderDetail.razor index db96ab8..a58aed3 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/OrderDetail.razor +++ b/src/FrontOffice.Main/Pages/DiscountStore/OrderDetail.razor @@ -82,8 +82,8 @@ else محصول قیمت واحد تعداد - سقف تخفیف - تخفیف + سقف اعتبار + اعتبار قیمت نهایی @@ -131,7 +131,7 @@ else @if (item.DiscountAmount > 0) { - تخفیف (@item.MaxDiscountPercent%): + اعتبار (@item.MaxDiscountPercent%): @FormatPrice(item.DiscountAmount)- } diff --git a/src/FrontOffice.Main/Pages/DiscountStore/ProductDetail.razor b/src/FrontOffice.Main/Pages/DiscountStore/ProductDetail.razor index 0b582e4..d7b473c 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/ProductDetail.razor +++ b/src/FrontOffice.Main/Pages/DiscountStore/ProductDetail.razor @@ -74,7 +74,7 @@ @if (_product.MaxDiscountPercent > 0) { - تخفیف از کیف اعتباری: + اعتبار از کیف اعتباری: @_product.MaxDiscountPercent% (@($"{_product.Price * _product.MaxDiscountPercent / 100:N0}") تومان) diff --git a/src/FrontOffice.Main/Pages/DiscountStore/Products.razor b/src/FrontOffice.Main/Pages/DiscountStore/Products.razor index 6cb49e8..6d1da72 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/Products.razor +++ b/src/FrontOffice.Main/Pages/DiscountStore/Products.razor @@ -97,7 +97,7 @@ { - @p.MaxDiscountPercent% تخفیف + @p.MaxDiscountPercent% اعتبار } From 93b7375db5fb23962f56dd1d37589e1529245d3f Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sun, 22 Feb 2026 21:26:01 +0330 Subject: [PATCH 7/9] =?UTF-8?q?feat:=20add=20VAT=20display=20to=20all=20Di?= =?UTF-8?q?scountStore=20pages=20=E2=80=94=20Products=20(note),=20ProductD?= =?UTF-8?q?etail=20(breakdown),=20Cart=20(summary=20line),=20Checkout=20(r?= =?UTF-8?q?efactor=20to=20VATService),=20OrderDetail=20(financial=20summar?= =?UTF-8?q?y)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pages/DiscountStore/Cart.razor | 18 +++++++++++-- .../Pages/DiscountStore/Cart.razor.cs | 13 ++++++++++ .../Pages/DiscountStore/Checkout.razor | 2 +- .../Pages/DiscountStore/Checkout.razor.cs | 8 +++--- .../Pages/DiscountStore/OrderDetail.razor | 8 ++++++ .../Pages/DiscountStore/OrderDetail.razor.cs | 16 ++++++++++++ .../Pages/DiscountStore/ProductDetail.razor | 26 ++++++++++++++++++- .../DiscountStore/ProductDetail.razor.cs | 10 +++++++ .../Pages/DiscountStore/Products.razor | 5 +++- 9 files changed, 97 insertions(+), 9 deletions(-) diff --git a/src/FrontOffice.Main/Pages/DiscountStore/Cart.razor b/src/FrontOffice.Main/Pages/DiscountStore/Cart.razor index 84af3d8..28da840 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/Cart.razor +++ b/src/FrontOffice.Main/Pages/DiscountStore/Cart.razor @@ -135,9 +135,16 @@ @FormatPrice(DiscountCart.TotalDiscount)- تومان } + @if (VAT.IsEnabled) + { + + مالیات ارزش افزوده (@VAT.VatPercentage%): + @FormatPrice(VatAmount)+ تومان + + } حداقل پرداخت: - @FormatPrice(DiscountCart.FinalPrice) تومان + @FormatPrice(TotalWithVat) تومان @@ -165,10 +172,17 @@ @FormatPrice(DiscountCart.TotalDiscount)- تومان } + @if (VAT.IsEnabled) + { + + مالیات بر ارزش افزوده (@VAT.VatPercentage%): + @FormatPrice(VatAmount)+ تومان + + } حداقل مبلغ پرداخت درگاه: - @FormatPrice(DiscountCart.FinalPrice) تومان + @FormatPrice(TotalWithVat) تومان مبلغ دقیق پرداخت در مرحله تسویه مشخص خواهد شد. diff --git a/src/FrontOffice.Main/Pages/DiscountStore/Cart.razor.cs b/src/FrontOffice.Main/Pages/DiscountStore/Cart.razor.cs index 256e9cb..d53ea46 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/Cart.razor.cs +++ b/src/FrontOffice.Main/Pages/DiscountStore/Cart.razor.cs @@ -6,6 +6,7 @@ namespace FrontOffice.Main.Pages.DiscountStore; public partial class Cart : IDisposable { [Inject] private DiscountCartService DiscountCart { get; set; } = default!; + [Inject] private VATService VAT { get; set; } = default!; protected override async Task OnInitializedAsync() { @@ -44,6 +45,18 @@ public partial class Cart : IDisposable Navigation.NavigateTo(RouteConstants.DiscountStore.Checkout); } + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await VAT.LoadAsync(); + StateHasChanged(); + } + } + + private long VatAmount => VAT.CalculateVAT(DiscountCart.FinalPrice); + private long TotalWithVat => DiscountCart.FinalPrice + VatAmount; + private static string FormatPrice(long price) => $"{price:N0} "; private static string GetImageUrl(string? imageUrl) diff --git a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor index 185d7c8..beba9e2 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor +++ b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor @@ -118,7 +118,7 @@ - مالیات بر ارزش افزوده (۱۰٪): + مالیات بر ارزش افزوده (@VAT.VatPercentage٪): @FormatPrice(VatAmount)+ تومان diff --git a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs index 11e971b..4036725 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs +++ b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs @@ -10,6 +10,7 @@ public partial class Checkout [Inject] private DiscountCartService DiscountCart { get; set; } = default!; [Inject] private DiscountOrderService DiscountOrderService { get; set; } = default!; [Inject] private UserAddressContract.UserAddressContractClient UserAddressContract { get; set; } = default!; + [Inject] private VATService VAT { get; set; } = default!; private List _addresses = new(); private CustomerAddressModel? _selectedAddress; @@ -18,13 +19,11 @@ public partial class Checkout private string? _notes; private bool _placing; - private const decimal VAT_RATE = 0.10m; - /// مبلغ درگاه قبل از مالیات (جمع کل - اعتبار) private long NetGatewayAmount => DiscountCart.TotalPrice - DiscountCart.TotalDiscount; - /// مالیات بر ارزش افزوده ۱۰٪ - private long VatAmount => (long)(NetGatewayAmount * VAT_RATE); + /// مالیات بر ارزش افزوده + private long VatAmount => VAT.CalculateVAT(NetGatewayAmount); /// مبلغ نهایی قابل پرداخت (شامل VAT) private long FinalGatewayAmount => NetGatewayAmount + VatAmount; @@ -33,6 +32,7 @@ public partial class Checkout protected override async Task OnInitializedAsync() { + await VAT.LoadAsync(); await DiscountCart.EnsureInitializedAsync(); await LoadAddresses(); } diff --git a/src/FrontOffice.Main/Pages/DiscountStore/OrderDetail.razor b/src/FrontOffice.Main/Pages/DiscountStore/OrderDetail.razor index a58aed3..528843c 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/OrderDetail.razor +++ b/src/FrontOffice.Main/Pages/DiscountStore/OrderDetail.razor @@ -163,6 +163,14 @@ else } + @if (VAT.IsEnabled) + { + + مالیات بر ارزش افزوده (@VAT.VatPercentage%): + @FormatPrice(OrderVatAmount)+ + + } + diff --git a/src/FrontOffice.Main/Pages/DiscountStore/OrderDetail.razor.cs b/src/FrontOffice.Main/Pages/DiscountStore/OrderDetail.razor.cs index 4c57dac..bcffac9 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/OrderDetail.razor.cs +++ b/src/FrontOffice.Main/Pages/DiscountStore/OrderDetail.razor.cs @@ -12,12 +12,28 @@ public partial class OrderDetail public string? PaymentResult { get; set; } [Inject] private DiscountOrderService DiscountOrderService { get; set; } = default!; + [Inject] private VATService VAT { get; set; } = default!; private DiscountOrderDetail? _order; private bool _loading = true; private string? _paymentMessage; private MudBlazor.Severity _paymentSeverity; + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await VAT.LoadAsync(); + StateHasChanged(); + } + } + + /// مبلغ قبل از مالیات (جمع کل - اعتبار) + private long PreVatGateway => _order is null ? 0 : (_order.TotalPrice - _order.DiscountBalanceUsed); + + /// مالیات بر ارزش افزوده + private long OrderVatAmount => VAT.CalculateVAT(PreVatGateway); + protected override async Task OnInitializedAsync() { // نمایش پیام نتیجه پرداخت (بعد از بازگشت از درگاه) diff --git a/src/FrontOffice.Main/Pages/DiscountStore/ProductDetail.razor b/src/FrontOffice.Main/Pages/DiscountStore/ProductDetail.razor index d7b473c..db89b9e 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/ProductDetail.razor +++ b/src/FrontOffice.Main/Pages/DiscountStore/ProductDetail.razor @@ -67,10 +67,34 @@ قیمت محصول: - + @($"{_product.Price:N0}") تومان + @if (VAT.IsEnabled) + { + + مالیات ارزش افزوده (@VAT.VatPercentage%): + + @($"{VAT.CalculateVAT(_product.Price):N0}") تومان + + + + قیمت با مالیات: + + @($"{VAT.AddVAT(_product.Price):N0}") تومان + + + } + else + { + + قیمت نهایی: + + @($"{_product.Price:N0}") تومان + + + } @if (_product.MaxDiscountPercent > 0) { diff --git a/src/FrontOffice.Main/Pages/DiscountStore/ProductDetail.razor.cs b/src/FrontOffice.Main/Pages/DiscountStore/ProductDetail.razor.cs index fd90d66..5d09884 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/ProductDetail.razor.cs +++ b/src/FrontOffice.Main/Pages/DiscountStore/ProductDetail.razor.cs @@ -9,6 +9,7 @@ public partial class ProductDetail [Inject] private DiscountProductService DiscountProductService { get; set; } = default!; [Inject] private DiscountCartService DiscountCartService { get; set; } = default!; + [Inject] private VATService VAT { get; set; } = default!; private DiscountProductDetail? _product; private string _selectedImage = string.Empty; @@ -21,6 +22,15 @@ public partial class ProductDetail await LoadProductAsync(); } + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await VAT.LoadAsync(); + StateHasChanged(); + } + } + private async Task LoadProductAsync() { _loading = true; diff --git a/src/FrontOffice.Main/Pages/DiscountStore/Products.razor b/src/FrontOffice.Main/Pages/DiscountStore/Products.razor index 6d1da72..5630c14 100644 --- a/src/FrontOffice.Main/Pages/DiscountStore/Products.razor +++ b/src/FrontOffice.Main/Pages/DiscountStore/Products.razor @@ -103,7 +103,10 @@
@p.Title - @FormatPrice(p.Price) +
+ @FormatPrice(p.Price) + (+ ارزش افزوده) +
From 8e1f7d7a0c38781589b1ce511677e1febe9f9ee8 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sun, 22 Feb 2026 21:30:26 +0330 Subject: [PATCH 8/9] =?UTF-8?q?fix:=20change=20=D8=B1=DB=8C=D8=A7=D9=84=20?= =?UTF-8?q?to=20=D8=AA=D9=88=D9=85=D8=A7=D9=86=20in=20MagicWallet=20helper?= =?UTF-8?q?=20text?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/FrontOffice.Main/Pages/Profile/MagicWallet.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor b/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor index dd8c5ee..b78db30 100644 --- a/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor +++ b/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor @@ -105,7 +105,7 @@ Format="N0" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Payments" - HelperText="@($"حداکثر: {FormatPrice(_status.MagicRemainingDeposit)} (ریال)")" /> + HelperText="@($"حداکثر: {FormatPrice(_status.MagicRemainingDeposit)} (تومان)")" /> @if (_chargeAmount > 0) { From 2fa9dbc900b23d20be629bf89f952715ab84e671 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sun, 22 Feb 2026 22:13:23 +0330 Subject: [PATCH 9/9] =?UTF-8?q?feat:=20enable=20gateway=20buttons=20-=20re?= =?UTF-8?q?move=20=D8=A8=D8=B2=D9=88=D8=AF=DB=8C=20disabled=20state?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ChargeDiscountWallet: active payment button with StartDiscountCharge - MagicWallet: active payment button with StartMagicCharge - Index: both branch buttons call DirectPayment with loading state --- .../Pages/Profile/ChargeDiscountWallet.razor | 17 +++++++--- .../Pages/Profile/Index.razor | 32 +++++++++++++++---- .../Pages/Profile/MagicWallet.razor | 17 +++++++--- 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor b/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor index 37feab8..0847eae 100644 --- a/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor +++ b/src/FrontOffice.Main/Pages/Profile/ChargeDiscountWallet.razor @@ -78,13 +78,22 @@ } - بزودی + @if (_isProcessing) + { + + در حال انتقال به درگاه... + } + else + { + پرداخت با کارت بانکی + } diff --git a/src/FrontOffice.Main/Pages/Profile/Index.razor b/src/FrontOffice.Main/Pages/Profile/Index.razor index da4b228..2ca1a37 100644 --- a/src/FrontOffice.Main/Pages/Profile/Index.razor +++ b/src/FrontOffice.Main/Pages/Profile/Index.razor @@ -216,16 +216,36 @@ پرداخت آنی از طریق درگاه بانکی @if (_purchaseCycleCount > 0) { - - پرداخت با کارت بانکی(بزودی) + + @if (_isProcessingPayment) + { + + در حال انتقال به درگاه... + } + else + { + پرداخت با کارت بانکی + } } else { - - پرداخت با کارت بانکی(بزودی) + + @if (_isProcessingPayment) + { + + در حال انتقال به درگاه... + } + else + { + پرداخت با کارت بانکی + } } diff --git a/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor b/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor index b78db30..839d38a 100644 --- a/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor +++ b/src/FrontOffice.Main/Pages/Profile/MagicWallet.razor @@ -138,13 +138,22 @@ - بزودی + @if (_isProcessing) + { + + در حال انتقال به درگاه... + } + else + { + پرداخت با کارت بانکی + }