feat(commission): add per-package filtering to commission pages

- CommissionDtos: add PackageId + PackageTitle to CommissionPayoutDto and WeeklyBalanceDto
- CommissionService: add packageId parameter to GetMyCommissionPayoutsAsync and GetMyWeeklyBalanceAsync
- CommissionDashboardPage: add package filter dropdown + package column in desktop/mobile views
- WeeklyBalancePage: add package filter dropdown + package chip in balance info section
- Update NuGet Foursat.CMSMicroservice.Protobuf to v0.0.187
This commit is contained in:
masoodafar-web
2026-02-26 21:08:30 +03:30
parent 40882c8b80
commit a956cb90a1
7 changed files with 102 additions and 21 deletions
+1 -1
View File
@@ -11,7 +11,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="DateTimeConverterCL" Version="1.0.0" /> <PackageReference Include="DateTimeConverterCL" Version="1.0.0" />
<!-- Replace all FrontOffice.BFF protobuf packages with CMS protobuf --> <!-- Replace all FrontOffice.BFF protobuf packages with CMS protobuf -->
<PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.186" /> <PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.187" />
<!-- <ProjectReference Include="../../../CMS/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj" />--> <!-- <ProjectReference Include="../../../CMS/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj" />-->
<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" />
@@ -13,7 +13,7 @@
<!-- فیلترها --> <!-- فیلترها -->
<MudPaper Elevation="2" Class="pa-3 rounded-lg"> <MudPaper Elevation="2" Class="pa-3 rounded-lg">
<MudGrid Spacing="2"> <MudGrid Spacing="2">
<MudItem xs="12" sm="6" md="4"> <MudItem xs="12" sm="6" md="3">
<WeekSelector @ref="_weekSelector" <WeekSelector @ref="_weekSelector"
@bind-Value="_selectedWeekDefinition" @bind-Value="_selectedWeekDefinition"
Label="انتخاب هفته" Label="انتخاب هفته"
@@ -23,7 +23,7 @@
Clearable="true" Clearable="true"
OnlyActive="false" /> OnlyActive="false" />
</MudItem> </MudItem>
<MudItem xs="12" sm="6" md="4"> <MudItem xs="12" sm="6" md="3">
<MudSelect T="string" @bind-Value="_filterStatus" Label="وضعیت" Variant="Variant.Outlined"> <MudSelect T="string" @bind-Value="_filterStatus" Label="وضعیت" Variant="Variant.Outlined">
<MudSelectItem T="string" Value="@string.Empty">همه</MudSelectItem> <MudSelectItem T="string" Value="@string.Empty">همه</MudSelectItem>
<MudSelectItem T="string" Value="@("Pending")">در انتظار</MudSelectItem> <MudSelectItem T="string" Value="@("Pending")">در انتظار</MudSelectItem>
@@ -34,7 +34,16 @@
<MudSelectItem T="string" Value="@("Cancelled")">لغو شده</MudSelectItem> <MudSelectItem T="string" Value="@("Cancelled")">لغو شده</MudSelectItem>
</MudSelect> </MudSelect>
</MudItem> </MudItem>
<MudItem xs="12" sm="12" md="4"> <MudItem xs="12" sm="6" md="3">
<MudSelect T="long?" @bind-Value="_filterPackageId" Label="پکیج" Variant="Variant.Outlined" Clearable="true">
<MudSelectItem T="long?" Value="@((long?)null)">همه پکیج‌ها</MudSelectItem>
@foreach (var pkg in _packages)
{
<MudSelectItem T="long?" Value="@((long?)pkg.Id)">@pkg.Title</MudSelectItem>
}
</MudSelect>
</MudItem>
<MudItem xs="12" sm="6" md="3">
<MudStack Row="true" Spacing="2" Style="height: 100%;" AlignItems="AlignItems.End"> <MudStack Row="true" Spacing="2" Style="height: 100%;" AlignItems="AlignItems.End">
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="ApplyFiltersAsync" StartIcon="@Icons.Material.Filled.FilterList" FullWidth="true"> <MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="ApplyFiltersAsync" StartIcon="@Icons.Material.Filled.FilterList" FullWidth="true">
اعمال فیلتر اعمال فیلتر
@@ -87,6 +96,7 @@
<MudTable Items="_payouts" Hover="true" Striped="true" Dense="true" FixedHeader="true" Height="400px"> <MudTable Items="_payouts" Hover="true" Striped="true" Dense="true" FixedHeader="true" Height="400px">
<HeaderContent> <HeaderContent>
<MudTh>هفته</MudTh> <MudTh>هفته</MudTh>
<MudTh>پکیج</MudTh>
<MudTh>امتیاز</MudTh> <MudTh>امتیاز</MudTh>
<MudTh>مبلغ (تومان)</MudTh> <MudTh>مبلغ (تومان)</MudTh>
<MudTh>وضعیت</MudTh> <MudTh>وضعیت</MudTh>
@@ -97,6 +107,11 @@
<MudTd DataLabel="هفته"> <MudTd DataLabel="هفته">
<MudChip T="string" Color="Color.Primary" Size="Size.Small" Variant="Variant.Outlined">@context.WeekDisplayName</MudChip> <MudChip T="string" Color="Color.Primary" Size="Size.Small" Variant="Variant.Outlined">@context.WeekDisplayName</MudChip>
</MudTd> </MudTd>
<MudTd DataLabel="پکیج">
<MudChip T="string" Color="Color.Tertiary" Size="Size.Small">
@(string.IsNullOrEmpty(context.PackageTitle) ? "-" : context.PackageTitle)
</MudChip>
</MudTd>
<MudTd DataLabel="امتیاز">@context.BalancesEarned</MudTd> <MudTd DataLabel="امتیاز">@context.BalancesEarned</MudTd>
<MudTd DataLabel="مبلغ"> <MudTd DataLabel="مبلغ">
<MudText Color="Color.Success"><strong>@context.AmountFormatted</strong></MudText> <MudText Color="Color.Success"><strong>@context.AmountFormatted</strong></MudText>
@@ -127,6 +142,10 @@
<MudChip T="string" Color="Color.Primary" Size="Size.Small" Variant="Variant.Outlined">@payout.WeekDisplayName</MudChip> <MudChip T="string" Color="Color.Primary" Size="Size.Small" Variant="Variant.Outlined">@payout.WeekDisplayName</MudChip>
<MudChip T="string" Color="@GetStatusColor(payout.StatusColor)" Size="Size.Small">@payout.StatusText</MudChip> <MudChip T="string" Color="@GetStatusColor(payout.StatusColor)" Size="Size.Small">@payout.StatusText</MudChip>
</MudStack> </MudStack>
@if (!string.IsNullOrEmpty(payout.PackageTitle))
{
<MudChip T="string" Color="Color.Tertiary" Size="Size.Small">@payout.PackageTitle</MudChip>
}
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center"> <MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center">
<MudText Typo="Typo.h6" Color="Color.Success">@payout.AmountFormatted</MudText> <MudText Typo="Typo.h6" Color="Color.Success">@payout.AmountFormatted</MudText>
<MudText Typo="Typo.caption" Class="mud-text-secondary">امتیاز: @payout.BalancesEarned</MudText> <MudText Typo="Typo.caption" Class="mud-text-secondary">امتیاز: @payout.BalancesEarned</MudText>
@@ -8,8 +8,10 @@ namespace FrontOffice.Main.Pages.Commission;
public partial class CommissionDashboardPage : ComponentBase public partial class CommissionDashboardPage : ComponentBase
{ {
[Inject] private CommissionService CommissionService { get; set; } = default!; [Inject] private CommissionService CommissionService { get; set; } = default!;
[Inject] private PackageService PackageService { get; set; } = default!;
private List<CommissionPayoutDto> _payouts = new(); private List<CommissionPayoutDto> _payouts = new();
private List<PackageDto> _packages = new();
private int _totalCount; private int _totalCount;
private long _totalAmount; private long _totalAmount;
private int _pageNumber = 1; private int _pageNumber = 1;
@@ -19,12 +21,26 @@ public partial class CommissionDashboardPage : ComponentBase
private WeekSelector? _weekSelector; private WeekSelector? _weekSelector;
private WeekDefinitionDto? _selectedWeekDefinition; private WeekDefinitionDto? _selectedWeekDefinition;
private string _filterStatus = string.Empty; private string _filterStatus = string.Empty;
private long? _filterPackageId;
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
await LoadPackagesAsync();
await LoadPayoutsAsync(); await LoadPayoutsAsync();
} }
private async Task LoadPackagesAsync()
{
try
{
_packages = await PackageService.GetAllPackagesAsync();
}
catch
{
_packages = new List<PackageDto>();
}
}
private async Task LoadPayoutsAsync() private async Task LoadPayoutsAsync()
{ {
try try
@@ -35,7 +51,8 @@ public partial class CommissionDashboardPage : ComponentBase
weekDefinitionId, weekDefinitionId,
_filterStatus, _filterStatus,
_pageNumber, _pageNumber,
_pageSize _pageSize,
_filterPackageId
); );
_payouts = result.Payouts; _payouts = result.Payouts;
_totalCount = result.TotalCount; _totalCount = result.TotalCount;
@@ -61,6 +78,7 @@ public partial class CommissionDashboardPage : ComponentBase
{ {
_selectedWeekDefinition = null; _selectedWeekDefinition = null;
_filterStatus = string.Empty; _filterStatus = string.Empty;
_filterPackageId = null;
_pageNumber = 1; _pageNumber = 1;
await LoadPayoutsAsync(); await LoadPayoutsAsync();
} }
@@ -12,7 +12,7 @@
<!-- انتخاب هفته --> <!-- انتخاب هفته -->
<MudPaper Elevation="2" Class="pa-3 rounded-lg"> <MudPaper Elevation="2" Class="pa-3 rounded-lg">
<MudGrid Spacing="2"> <MudGrid Spacing="2">
<MudItem xs="8" sm="6" md="6"> <MudItem xs="8" sm="4" md="4">
<WeekSelector @ref="_weekSelector" <WeekSelector @ref="_weekSelector"
@bind-Value="_selectedWeekDefinition" @bind-Value="_selectedWeekDefinition"
Label="انتخاب هفته" Label="انتخاب هفته"
@@ -21,15 +21,15 @@
Dense="false" Dense="false"
OnlyActive="true" /> OnlyActive="true" />
</MudItem> </MudItem>
@* <MudItem xs="4" sm="3" md="3"> *@ <MudItem xs="4" sm="4" md="4">
@* <MudButton Variant="Variant.Outlined" *@ <MudSelect T="long?" @bind-Value="_filterPackageId" Label="پکیج" Variant="Variant.Outlined" Clearable="true">
@* OnClick="LoadCurrentWeekAsync" *@ <MudSelectItem T="long?" Value="@((long?)null)">همه پکیج‌ها</MudSelectItem>
@* StartIcon="@Icons.Material.Filled.Today" *@ @foreach (var pkg in _packages)
@* FullWidth="true" *@ {
@* Style="height: 56px;"> *@ <MudSelectItem T="long?" Value="@((long?)pkg.Id)">@pkg.Title</MudSelectItem>
@* هفته جاری *@ }
@* </MudButton> *@ </MudSelect>
@* </MudItem> *@ </MudItem>
<MudItem xs="4" sm="3" md="3" Class="pt-6"> <MudItem xs="4" sm="3" md="3" Class="pt-6">
<MudButton Variant="Variant.Filled" <MudButton Variant="Variant.Filled"
Color="Color.Primary" Color="Color.Primary"
@@ -66,6 +66,12 @@
<MudItem xs="6" sm="4"> <MudItem xs="6" sm="4">
<MudText Typo="Typo.caption" Class="mud-text-secondary">پایان: <strong>@_weeklyBalance.EndDatePersian</strong></MudText> <MudText Typo="Typo.caption" Class="mud-text-secondary">پایان: <strong>@_weeklyBalance.EndDatePersian</strong></MudText>
</MudItem> </MudItem>
@if (!string.IsNullOrEmpty(_weeklyBalance.PackageTitle))
{
<MudItem xs="12" sm="12">
<MudChip T="string" Color="Color.Info" Size="Size.Small" Icon="@Icons.Material.Filled.Inventory2">@_weeklyBalance.PackageTitle</MudChip>
</MudItem>
}
</MudGrid> </MudGrid>
</MudPaper> </MudPaper>
@@ -8,6 +8,7 @@ namespace FrontOffice.Main.Pages.Commission;
public partial class WeeklyBalancePage : ComponentBase public partial class WeeklyBalancePage : ComponentBase
{ {
[Inject] private CommissionService CommissionService { get; set; } = default!; [Inject] private CommissionService CommissionService { get; set; } = default!;
[Inject] private PackageService PackageService { get; set; } = default!;
[Inject] private ISnackbar SnackbarService { get; set; } = default!; [Inject] private ISnackbar SnackbarService { get; set; } = default!;
[Parameter] [Parameter]
@@ -17,6 +18,8 @@ public partial class WeeklyBalancePage : ComponentBase
private WeekSelector? _weekSelector; private WeekSelector? _weekSelector;
private WeekDefinitionDto? _selectedWeekDefinition; private WeekDefinitionDto? _selectedWeekDefinition;
private WeeklyBalanceDto? _weeklyBalance; private WeeklyBalanceDto? _weeklyBalance;
private List<PackageDto> _packages = new();
private long? _filterPackageId;
private bool _isLoading = true; private bool _isLoading = true;
private bool _hasError = false; private bool _hasError = false;
@@ -34,6 +37,8 @@ public partial class WeeklyBalancePage : ComponentBase
{ {
if (firstRender) if (firstRender)
{ {
await LoadPackagesAsync();
// Wait for WeekSelector to initialize and load its cached weeks // Wait for WeekSelector to initialize and load its cached weeks
if (_weekSelector != null) if (_weekSelector != null)
{ {
@@ -88,7 +93,7 @@ public partial class WeeklyBalancePage : ComponentBase
long? weekDefinitionId = _selectedWeekDefinition?.Id; long? weekDefinitionId = _selectedWeekDefinition?.Id;
_weeklyBalance = await CommissionService.GetMyWeeklyBalanceAsync(weekDefinitionId); _weeklyBalance = await CommissionService.GetMyWeeklyBalanceAsync(weekDefinitionId, _filterPackageId);
// Update week display name from selected definition if available // Update week display name from selected definition if available
if (_selectedWeekDefinition != null && _weeklyBalance != null) if (_selectedWeekDefinition != null && _weeklyBalance != null)
@@ -113,6 +118,18 @@ public partial class WeeklyBalancePage : ComponentBase
} }
} }
private async Task LoadPackagesAsync()
{
try
{
_packages = await PackageService.GetAllPackagesAsync();
}
catch
{
_packages = new();
}
}
private async Task LoadCurrentWeekAsync() private async Task LoadCurrentWeekAsync()
{ {
if (_weekSelector != null) if (_weekSelector != null)
@@ -15,6 +15,8 @@ public class CommissionPayoutDto
public string AmountFormatted { get; set; } = string.Empty; public string AmountFormatted { get; set; } = string.Empty;
public int Status { get; set; } public int Status { get; set; }
public string DatePersian { get; set; } = string.Empty; public string DatePersian { get; set; } = string.Empty;
public long PackageId { get; set; }
public string PackageTitle { get; set; } = string.Empty;
// Computed properties for UI // Computed properties for UI
public string StatusText => Status switch public string StatusText => Status switch
@@ -69,6 +71,8 @@ public class WeeklyBalanceDto
public int RightNewMembers { get; set; } public int RightNewMembers { get; set; }
public DateTime StartDate { get; set; } public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; } public DateTime EndDate { get; set; }
public long PackageId { get; set; }
public string PackageTitle { get; set; } = string.Empty;
// Formatted properties // Formatted properties
public string LeftBalanceFormatted => $"{LeftBalance:N0} "; public string LeftBalanceFormatted => $"{LeftBalance:N0} ";
@@ -78,7 +78,8 @@ public class CommissionService
long? weekDefinitionId, long? weekDefinitionId,
string? status, string? status,
int pageNumber, int pageNumber,
int pageSize) int pageSize,
long? packageId = null)
{ {
try try
{ {
@@ -108,6 +109,11 @@ public class CommissionService
}; };
} }
if (packageId.HasValue && packageId.Value > 0)
{
request.PackageId = packageId.Value;
}
var response = await _client.GetMyCommissionPayoutsAsync(request); var response = await _client.GetMyCommissionPayoutsAsync(request);
return new CommissionPayoutsResponseDto return new CommissionPayoutsResponseDto
@@ -121,7 +127,9 @@ public class CommissionService
TotalAmount = p.TotalAmount, TotalAmount = p.TotalAmount,
AmountFormatted = p.AmountFormatted, AmountFormatted = p.AmountFormatted,
Status = p.Status, Status = p.Status,
DatePersian = p.DatePersian DatePersian = p.DatePersian,
PackageId = p.PackageId,
PackageTitle = p.PackageTitle
}).ToList(), }).ToList(),
TotalCount = (int)(response.MetaData?.TotalCount ?? 0), TotalCount = (int)(response.MetaData?.TotalCount ?? 0),
PageNumber = pageNumber, PageNumber = pageNumber,
@@ -145,7 +153,7 @@ public class CommissionService
/// Get weekly balance details for a specific week /// Get weekly balance details for a specific week
/// Maps to: CommissionCQ.GetMyWeeklyBalances /// Maps to: CommissionCQ.GetMyWeeklyBalances
/// </summary> /// </summary>
public async Task<WeeklyBalanceDto> GetMyWeeklyBalanceAsync(long? weekDefinitionId = null) public async Task<WeeklyBalanceDto> GetMyWeeklyBalanceAsync(long? weekDefinitionId = null, long? packageId = null)
{ {
try try
{ {
@@ -164,6 +172,11 @@ public class CommissionService
request.WeekDefinitionId=7; request.WeekDefinitionId=7;
} }
if (packageId.HasValue && packageId.Value > 0)
{
request.PackageId = packageId.Value;
}
var response = await _client.GetMyWeeklyBalancesAsync(request); var response = await _client.GetMyWeeklyBalancesAsync(request);
if (response.Balances.Count > 0) if (response.Balances.Count > 0)
@@ -183,7 +196,9 @@ public class CommissionService
LeftNewMembers = balance.LeftLegNewMembers, LeftNewMembers = balance.LeftLegNewMembers,
RightNewMembers = balance.RightLegNewMembers, RightNewMembers = balance.RightLegNewMembers,
StartDate = balance.CalculatedAt?.ToDateTime().AddDays(-7) ?? DateTime.Now.AddDays(-7), StartDate = balance.CalculatedAt?.ToDateTime().AddDays(-7) ?? DateTime.Now.AddDays(-7),
EndDate = balance.CalculatedAt?.ToDateTime() ?? DateTime.Now EndDate = balance.CalculatedAt?.ToDateTime() ?? DateTime.Now,
PackageId = balance.PackageId,
PackageTitle = balance.PackageTitle
}; };
} }
@@ -227,7 +242,9 @@ public class CommissionService
TotalAmount = p.TotalAmount, TotalAmount = p.TotalAmount,
AmountFormatted = p.AmountFormatted, AmountFormatted = p.AmountFormatted,
Status = p.Status, Status = p.Status,
DatePersian = p.DatePersian DatePersian = p.DatePersian,
PackageId = p.PackageId,
PackageTitle = p.PackageTitle
}).ToList(); }).ToList();
} }
catch catch