diff --git a/.gitignore b/.gitignore
index fe8a569..1c55f34 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,7 +14,7 @@
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
-# Mono auto generated files
+# Mono auto generated files
mono_crash.*
# Build results
diff --git a/src/FrontOffice.Main/Pages/Checkout.razor b/src/FrontOffice.Main/Pages/Checkout.razor
index 79173be..f138e5b 100644
--- a/src/FrontOffice.Main/Pages/Checkout.razor
+++ b/src/FrontOffice.Main/Pages/Checkout.razor
@@ -71,80 +71,6 @@
}
-
-
-
- انتخاب آدرس
-
- @if (_isLoadingAddresses)
- {
-
-
- بارگذاری آدرسها...
-
- }
- else if (_addresses.Any())
- {
-
- @foreach (var address in _addresses)
- {
- SetAddressAsDefault(address.Id)">
-
-
-
- @(address.Title)
- @if (address.IsDefault)
- {
- پیشفرض
- }
- @if (!address.IsDefault)
- {
- @if (_isSettingDefaultAddress && _settingDefaultAddressId == address.Id)
- {
-
- }
- else
- {
-
- تنظیم به عنوان پیشفرض
-
- }
- }
-
-
- @(address.Address)
-
- کد پستی: @(address.PostalCode)
-
-
-
- }
-
- }
- else
- {
-
-
- آدرسی ثبت نشده است.
-
- افزودن آدرس
-
-
- }
-
@@ -241,7 +167,7 @@
@if (!CanProceedToPayment)
{
- لطفاً پکیج و آدرس را انتخاب کنید.
+ لطفاً پکیج را انتخاب کنید.
}
diff --git a/src/FrontOffice.Main/Pages/Checkout.razor.cs b/src/FrontOffice.Main/Pages/Checkout.razor.cs
index 24e2a78..5e30af5 100644
--- a/src/FrontOffice.Main/Pages/Checkout.razor.cs
+++ b/src/FrontOffice.Main/Pages/Checkout.razor.cs
@@ -1,6 +1,4 @@
-
using CMSMicroservice.Protobuf.Protos.Package;
-using CMSMicroservice.Protobuf.Protos.UserAddress;
using FrontOffice.Main.Utilities;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
@@ -13,14 +11,10 @@ public partial class Checkout
{
[Inject] private PackageService PackageService { get; set; } = default!;
[Inject] private PackageContract.PackageContractClient PackageClient { get; set; } = default!;
- [Inject] private UserAddressContract.UserAddressContractClient UserAddressContract { get; set; } = default!;
[Parameter] public long? PackageId { get; set; }
private Pack? _selectedPackage;
- private List _addresses = new();
- private CustomerAddressModel? _selectedAddress;
- private bool _isLoadingAddresses;
private bool _isProcessingPayment;
// Discount code
@@ -31,16 +25,11 @@ public partial class Checkout
private long _discountAmount;
private long _finalPrice;
- // Address management
- private bool _isSettingDefaultAddress;
- private long? _settingDefaultAddressId;
-
- private bool CanProceedToPayment => _selectedPackage != null && _selectedAddress != null;
+ private bool CanProceedToPayment => _selectedPackage != null;
protected override async Task OnInitializedAsync()
{
await LoadPackageDetails();
- await LoadAddresses();
}
private async Task LoadPackageDetails()
@@ -72,60 +61,6 @@ public partial class Checkout
}
}
- private async Task LoadAddresses()
- {
- _isLoadingAddresses = true;
- try
- {
- var response = await UserAddressContract.GetCustomerAddressesAsync(request: new());
- if (response?.Models?.Any() == true)
- {
- _addresses = response.Models.ToList();
- // Select default address if available
- _selectedAddress = _addresses.FirstOrDefault(a => a.IsDefault) ?? _addresses.First();
- }
- else
- {
- _addresses = new List();
- }
- }
- catch (Exception ex)
- {
- Snackbar.Add($"خطا در بارگذاری آدرسها: {ex.Message}", Severity.Error);
- _addresses = new List();
- }
- finally
- {
- _isLoadingAddresses = false;
- await InvokeAsync(StateHasChanged);
- }
- }
-
- private async Task SetAddressAsDefault(long addressId)
- {
- if (_isSettingDefaultAddress) return;
-
- _isSettingDefaultAddress = true;
- _settingDefaultAddressId = addressId;
-
- try
- {
- await UserAddressContract.SetAddressAsDefaultAsync(new() { Id = addressId });
- await LoadAddresses(); // Reload addresses to reflect the change
- Snackbar.Add("آدرس پیشفرض با موفقیت تغییر یافت.", Severity.Success);
- }
- catch (Exception ex)
- {
- Snackbar.Add($"خطا در تغییر آدرس پیشفرض: {ex.Message}", Severity.Error);
- }
- finally
- {
- _isSettingDefaultAddress = false;
- _settingDefaultAddressId = null;
- await InvokeAsync(StateHasChanged);
- }
- }
-
private async Task ApplyDiscountCode()
{
if (string.IsNullOrWhiteSpace(_discountCode))
@@ -157,7 +92,7 @@ public partial class Checkout
_finalPrice = _selectedPackage!.Price;
}
}
- catch (Exception ex)
+ catch (Exception)
{
_discountMessage = "خطا در اعمال کد تخفیف.";
_discountApplied = false;
@@ -175,9 +110,9 @@ public partial class Checkout
{
if (_isProcessingPayment) return;
- if (!CanProceedToPayment || _selectedPackage == null || _selectedAddress == null)
+ if (!CanProceedToPayment || _selectedPackage == null)
{
- Snackbar.Add("لطفاً پکیج و آدرس را انتخاب کنید.", Severity.Warning);
+ Snackbar.Add("لطفاً پکیج را انتخاب کنید.", Severity.Warning);
return;
}
@@ -219,9 +154,9 @@ public partial class Checkout
private async Task DayaLoanPayment()
{
- if (_selectedAddress == null)
+ if (_selectedPackage == null)
{
- Snackbar.Add("لطفاً آدرس را انتخاب کنید.", Severity.Warning);
+ Snackbar.Add("لطفاً پکیج را انتخاب کنید.", Severity.Warning);
return;
}
@@ -230,4 +165,4 @@ public partial class Checkout
}
private record Pack(long Id, string Title, string Body, string Image, long Price, bool SupportsDirectPurchase = true, bool SupportsDayaPurchase = false);
-}
\ No newline at end of file
+}
diff --git a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs
index 50cb81b..1185e0b 100644
--- a/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs
+++ b/src/FrontOffice.Main/Pages/DiscountStore/Checkout.razor.cs
@@ -40,7 +40,11 @@ public partial class Checkout
}
await VAT.LoadAsync();
await DiscountCart.EnsureInitializedAsync();
- await LoadAddresses();
+ var userInfo = await AuthService.GetUserAuthInfo();
+ if (userInfo.HasAddress)
+ await LoadAddresses();
+ else
+ _addresses = new();
}
private async Task LoadAddresses()
diff --git a/src/FrontOffice.Main/Pages/Profile/Addresses.razor.cs b/src/FrontOffice.Main/Pages/Profile/Addresses.razor.cs
index be3d05d..2a496ef 100644
--- a/src/FrontOffice.Main/Pages/Profile/Addresses.razor.cs
+++ b/src/FrontOffice.Main/Pages/Profile/Addresses.razor.cs
@@ -1,4 +1,4 @@
-using CMSMicroservice.Protobuf.Protos.UserAddress;
+using FrontOffice.Main.Utilities;
using CMSMicroservice.Protobuf.Protos.UserAddress;
using FrontOffice.Main.Pages.Profile.Components;
using Microsoft.AspNetCore.Components;
@@ -9,6 +9,7 @@ namespace FrontOffice.Main.Pages.Profile;
public partial class Addresses : ComponentBase
{
[Inject] private UserAddressContract.UserAddressContractClient UserAddressContract { get; set; } = default!;
+ [Inject] private AuthService AuthService { get; set; } = default!;
private List _addresses = new();
private bool _isLoadingAddresses;
@@ -42,7 +43,10 @@ public partial class Addresses : ComponentBase
var dialog = await DialogService.ShowAsync("افزودن آدرس جدید");
var result = await dialog.Result;
if (result is not null && !result.Canceled)
+ {
await LoadAddresses();
+ await AuthService.RefreshTokenAsync();
+ }
}
private async Task OpenEditAddressDialog(CustomerAddressModel address)
@@ -80,6 +84,7 @@ public partial class Addresses : ComponentBase
await UserAddressContract.DeleteCustomerAddressAsync(new() { Id = id });
Snackbar.Add("آدرس حذف شد.", Severity.Success);
await LoadAddresses();
+ await AuthService.RefreshTokenAsync();
}
catch (Exception ex)
{
diff --git a/src/FrontOffice.Main/Pages/Profile/Index.razor.cs b/src/FrontOffice.Main/Pages/Profile/Index.razor.cs
index 10272ec..2f4a266 100644
--- a/src/FrontOffice.Main/Pages/Profile/Index.razor.cs
+++ b/src/FrontOffice.Main/Pages/Profile/Index.razor.cs
@@ -333,6 +333,7 @@ public partial class Index
if (!result.Canceled)
{
await LoadAddresses();
+ await AuthService.RefreshTokenAsync();
}
}
@@ -385,6 +386,7 @@ public partial class Index
});
Snackbar.Add("آدرس با موفقیت حذف شد.", Severity.Success);
await LoadAddresses();
+ await AuthService.RefreshTokenAsync();
}
catch (Exception ex)
{
@@ -491,11 +493,6 @@ public partial class Index
Snackbar.Add("لطفا اطلاعات شخصی خود را تکمیل کنید. (تاریخ تولد وارد نشده)", Severity.Error);
return;
}
- if (!_addresses.Any())
- {
- Snackbar.Add("آدرس محل سکونت شما الزامی است!", Severity.Error);
- return;
- }
var url = "https://dayadiamond.ir/profile/creditpurchase/?merchantcode=56146364";
await JSRuntime.InvokeVoidAsync("open", url, "_blank");
diff --git a/src/FrontOffice.Main/Pages/Profile/WithdrawalRequests.razor.cs b/src/FrontOffice.Main/Pages/Profile/WithdrawalRequests.razor.cs
index 5866666..2370755 100644
--- a/src/FrontOffice.Main/Pages/Profile/WithdrawalRequests.razor.cs
+++ b/src/FrontOffice.Main/Pages/Profile/WithdrawalRequests.razor.cs
@@ -58,8 +58,19 @@ public partial class WithdrawalRequests : ComponentBase
try
{
_isSubmittingWithdrawal = true;
- _withdrawIban=_withdrawIban!.Trim().ToUpper().Replace("IR", "").Replace(" ", "");
- await WalletService.RequestWithdrawalAsync(_selectedPayout.Id, _withdrawMethod, "IR"+_withdrawIban);
+
+ string? normalizedIban = null;
+ if (_withdrawMethod == WithdrawalMethodClient.Cash)
+ {
+ normalizedIban = NormalizeIranianIban(_withdrawIban);
+ if (normalizedIban is null)
+ {
+ Snackbar.Add("فرمت شماره شبا معتبر نیست. باید IR و ۲۴ رقم باشد (خط تیره اختیاری است).", Severity.Warning);
+ return;
+ }
+ }
+
+ await WalletService.RequestWithdrawalAsync(_selectedPayout.Id, _withdrawMethod, normalizedIban);
Snackbar.Add("درخواست برداشت ثبت شد.", Severity.Success);
// بروزرسانی لیست
@@ -125,4 +136,26 @@ public partial class WithdrawalRequests : ComponentBase
1 => "الماس",
_ => "-"
};
+
+ ///
+ /// فاصله و خط تیره را حذف میکند و شبا را به شکل IR + ۲۴ رقم برمیگرداند.
+ ///
+ private static string? NormalizeIranianIban(string? iban)
+ {
+ if (string.IsNullOrWhiteSpace(iban))
+ return null;
+
+ var normalized = iban.Trim().ToUpperInvariant()
+ .Replace(" ", "", StringComparison.Ordinal)
+ .Replace("-", "", StringComparison.Ordinal);
+
+ if (normalized.StartsWith("IR", StringComparison.Ordinal))
+ normalized = normalized[2..];
+
+ normalized = "IR" + normalized;
+
+ return System.Text.RegularExpressions.Regex.IsMatch(normalized, @"^IR\d{24}$")
+ ? normalized
+ : null;
+ }
}
diff --git a/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor.cs b/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor.cs
index 8437093..0c8aedf 100644
--- a/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor.cs
+++ b/src/FrontOffice.Main/Pages/Store/CheckoutSummary.razor.cs
@@ -35,7 +35,11 @@ public partial class CheckoutSummary : ComponentBase
await AuthDialogService.ShowAuthDialogAsync();
}
await Cart.EnsureInitializedAsync();
- await LoadAddresses();
+ var userInfo = await AuthService.GetUserAuthInfo();
+ if (userInfo.HasAddress)
+ await LoadAddresses();
+ else
+ _addresses = new();
await LoadWalletBalance();
}
diff --git a/src/FrontOffice.Main/Utilities/AuthService.cs b/src/FrontOffice.Main/Utilities/AuthService.cs
index 8fe509a..111d5d6 100644
--- a/src/FrontOffice.Main/Utilities/AuthService.cs
+++ b/src/FrontOffice.Main/Utilities/AuthService.cs
@@ -79,6 +79,7 @@ public class AuthService
var isSignMainContractStr = claims.FirstOrDefault(c => c.key == "IsSignMainContract").value;
var hasPurchasedPackageStr = claims.FirstOrDefault(c => c.key == "HasPurchasedPackage").value;
var isClubMemberActiveStr = claims.FirstOrDefault(c => c.key == "IsClubMemberActive").value;
+ var hasAddressStr = claims.FirstOrDefault(c => c.key == "HasAddress").value;
_userAuthInfo.UserId = long.TryParse(userIdStr, out var userId) ? userId : 0;
_userAuthInfo.FirstName = firstName ?? string.Empty;
@@ -88,6 +89,7 @@ public class AuthService
_userAuthInfo.IsSignMainContract = bool.TryParse(isSignMainContractStr, out var isSignMainContract) && isSignMainContract;
_userAuthInfo.HasPurchasedPackage = bool.TryParse(hasPurchasedPackageStr, out var hasPurchased) && hasPurchased;
_userAuthInfo.IsClubMemberActive = bool.TryParse(isClubMemberActiveStr, out var isClubActive) && isClubActive;
+ _userAuthInfo.HasAddress = bool.TryParse(hasAddressStr, out var hasAddress) && hasAddress;
}
private async Task?> GetTokenClaimsAsync()
diff --git a/src/FrontOffice.Main/Utilities/UserAuthInfo.cs b/src/FrontOffice.Main/Utilities/UserAuthInfo.cs
index 32ae68e..043a25b 100644
--- a/src/FrontOffice.Main/Utilities/UserAuthInfo.cs
+++ b/src/FrontOffice.Main/Utilities/UserAuthInfo.cs
@@ -11,4 +11,5 @@ public class UserAuthInfo
public bool IsSignMainContract { get; set; }
public bool HasPurchasedPackage { get; set; }
public bool IsClubMemberActive { get; set; }
+ public bool HasAddress { get; set; }
}
\ No newline at end of file