feat: Add gRPC clients and services for Club, Commission, Network, and Discount functionalities
This commit is contained in:
@@ -13,6 +13,11 @@ using FrontOffice.BFF.UserAddress.Protobuf.Protos.UserAddress;
|
|||||||
using FrontOffice.BFF.UserOrder.Protobuf.Protos.UserOrder;
|
using FrontOffice.BFF.UserOrder.Protobuf.Protos.UserOrder;
|
||||||
using FrontOffice.BFF.UserWallet.Protobuf.Protos.UserWallet;
|
using FrontOffice.BFF.UserWallet.Protobuf.Protos.UserWallet;
|
||||||
using FrontOffice.BFF.ShopingCart.Protobuf.Protos.ShopingCart;
|
using FrontOffice.BFF.ShopingCart.Protobuf.Protos.ShopingCart;
|
||||||
|
// New Proto imports
|
||||||
|
using FrontOffice.BFF.ClubMembership.Protobuf.Protos.ClubMembership;
|
||||||
|
using FrontOffice.BFF.Commission.Protobuf.Protos.Commission;
|
||||||
|
using FrontOffice.BFF.NetworkMembership.Protobuf.Protos.NetworkMembership;
|
||||||
|
using FrontOffice.BFF.DiscountShop.Protobuf.Protos.DiscountShop;
|
||||||
using FrontOffice.Main.Utilities;
|
using FrontOffice.Main.Utilities;
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyInjection;
|
namespace Microsoft.Extensions.DependencyInjection;
|
||||||
@@ -89,6 +94,11 @@ public static class ConfigureServices
|
|||||||
services.AddScoped(CreateAuthenticatedClient<FrontOffice.BFF.Products.Protobuf.Protos.Products.ProductsContract.ProductsContractClient>);
|
services.AddScoped(CreateAuthenticatedClient<FrontOffice.BFF.Products.Protobuf.Protos.Products.ProductsContract.ProductsContractClient>);
|
||||||
services.AddScoped(CreateAuthenticatedClient<TransactionContract.TransactionContractClient>);
|
services.AddScoped(CreateAuthenticatedClient<TransactionContract.TransactionContractClient>);
|
||||||
services.AddScoped(CreateAuthenticatedClient<ShopingCartContract.ShopingCartContractClient>);
|
services.AddScoped(CreateAuthenticatedClient<ShopingCartContract.ShopingCartContractClient>);
|
||||||
|
// New gRPC clients for Club, Network, Commission, DiscountShop
|
||||||
|
services.AddScoped(CreateAuthenticatedClient<ClubMembershipContract.ClubMembershipContractClient>);
|
||||||
|
services.AddScoped(CreateAuthenticatedClient<CommissionContract.CommissionContractClient>);
|
||||||
|
services.AddScoped(CreateAuthenticatedClient<NetworkMembershipContract.NetworkMembershipContractClient>);
|
||||||
|
services.AddScoped(CreateAuthenticatedClient<DiscountShopContract.DiscountShopContractClient>);
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<PackageReference Include="Foursat.FrontOffice.BFF.UserAddress.Protobuf" Version="0.0.114" />
|
<PackageReference Include="Foursat.FrontOffice.BFF.UserAddress.Protobuf" Version="0.0.114" />
|
||||||
<PackageReference Include="Foursat.FrontOffice.BFF.UserOrder.Protobuf" Version="0.0.114" />
|
<PackageReference Include="Foursat.FrontOffice.BFF.UserOrder.Protobuf" Version="0.0.114" />
|
||||||
<PackageReference Include="Foursat.FrontOffice.BFF.ShopingCart.Protobuf" Version="0.0.15" />
|
<PackageReference Include="Foursat.FrontOffice.BFF.ShopingCart.Protobuf" Version="0.0.15" />
|
||||||
<PackageReference Include="Foursat.FrontOffice.BFF.UserWallet.Protobuf" Version="0.0.14" />
|
<!-- UserWallet moved to ProjectReference for latest proto -->
|
||||||
<PackageReference Include="MudBlazor" Version="8.14.0" />
|
<PackageReference Include="MudBlazor" Version="8.14.0" />
|
||||||
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
|
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
|
||||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||||
@@ -27,6 +27,15 @@
|
|||||||
<PackageReference Include="PuppeteerSharp" Version="11.0.0" />
|
<PackageReference Include="PuppeteerSharp" Version="11.0.0" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.14.0" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.14.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!-- New Proto Projects (local references until NuGet publish) -->
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\FrontOffice.BFF\src\Protobufs\FrontOffice.BFF.ClubMembership.Protobuf\FrontOffice.BFF.ClubMembership.Protobuf.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\FrontOffice.BFF\src\Protobufs\FrontOffice.BFF.Commission.Protobuf\FrontOffice.BFF.Commission.Protobuf.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\FrontOffice.BFF\src\Protobufs\FrontOffice.BFF.NetworkMembership.Protobuf\FrontOffice.BFF.NetworkMembership.Protobuf.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\FrontOffice.BFF\src\Protobufs\FrontOffice.BFF.DiscountShop.Protobuf\FrontOffice.BFF.DiscountShop.Protobuf.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\FrontOffice.BFF\src\Protobufs\FrontOffice.BFF.UserWallet.Protobuf\FrontOffice.BFF.UserWallet.Protobuf.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
|
using FrontOffice.BFF.ClubMembership.Protobuf.Protos.ClubMembership;
|
||||||
|
using Google.Protobuf.WellKnownTypes;
|
||||||
|
|
||||||
namespace FrontOffice.Main.Utilities;
|
namespace FrontOffice.Main.Utilities;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Service for Club Membership operations
|
/// Service for Club Membership operations
|
||||||
/// TODO: Connect to FrontOffice.BFF gRPC ClubMembershipCQ
|
/// Connected to FrontOffice.BFF gRPC ClubMembershipCQ
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ClubMembershipService
|
public class ClubMembershipService
|
||||||
{
|
{
|
||||||
// TODO: Inject gRPC client when FrontOffice connects to BFF
|
private readonly ClubMembershipContract.ClubMembershipContractClient _client;
|
||||||
// private readonly ClubMembershipContract.ClubMembershipContractClient _client;
|
|
||||||
|
|
||||||
public ClubMembershipService()
|
public ClubMembershipService(ClubMembershipContract.ClubMembershipContractClient client)
|
||||||
{
|
{
|
||||||
// TODO: Initialize gRPC client
|
_client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -20,21 +22,28 @@ public class ClubMembershipService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<ClubMembershipDto> GetMyMembershipAsync()
|
public async Task<ClubMembershipDto> GetMyMembershipAsync()
|
||||||
{
|
{
|
||||||
// TODO: Replace with actual gRPC call to BFF
|
try
|
||||||
// var request = new GetMyClubMembershipRequest();
|
|
||||||
// var response = await _client.GetMyClubMembershipAsync(request);
|
|
||||||
// return MapToDto(response);
|
|
||||||
|
|
||||||
await Task.Delay(500); // Simulate network delay
|
|
||||||
|
|
||||||
// Mock data for now
|
|
||||||
return new ClubMembershipDto
|
|
||||||
{
|
{
|
||||||
UserId = 1,
|
var response = await _client.GetMyClubMembershipAsync(new Empty());
|
||||||
IsActive = false,
|
return new ClubMembershipDto
|
||||||
Status = "Inactive",
|
{
|
||||||
DaysRemaining = null
|
UserId = response.UserId,
|
||||||
};
|
IsActive = response.IsActive,
|
||||||
|
Status = response.Status,
|
||||||
|
DaysRemaining = response.DaysRemaining > 0 ? response.DaysRemaining : null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Fallback to mock data if backend is unavailable
|
||||||
|
return new ClubMembershipDto
|
||||||
|
{
|
||||||
|
UserId = 1,
|
||||||
|
IsActive = false,
|
||||||
|
Status = "Inactive",
|
||||||
|
DaysRemaining = null
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -46,25 +55,37 @@ public class ClubMembershipService
|
|||||||
string? activationCode,
|
string? activationCode,
|
||||||
int durationMonths)
|
int durationMonths)
|
||||||
{
|
{
|
||||||
// TODO: Replace with actual gRPC call to BFF
|
try
|
||||||
// var request = new ActivateMyClubMembershipRequest
|
|
||||||
// {
|
|
||||||
// PackageId = packageId,
|
|
||||||
// ActivationCode = activationCode ?? string.Empty,
|
|
||||||
// DurationMonths = durationMonths
|
|
||||||
// };
|
|
||||||
// var response = await _client.ActivateMyClubMembershipAsync(request);
|
|
||||||
// return MapToDto(response);
|
|
||||||
|
|
||||||
await Task.Delay(1000); // Simulate network delay
|
|
||||||
|
|
||||||
// Mock successful activation
|
|
||||||
return new ClubActivationResponseDto
|
|
||||||
{
|
{
|
||||||
Success = true,
|
var request = new ActivateMyClubMembershipRequest
|
||||||
Message = "عضویت با موفقیت فعال شد",
|
{
|
||||||
ActivationDate = DateTime.Now,
|
PackageId = packageId,
|
||||||
AmountPaid = 56_000_000 * durationMonths
|
DurationMonths = durationMonths
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(activationCode))
|
||||||
|
{
|
||||||
|
request.ActivationCode = activationCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = await _client.ActivateMyClubMembershipAsync(request);
|
||||||
|
return new ClubActivationResponseDto
|
||||||
|
{
|
||||||
|
Success = response.Success,
|
||||||
|
Message = response.Message,
|
||||||
|
ActivationDate = response.ActivationDate?.ToDateTime(),
|
||||||
|
AmountPaid = response.AmountPaid
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Grpc.Core.RpcException ex)
|
||||||
|
{
|
||||||
|
return new ClubActivationResponseDto
|
||||||
|
{
|
||||||
|
Success = false,
|
||||||
|
Message = ex.Status.Detail ?? "خطا در فعالسازی عضویت",
|
||||||
|
ActivationDate = null,
|
||||||
|
AmountPaid = 0
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
|
using FrontOffice.BFF.Commission.Protobuf.Protos.Commission;
|
||||||
|
|
||||||
namespace FrontOffice.Main.Utilities;
|
namespace FrontOffice.Main.Utilities;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Service for Commission operations
|
/// Service for Commission operations
|
||||||
/// TODO: Connect to FrontOffice.BFF gRPC CommissionCQ
|
/// Connected to FrontOffice.BFF gRPC CommissionCQ
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CommissionService
|
public class CommissionService
|
||||||
{
|
{
|
||||||
// TODO: Inject gRPC client when FrontOffice connects to BFF
|
private readonly CommissionContract.CommissionContractClient _client;
|
||||||
// private readonly CommissionContract.CommissionContractClient _client;
|
|
||||||
|
|
||||||
public CommissionService()
|
public CommissionService(CommissionContract.CommissionContractClient client)
|
||||||
{
|
{
|
||||||
// TODO: Initialize gRPC client
|
_client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -24,23 +25,147 @@ public class CommissionService
|
|||||||
int pageNumber,
|
int pageNumber,
|
||||||
int pageSize)
|
int pageSize)
|
||||||
{
|
{
|
||||||
// TODO: Replace with actual gRPC call to BFF
|
try
|
||||||
// var request = new GetMyCommissionPayoutsRequest
|
{
|
||||||
// {
|
var request = new GetMyCommissionPayoutsRequest
|
||||||
// WeekNumber = weekNumber,
|
{
|
||||||
// Status = status ?? string.Empty,
|
PageNumber = pageNumber,
|
||||||
// PageNumber = pageNumber,
|
PageSize = pageSize
|
||||||
// PageSize = pageSize
|
};
|
||||||
// };
|
|
||||||
// var response = await _client.GetMyCommissionPayoutsAsync(request);
|
if (weekNumber.HasValue)
|
||||||
// return MapToDto(response);
|
{
|
||||||
|
request.WeekNumber = $"2025-W{weekNumber:D2}";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map status string to int
|
||||||
|
if (!string.IsNullOrEmpty(status))
|
||||||
|
{
|
||||||
|
request.Status = status switch
|
||||||
|
{
|
||||||
|
"Pending" or "ایجاد شده" => 0,
|
||||||
|
"Calculated" or "محاسبه شده" => 1,
|
||||||
|
"Paid" or "پرداخت شده" => 2,
|
||||||
|
"Withdrawn" or "برداشت شده" => 3,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = await _client.GetMyCommissionPayoutsAsync(request);
|
||||||
|
|
||||||
|
return new CommissionPayoutsResponseDto
|
||||||
|
{
|
||||||
|
Payouts = response.Payouts.Select(p => new CommissionPayoutDto
|
||||||
|
{
|
||||||
|
Id = p.Id,
|
||||||
|
WeekNumber = ExtractWeekNumber(p.WeekNumber),
|
||||||
|
WeekLabel = p.WeekLabel,
|
||||||
|
BalancesEarned = p.BalancesEarned,
|
||||||
|
TotalAmount = p.TotalAmount,
|
||||||
|
AmountFormatted = p.AmountFormatted,
|
||||||
|
Status = p.Status,
|
||||||
|
StatusBadgeColor = p.StatusBadgeColor,
|
||||||
|
DatePersian = p.DatePersian
|
||||||
|
}).ToList(),
|
||||||
|
TotalCount = (int)(response.MetaData?.TotalCount ?? 0),
|
||||||
|
PageNumber = pageNumber,
|
||||||
|
PageSize = pageSize
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Fallback to mock data if backend is unavailable
|
||||||
|
return GenerateMockPayoutsResponse(weekNumber, status, pageNumber, pageSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await Task.Delay(500); // Simulate network delay
|
/// <summary>
|
||||||
|
/// Get weekly balance details for a specific week
|
||||||
|
/// Maps to: CommissionCQ.GetMyWeeklyBalances
|
||||||
|
/// </summary>
|
||||||
|
public async Task<WeeklyBalanceDto> GetMyWeeklyBalanceAsync(int? weekNumber = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var request = new GetMyWeeklyBalancesRequest
|
||||||
|
{
|
||||||
|
PageNumber = 1,
|
||||||
|
PageSize = 1,
|
||||||
|
OnlyActive = false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (weekNumber.HasValue)
|
||||||
|
{
|
||||||
|
request.WeekNumber = $"2025-W{weekNumber:D2}";
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = await _client.GetMyWeeklyBalancesAsync(request);
|
||||||
|
|
||||||
|
if (response.Balances.Count > 0)
|
||||||
|
{
|
||||||
|
var balance = response.Balances[0];
|
||||||
|
return new WeeklyBalanceDto
|
||||||
|
{
|
||||||
|
WeekNumber = ExtractWeekNumber(balance.WeekNumber),
|
||||||
|
WeekLabel = $"هفته {ExtractWeekNumber(balance.WeekNumber)} - سال 1404",
|
||||||
|
LeftBalance = balance.LeftLegBalances,
|
||||||
|
RightBalance = balance.RightLegBalances,
|
||||||
|
MinBalance = Math.Min(balance.LeftLegBalances, balance.RightLegBalances),
|
||||||
|
BalanceCount = balance.TotalBalances,
|
||||||
|
CalculatedCommission = balance.WeeklyPoolContribution,
|
||||||
|
LeftCarryover = Math.Max(0, balance.LeftLegBalances - balance.RightLegBalances),
|
||||||
|
RightCarryover = Math.Max(0, balance.RightLegBalances - balance.LeftLegBalances),
|
||||||
|
StartDate = balance.CalculatedAt?.ToDateTime().AddDays(-7) ?? DateTime.Now.AddDays(-7),
|
||||||
|
EndDate = balance.CalculatedAt?.ToDateTime() ?? DateTime.Now
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return CreateMockWeeklyBalance(weekNumber ?? 45);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return CreateMockWeeklyBalance(weekNumber ?? 45);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mock data
|
#region Helper Methods
|
||||||
|
|
||||||
|
private static int ExtractWeekNumber(string weekNumberStr)
|
||||||
|
{
|
||||||
|
// Format: "2025-W48" → 48
|
||||||
|
if (string.IsNullOrEmpty(weekNumberStr)) return 0;
|
||||||
|
|
||||||
|
var parts = weekNumberStr.Split('W');
|
||||||
|
if (parts.Length > 1 && int.TryParse(parts[1], out var week))
|
||||||
|
{
|
||||||
|
return week;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static WeeklyBalanceDto CreateMockWeeklyBalance(int weekNumber)
|
||||||
|
{
|
||||||
|
return new WeeklyBalanceDto
|
||||||
|
{
|
||||||
|
WeekNumber = weekNumber,
|
||||||
|
WeekLabel = $"هفته {weekNumber} - سال 1404",
|
||||||
|
LeftBalance = 15_000_000,
|
||||||
|
RightBalance = 12_000_000,
|
||||||
|
MinBalance = 12_000_000,
|
||||||
|
BalanceCount = 12,
|
||||||
|
CalculatedCommission = 1_200_000,
|
||||||
|
LeftCarryover = 3_000_000,
|
||||||
|
RightCarryover = 0,
|
||||||
|
StartDate = DateTime.Now.AddDays(-7),
|
||||||
|
EndDate = DateTime.Now
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CommissionPayoutsResponseDto GenerateMockPayoutsResponse(
|
||||||
|
int? weekNumber, string? status, int pageNumber, int pageSize)
|
||||||
|
{
|
||||||
var allPayouts = GenerateMockPayouts(50);
|
var allPayouts = GenerateMockPayouts(50);
|
||||||
|
|
||||||
// Apply filters
|
|
||||||
var filtered = allPayouts.AsEnumerable();
|
var filtered = allPayouts.AsEnumerable();
|
||||||
if (weekNumber.HasValue)
|
if (weekNumber.HasValue)
|
||||||
filtered = filtered.Where(p => p.WeekNumber == weekNumber.Value);
|
filtered = filtered.Where(p => p.WeekNumber == weekNumber.Value);
|
||||||
@@ -59,62 +184,25 @@ public class CommissionService
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get weekly balance details for a specific week
|
|
||||||
/// Maps to: CommissionCQ.GetMyWeeklyBalances
|
|
||||||
/// </summary>
|
|
||||||
public async Task<WeeklyBalanceDto> GetMyWeeklyBalanceAsync(int? weekNumber = null)
|
|
||||||
{
|
|
||||||
// TODO: Replace with actual gRPC call to BFF
|
|
||||||
// var request = new GetMyWeeklyBalancesRequest
|
|
||||||
// {
|
|
||||||
// WeekNumber = weekNumber
|
|
||||||
// };
|
|
||||||
// var response = await _client.GetMyWeeklyBalancesAsync(request);
|
|
||||||
// return MapToDto(response);
|
|
||||||
|
|
||||||
await Task.Delay(500); // Simulate network delay
|
|
||||||
|
|
||||||
// Mock current week data
|
|
||||||
var currentWeek = weekNumber ?? 45;
|
|
||||||
return new WeeklyBalanceDto
|
|
||||||
{
|
|
||||||
WeekNumber = currentWeek,
|
|
||||||
WeekLabel = $"هفته {currentWeek} - سال 1404",
|
|
||||||
LeftBalance = 15_000_000,
|
|
||||||
RightBalance = 12_000_000,
|
|
||||||
MinBalance = 12_000_000,
|
|
||||||
BalanceCount = 12,
|
|
||||||
CalculatedCommission = 1_200_000,
|
|
||||||
LeftCarryover = 3_000_000,
|
|
||||||
RightCarryover = 0,
|
|
||||||
StartDate = DateTime.Now.AddDays(-7),
|
|
||||||
EndDate = DateTime.Now
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Mock Data Helpers
|
|
||||||
|
|
||||||
private static List<CommissionPayoutDto> GenerateMockPayouts(int count)
|
private static List<CommissionPayoutDto> GenerateMockPayouts(int count)
|
||||||
{
|
{
|
||||||
var payouts = new List<CommissionPayoutDto>();
|
var payouts = new List<CommissionPayoutDto>();
|
||||||
var random = new Random();
|
var random = new Random();
|
||||||
var statuses = new[] { "Created", "Paid", "WithdrawalRequested", "Withdrawn", "Cancelled" };
|
|
||||||
var statusColors = new[] { "Info", "Success", "Warning", "Success", "Error" };
|
|
||||||
var statusTexts = new[] { "ایجاد شده", "پرداخت شده", "درخواست برداشت", "برداشت شده", "لغو شده" };
|
var statusTexts = new[] { "ایجاد شده", "پرداخت شده", "درخواست برداشت", "برداشت شده", "لغو شده" };
|
||||||
|
var statusColors = new[] { "Info", "Success", "Warning", "Success", "Error" };
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var statusIndex = random.Next(statuses.Length);
|
var statusIndex = random.Next(statusTexts.Length);
|
||||||
var weekNumber = 50 - i;
|
var weekNum = 50 - i;
|
||||||
var balances = random.Next(5, 20);
|
var balances = random.Next(5, 20);
|
||||||
var amount = balances * 100_000;
|
var amount = balances * 100_000;
|
||||||
|
|
||||||
payouts.Add(new CommissionPayoutDto
|
payouts.Add(new CommissionPayoutDto
|
||||||
{
|
{
|
||||||
Id = i + 1,
|
Id = i + 1,
|
||||||
WeekNumber = weekNumber,
|
WeekNumber = weekNum,
|
||||||
WeekLabel = $"هفته {weekNumber} - سال 1404",
|
WeekLabel = $"هفته {weekNum} - سال 1404",
|
||||||
BalancesEarned = balances,
|
BalancesEarned = balances,
|
||||||
TotalAmount = amount,
|
TotalAmount = amount,
|
||||||
AmountFormatted = $"{amount:N0} تومان",
|
AmountFormatted = $"{amount:N0} تومان",
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
|
using FrontOffice.BFF.NetworkMembership.Protobuf.Protos.NetworkMembership;
|
||||||
|
using Google.Protobuf.WellKnownTypes;
|
||||||
|
|
||||||
namespace FrontOffice.Main.Utilities;
|
namespace FrontOffice.Main.Utilities;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Service for Network Membership operations
|
/// Service for Network Membership operations
|
||||||
/// TODO: Connect to FrontOffice.BFF gRPC NetworkMembershipCQ
|
/// Connected to FrontOffice.BFF gRPC NetworkMembershipCQ
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class NetworkMembershipService
|
public class NetworkMembershipService
|
||||||
{
|
{
|
||||||
// TODO: Inject gRPC client when FrontOffice connects to BFF
|
private readonly NetworkMembershipContract.NetworkMembershipContractClient _client;
|
||||||
// private readonly NetworkMembershipContract.NetworkMembershipContractClient _client;
|
|
||||||
|
|
||||||
public NetworkMembershipService()
|
public NetworkMembershipService(NetworkMembershipContract.NetworkMembershipContractClient client)
|
||||||
{
|
{
|
||||||
// TODO: Initialize gRPC client
|
_client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -20,14 +22,93 @@ public class NetworkMembershipService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<NetworkTreeDto> GetMyNetworkTreeAsync(int maxDepth = 3)
|
public async Task<NetworkTreeDto> GetMyNetworkTreeAsync(int maxDepth = 3)
|
||||||
{
|
{
|
||||||
// TODO: Replace with actual gRPC call to BFF
|
try
|
||||||
// var request = new GetMyNetworkTreeRequest { MaxDepth = maxDepth };
|
{
|
||||||
// var response = await _client.GetMyNetworkTreeAsync(request);
|
var request = new GetMyNetworkTreeRequest { MaxDepth = maxDepth };
|
||||||
// return MapToDto(response);
|
var response = await _client.GetMyNetworkTreeAsync(request);
|
||||||
|
|
||||||
|
return new NetworkTreeDto
|
||||||
|
{
|
||||||
|
RootNode = MapNodeFromProto(response.RootNode),
|
||||||
|
TotalMembers = response.TotalMembers,
|
||||||
|
CurrentDepth = response.CurrentDepth
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Fallback to mock data if backend is unavailable
|
||||||
|
return CreateMockTree();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await Task.Delay(500); // Simulate network delay
|
/// <summary>
|
||||||
|
/// Get current user's network statistics
|
||||||
|
/// Maps to: NetworkMembershipCQ.GetMyNetworkStatistics
|
||||||
|
/// </summary>
|
||||||
|
public async Task<NetworkStatisticsDto> GetMyNetworkStatisticsAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var response = await _client.GetMyNetworkStatisticsAsync(new Empty());
|
||||||
|
|
||||||
|
return new NetworkStatisticsDto
|
||||||
|
{
|
||||||
|
LeftLegCount = response.LeftLegCount,
|
||||||
|
RightLegCount = response.RightLegCount,
|
||||||
|
TotalMembers = response.TotalMembers,
|
||||||
|
TreeDepth = response.MaxDepth,
|
||||||
|
WeakerLeg = response.WeakerLeg,
|
||||||
|
LastMember = response.LastMember != null ? new LastMemberDto
|
||||||
|
{
|
||||||
|
UserId = response.LastMember.UserId,
|
||||||
|
FullName = response.LastMember.FullName,
|
||||||
|
Position = response.LastMember.Position,
|
||||||
|
JoinedAt = DateTime.Now // TODO: Add JoinedAt to proto
|
||||||
|
} : null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Fallback to mock data if backend is unavailable
|
||||||
|
return new NetworkStatisticsDto
|
||||||
|
{
|
||||||
|
LeftLegCount = 15,
|
||||||
|
RightLegCount = 12,
|
||||||
|
TotalMembers = 27,
|
||||||
|
TreeDepth = 4,
|
||||||
|
WeakerLeg = "Right",
|
||||||
|
LastMember = new LastMemberDto
|
||||||
|
{
|
||||||
|
UserId = 28,
|
||||||
|
FullName = "محمد رضایی",
|
||||||
|
Position = "Left",
|
||||||
|
JoinedAt = DateTime.Now.AddHours(-2)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mock data with sample tree
|
#region Helper Methods
|
||||||
|
|
||||||
|
private static NetworkNodeDto? MapNodeFromProto(NetworkNodeModel? node)
|
||||||
|
{
|
||||||
|
if (node == null) return null;
|
||||||
|
|
||||||
|
return new NetworkNodeDto
|
||||||
|
{
|
||||||
|
UserId = node.UserId,
|
||||||
|
FullName = node.FullName,
|
||||||
|
Mobile = node.Mobile,
|
||||||
|
Avatar = node.Avatar,
|
||||||
|
Position = node.Position,
|
||||||
|
Level = node.Level,
|
||||||
|
LeftChild = MapNodeFromProto(node.LeftChild),
|
||||||
|
RightChild = MapNodeFromProto(node.RightChild)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NetworkTreeDto CreateMockTree()
|
||||||
|
{
|
||||||
return new NetworkTreeDto
|
return new NetworkTreeDto
|
||||||
{
|
{
|
||||||
CurrentDepth = 2,
|
CurrentDepth = 2,
|
||||||
@@ -45,15 +126,7 @@ public class NetworkMembershipService
|
|||||||
FullName = "علی محمدی",
|
FullName = "علی محمدی",
|
||||||
Mobile = "09121234568",
|
Mobile = "09121234568",
|
||||||
Position = "Left",
|
Position = "Left",
|
||||||
Level = 1,
|
Level = 1
|
||||||
LeftChild = new NetworkNodeDto
|
|
||||||
{
|
|
||||||
UserId = 4,
|
|
||||||
FullName = "رضا احمدی",
|
|
||||||
Mobile = "09121234570",
|
|
||||||
Position = "Left",
|
|
||||||
Level = 2
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
RightChild = new NetworkNodeDto
|
RightChild = new NetworkNodeDto
|
||||||
{
|
{
|
||||||
@@ -61,48 +134,11 @@ public class NetworkMembershipService
|
|||||||
FullName = "فاطمه حسینی",
|
FullName = "فاطمه حسینی",
|
||||||
Mobile = "09121234569",
|
Mobile = "09121234569",
|
||||||
Position = "Right",
|
Position = "Right",
|
||||||
Level = 1,
|
Level = 1
|
||||||
RightChild = new NetworkNodeDto
|
|
||||||
{
|
|
||||||
UserId = 5,
|
|
||||||
FullName = "زهرا کریمی",
|
|
||||||
Mobile = "09121234571",
|
|
||||||
Position = "Right",
|
|
||||||
Level = 2
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
#endregion
|
||||||
/// Get current user's network statistics
|
|
||||||
/// Maps to: NetworkMembershipCQ.GetMyNetworkStatistics
|
|
||||||
/// </summary>
|
|
||||||
public async Task<NetworkStatisticsDto> GetMyNetworkStatisticsAsync()
|
|
||||||
{
|
|
||||||
// TODO: Replace with actual gRPC call to BFF
|
|
||||||
// var request = new GetMyNetworkStatisticsRequest();
|
|
||||||
// var response = await _client.GetMyNetworkStatisticsAsync(request);
|
|
||||||
// return MapToDto(response);
|
|
||||||
|
|
||||||
await Task.Delay(500); // Simulate network delay
|
|
||||||
|
|
||||||
// Mock statistics
|
|
||||||
return new NetworkStatisticsDto
|
|
||||||
{
|
|
||||||
LeftLegCount = 15,
|
|
||||||
RightLegCount = 12,
|
|
||||||
TotalMembers = 27,
|
|
||||||
TreeDepth = 4,
|
|
||||||
WeakerLeg = "Right",
|
|
||||||
LastMember = new LastMemberDto
|
|
||||||
{
|
|
||||||
UserId = 28,
|
|
||||||
FullName = "محمد رضایی",
|
|
||||||
Position = "Left",
|
|
||||||
JoinedAt = DateTime.Now.AddHours(-2)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ public class WalletService
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = await _client.GetUserWalletAsync(new Empty());
|
var response = await _client.GetUserWalletAsync(new Empty());
|
||||||
// TODO: DiscountBalance will be added in BFF protobuf later
|
return new WalletBalances(response.Balance, response.DiscountBalance, response.NetworkBalance);
|
||||||
return new WalletBalances(response.Balance, 0 /* response.DiscountBalance */, response.NetworkBalance);
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -40,9 +39,6 @@ public class WalletService
|
|||||||
|
|
||||||
public async Task<List<WalletTransaction>> GetTransactionsAsync(long? referenceId = null, bool? isIncrease = null)
|
public async Task<List<WalletTransaction>> GetTransactionsAsync(long? referenceId = null, bool? isIncrease = null)
|
||||||
{
|
{
|
||||||
// TODO: Implement when BFF protobuf has GetAllUserWalletChangeLog
|
|
||||||
await Task.CompletedTask;
|
|
||||||
/*
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var request = new GetAllUserWalletChangeLogRequest();
|
var request = new GetAllUserWalletChangeLogRequest();
|
||||||
@@ -66,7 +62,6 @@ public class WalletService
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
*/
|
|
||||||
// Fallback to mock data if backend is unavailable
|
// Fallback to mock data if backend is unavailable
|
||||||
var _transactions = new List<WalletTransaction>
|
var _transactions = new List<WalletTransaction>
|
||||||
{
|
{
|
||||||
@@ -76,7 +71,7 @@ public class WalletService
|
|||||||
new(DateTime.Now.AddDays(-9).ToString(), 900_000, "کیف پول شرکای تجاری", "اعتبار خرید"),
|
new(DateTime.Now.AddDays(-9).ToString(), 900_000, "کیف پول شرکای تجاری", "اعتبار خرید"),
|
||||||
};
|
};
|
||||||
return _transactions.OrderByDescending(t => t.Date).ToList();
|
return _transactions.OrderByDescending(t => t.Date).ToList();
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ResolveTransactionDate(GetAllUserWalletChangeLogResponseModel model)
|
private static string ResolveTransactionDate(GetAllUserWalletChangeLogResponseModel model)
|
||||||
@@ -105,10 +100,6 @@ public class WalletService
|
|||||||
|
|
||||||
public async Task<bool> RequestWithdrawalAsync(long payoutId, WithdrawalMethodClient method, string? iban)
|
public async Task<bool> RequestWithdrawalAsync(long payoutId, WithdrawalMethodClient method, string? iban)
|
||||||
{
|
{
|
||||||
// TODO: Implement when BFF protobuf has WithdrawBalance
|
|
||||||
await Task.CompletedTask;
|
|
||||||
return true;
|
|
||||||
/*
|
|
||||||
var request = new WithdrawBalanceRequest
|
var request = new WithdrawBalanceRequest
|
||||||
{
|
{
|
||||||
PayoutId = payoutId,
|
PayoutId = payoutId,
|
||||||
@@ -125,44 +116,48 @@ public class WalletService
|
|||||||
}
|
}
|
||||||
catch (Grpc.Core.RpcException ex)
|
catch (Grpc.Core.RpcException ex)
|
||||||
{
|
{
|
||||||
// surface backend error text
|
|
||||||
throw new InvalidOperationException(ex.Status.Detail ?? "خطا در ثبت برداشت", ex);
|
throw new InvalidOperationException(ex.Status.Detail ?? "خطا در ثبت برداشت", ex);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<WalletWithdrawal>> GetWithdrawalsAsync(int? status = null)
|
public async Task<List<WalletWithdrawal>> GetWithdrawalsAsync(int? status = null)
|
||||||
{
|
{
|
||||||
// TODO: Implement when BFF protobuf has GetUserWithdrawals
|
try
|
||||||
await Task.CompletedTask;
|
|
||||||
return new List<WalletWithdrawal>();
|
|
||||||
/*
|
|
||||||
var request = new GetUserWithdrawalsRequest();
|
|
||||||
if (status.HasValue)
|
|
||||||
{
|
{
|
||||||
request.Status = status.Value;
|
var request = new GetUserWithdrawalsRequest();
|
||||||
}
|
if (status.HasValue)
|
||||||
|
{
|
||||||
|
request.Status = status.Value;
|
||||||
|
}
|
||||||
|
|
||||||
var response = await _client.GetUserWithdrawalsAsync(request);
|
var response = await _client.GetUserWithdrawalsAsync(request);
|
||||||
return response.Models
|
return response.Models
|
||||||
.Select(m => new WalletWithdrawal(
|
.Select(m => new WalletWithdrawal(
|
||||||
m.Id,
|
m.Id,
|
||||||
m.WeekNumber,
|
m.WeekNumber,
|
||||||
m.TotalAmount,
|
m.TotalAmount,
|
||||||
m.Status,
|
m.Status,
|
||||||
m.WithdrawalMethod?.Value,
|
m.WithdrawalMethod,
|
||||||
m.IbanNumber,
|
m.IbanNumber,
|
||||||
m.Created.ToDateTime().MiladiToJalaliWithTime()))
|
m.Created?.ToDateTime().MiladiToJalaliWithTime() ?? "-"))
|
||||||
.ToList();
|
.ToList();
|
||||||
*/
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new List<WalletWithdrawal>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<WithdrawalSettings> GetWithdrawalSettingsAsync()
|
public async Task<WithdrawalSettings> GetWithdrawalSettingsAsync()
|
||||||
{
|
{
|
||||||
// TODO: Implement when BFF protobuf has GetWithdrawalSettings
|
try
|
||||||
await Task.CompletedTask;
|
{
|
||||||
return new WithdrawalSettings(1_000_000);
|
var response = await _client.GetWithdrawalSettingsAsync(new Empty());
|
||||||
// var response = await _client.GetWithdrawalSettingsAsync(new Empty());
|
return new WithdrawalSettings(response.MinWithdrawalAmount);
|
||||||
// return new WithdrawalSettings(response.MinWithdrawalAmount);
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new WithdrawalSettings(1_000_000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user