feat(commission): add per-package filtering to commission & balance queries

- Proto: add package_id filter to 4 request messages, package_id/package_title to 4 response models
- Queries: add PackageId filter to GetUserWeeklyBalances, GetUserCommissionPayouts, GetMyCommissionPayouts, GetMyWeeklyBalances
- Handlers: include Package navigation, filter by PackageId, map PackageId/PackageTitle
- DTOs: add PackageId + PackageTitle to all response models
- Mappings: update CommissionProfile with PackageId/PackageTitle for all admin+customer mappings
- NuGet: bump proto version to 0.0.187
This commit is contained in:
masoodafar-web
2026-02-26 21:07:59 +03:30
parent 7554d7054a
commit aaaf7fc1ca
14 changed files with 89 additions and 8 deletions
@@ -18,6 +18,11 @@ public record GetMyCommissionPayoutsQuery : IRequest<GetMyCommissionPayoutsRespo
/// </summary>
public long? WeekDefinitionId { get; init; }
/// <summary>
/// فیلتر بر اساس پکیج (اختیاری)
/// </summary>
public long? PackageId { get; init; }
/// <summary>
/// Pagination
/// </summary>
@@ -28,6 +28,7 @@ public class GetMyCommissionPayoutsQueryHandler : IRequestHandler<GetMyCommissio
var query = _context.UserCommissionPayouts
.Include(x => x.WeekDefinition)
.Include(x => x.Package)
.Where(x => x.UserId == userId)
.AsNoTracking()
.AsQueryable();
@@ -43,6 +44,12 @@ public class GetMyCommissionPayoutsQueryHandler : IRequestHandler<GetMyCommissio
query = query.Where(x => x.WeekDefinitionId == request.WeekDefinitionId.Value);
}
// فیلتر بر اساس پکیج
if (request.PackageId.HasValue && request.PackageId.Value > 0)
{
query = query.Where(x => x.PackageId == request.PackageId.Value);
}
// مرتب‌سازی: جدیدترین اول
query = query.OrderByDescending(x => x.Created);
@@ -60,7 +67,9 @@ public class GetMyCommissionPayoutsQueryHandler : IRequestHandler<GetMyCommissio
AmountFormatted = x.TotalAmount.ToString("N0") + " تومان",
Status = x.Status,
CalculatedDate = x.PaidAt ?? (DateTime?)x.Created,
DatePersian = ""
DatePersian = "",
PackageId = x.PackageId,
PackageTitle = x.Package != null ? x.Package.Title : ""
})
.ToListAsync(cancellationToken);
@@ -20,4 +20,8 @@ public class GetMyCommissionPayoutsResponseModel
public CommissionPayoutStatus Status { get; set; }
public DateTime? CalculatedDate { get; set; }
public string DatePersian { get; set; } = string.Empty;
// Package info
public long PackageId { get; set; }
public string PackageTitle { get; set; } = string.Empty;
}
@@ -17,6 +17,11 @@ public record GetMyWeeklyBalancesQuery : IRequest<GetUserWeeklyBalancesResponseD
/// </summary>
public bool OnlyActive { get; init; }
/// <summary>
/// فیلتر بر اساس پکیج (اختیاری)
/// </summary>
public long? PackageId { get; init; }
/// <summary>
/// Pagination
/// </summary>
@@ -38,6 +38,7 @@ public class GetMyWeeklyBalancesQueryHandler : IRequestHandler<GetMyWeeklyBalanc
{
UserId = userId,
WeekDefinitionId = request.WeekDefinitionId,
PackageId = request.PackageId,
OnlyActive = request.OnlyActive,
PaginationState = request.PaginationState
};
@@ -20,6 +20,11 @@ public record GetUserCommissionPayoutsQuery : IRequest<GetUserCommissionPayoutsR
/// </summary>
public long? WeekDefinitionId { get; init; }
/// <summary>
/// فیلتر بر اساس پکیج (اختیاری)
/// </summary>
public long? PackageId { get; init; }
/// <summary>
/// مرتب‌سازی
/// </summary>
@@ -18,6 +18,7 @@ public class GetUserCommissionPayoutsQueryHandler : IRequestHandler<GetUserCommi
var query = _context.UserCommissionPayouts
.Include(x => x.WeekDefinition)
.Include(x => x.User)
.Include(x => x.Package)
.AsNoTracking()
.AsQueryable();
@@ -41,6 +42,12 @@ public class GetUserCommissionPayoutsQueryHandler : IRequestHandler<GetUserCommi
query = query.Where(x => x.WeekDefinitionId == request.WeekDefinitionId);
}
// فیلتر بر اساس پکیج
if (request.PackageId.HasValue && request.PackageId.Value > 0)
{
query = query.Where(x => x.PackageId == request.PackageId.Value);
}
query = query.ApplyOrder(sortBy: request.SortBy ?? "Created");
var meta = await query.GetMetaData(request.PaginationState, cancellationToken);
@@ -64,7 +71,9 @@ public class GetUserCommissionPayoutsQueryHandler : IRequestHandler<GetUserCommi
WithdrawalMethod = x.WithdrawalMethod,
IbanNumber = x.IbanNumber,
WithdrawnAt = x.WithdrawnAt,
Created = x.Created
Created = x.Created,
PackageId = x.PackageId,
PackageTitle = x.Package != null ? x.Package.Title : ""
})
.ToListAsync(cancellationToken);
@@ -24,4 +24,8 @@ public class GetUserCommissionPayoutsResponseModel
public string? IbanNumber { get; set; }
public DateTime? WithdrawnAt { get; set; }
public DateTimeOffset Created { get; set; }
// Package info
public long PackageId { get; set; }
public string PackageTitle { get; set; } = string.Empty;
}
@@ -15,6 +15,10 @@ public record GetUserWeeklyBalancesQuery : IRequest<GetUserWeeklyBalancesRespons
/// </summary>
public long? WeekDefinitionId { get; init; }
/// <summary>
/// فیلتر بر اساس پکیج (اختیاری)
/// </summary>
public long? PackageId { get; init; }
/// <summary>
/// فقط موارد Expired نشده؟
@@ -18,6 +18,7 @@ public class GetUserWeeklyBalancesQueryHandler : IRequestHandler<GetUserWeeklyBa
var query = _context.NetworkWeeklyBalances
.Include(x => x.WeekDefinition)
.Include(x => x.User)
.Include(x => x.Package)
.AsNoTracking()
.AsQueryable();
@@ -43,6 +44,12 @@ public class GetUserWeeklyBalancesQueryHandler : IRequestHandler<GetUserWeeklyBa
query = query.Where(x => !x.IsExpired);
}
// فیلتر بر اساس پکیج
if (request.PackageId.HasValue && request.PackageId.Value > 0)
{
query = query.Where(x => x.PackageId == request.PackageId.Value);
}
// مرتب‌سازی بر اساس WeekDefinitionId (نزولی = جدیدترین اول)
query = query.ApplyOrder(sortBy: request.SortBy ?? "-WeekDefinitionId");
@@ -67,7 +74,9 @@ public class GetUserWeeklyBalancesQueryHandler : IRequestHandler<GetUserWeeklyBa
WeeklyPoolContribution = x.WeeklyPoolContribution,
CalculatedAt = x.CalculatedAt,
IsExpired = x.IsExpired,
Created = x.Created
Created = x.Created,
PackageId = x.PackageId,
PackageTitle = x.Package != null ? x.Package.Title : ""
})
.ToListAsync(cancellationToken);
@@ -29,4 +29,8 @@ public class GetUserWeeklyBalancesResponseModel
public DateTime? CalculatedAt { get; set; }
public bool IsExpired { get; set; }
public DateTimeOffset Created { get; set; }
// Package info
public long PackageId { get; set; }
public string PackageTitle { get; set; } = string.Empty;
}
@@ -3,7 +3,7 @@
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>0.0.186</Version>
<Version>0.0.187</Version>
<DebugType>None</DebugType>
<DebugSymbols>False</DebugSymbols>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
@@ -217,6 +217,7 @@ message GetUserCommissionPayoutsRequest
google.protobuf.Int64Value user_id = 1;
google.protobuf.Int32Value status = 2; // CommissionPayoutStatus enum
google.protobuf.Int64Value week_definition_id = 3; // Preferred filter
google.protobuf.Int64Value package_id = 4; // فیلتر بر اساس پکیج
int32 page_index = 5;
int32 page_size = 6;
}
@@ -244,6 +245,8 @@ message UserCommissionPayoutModel
string iban_number = 13;
google.protobuf.Timestamp withdrawn_at = 14;
google.protobuf.Timestamp created = 15;
int64 package_id = 16; // شناسه پکیج
string package_title = 17; // نام پکیج
}
// GetCommissionPayoutHistory Query
@@ -314,6 +317,7 @@ message GetUserWeeklyBalancesRequest
{
google.protobuf.Int64Value user_id = 1;
google.protobuf.Int64Value week_definition_id = 2; // Preferred filter
google.protobuf.Int64Value package_id = 3; // فیلتر بر اساس پکیج
bool only_active = 4; // Only non-expired balances
int32 page_index = 5;
int32 page_size = 6;
@@ -343,6 +347,8 @@ message UserWeeklyBalanceModel
google.protobuf.Timestamp calculated_at = 14;
bool is_expired = 15;
google.protobuf.Timestamp created = 16;
int64 package_id = 17; // شناسه پکیج
string package_title = 18; // نام پکیج
}
// GetAllWeeklyPools Query
@@ -598,6 +604,7 @@ message GetMyCommissionPayoutsRequest
int32 page_size = 2;
google.protobuf.Int64Value week_definition_id = 3;
google.protobuf.Int32Value status = 4; // 0=Pending, 1=Calculated, 2=Paid, 3=Withdrawn
google.protobuf.Int64Value package_id = 5; // فیلتر بر اساس پکیج
}
message GetMyCommissionPayoutsResponse
@@ -622,6 +629,8 @@ message CustomerCommissionPayoutModel
int32 status = 7; // 0=Pending, 1=Paid, 2=WithdrawRequested, 3=Withdrawn, 4=PaymentFailed, 5=Cancelled
google.protobuf.Timestamp calculated_date = 8;
string date_persian = 9;
int64 package_id = 10; // شناسه پکیج
string package_title = 11; // نام پکیج
}
// GetMyWeeklyBalances - for frontend customer display
@@ -631,6 +640,7 @@ message GetMyWeeklyBalancesRequest
int32 page_size = 2;
google.protobuf.Int64Value week_definition_id = 3;
bool only_active = 4;
google.protobuf.Int64Value package_id = 5; // فیلتر بر اساس پکیج
}
message GetMyWeeklyBalancesResponse
@@ -658,4 +668,6 @@ message CustomerWeeklyBalanceModel
int32 right_leg_carryover = 12;
int32 left_leg_new_members = 13;
int32 right_leg_new_members = 14;
int64 package_id = 15; // شناسه پکیج
string package_title = 16; // نام پکیج
}
@@ -68,7 +68,9 @@ public class CommissionProfile : IRegister
.Map(dest => dest.WithdrawnAt, src => src.WithdrawnAt.HasValue
? Timestamp.FromDateTime(src.WithdrawnAt.Value.ToUniversalTime())
: null)
.Map(dest => dest.Created, src => Timestamp.FromDateTimeOffset(src.Created));
.Map(dest => dest.Created, src => Timestamp.FromDateTimeOffset(src.Created))
.Map(dest => dest.PackageId, src => src.PackageId)
.Map(dest => dest.PackageTitle, src => src.PackageTitle);
// GetWeekDefinitions Request Mapping
config.NewConfig<GetWeekDefinitionsRequest, GetWeekDefinitionsQuery>()
@@ -127,7 +129,9 @@ public class CommissionProfile : IRegister
? Timestamp.FromDateTime(DateTime.SpecifyKind(src.CalculatedAt.Value, DateTimeKind.Utc))
: null)
.Map(dest => dest.IsExpired, src => src.IsExpired)
.Map(dest => dest.Created, src => Timestamp.FromDateTimeOffset(src.Created));
.Map(dest => dest.Created, src => Timestamp.FromDateTimeOffset(src.Created))
.Map(dest => dest.PackageId, src => src.PackageId)
.Map(dest => dest.PackageTitle, src => src.PackageTitle);
// GetMyCommissionPayouts Request Mapping
config.NewConfig<GetMyCommissionPayoutsRequest, GetMyCommissionPayoutsQuery>()
@@ -135,6 +139,7 @@ public class CommissionProfile : IRegister
? (CommissionPayoutStatus?)src.Status.Value
: null)
.Map(dest => dest.WeekDefinitionId, src => src.WeekDefinitionId != null ? src.WeekDefinitionId.Value : (long?)null)
.Map(dest => dest.PackageId, src => src.PackageId != null ? src.PackageId.Value : (long?)null)
.Map(dest => dest.PaginationState, src => new PaginationState
{
PageNumber = src.PageNumber > 0 ? src.PageNumber : 1,
@@ -160,12 +165,15 @@ public class CommissionProfile : IRegister
.Map(dest => dest.CalculatedDate, src => src.CalculatedDate.HasValue
? Timestamp.FromDateTime(src.CalculatedDate.Value.ToUniversalTime())
: null)
.Map(dest => dest.DatePersian, src => src.DatePersian);
.Map(dest => dest.DatePersian, src => src.DatePersian)
.Map(dest => dest.PackageId, src => src.PackageId)
.Map(dest => dest.PackageTitle, src => src.PackageTitle);
// GetMyWeeklyBalances Request Mapping
config.NewConfig<GetMyWeeklyBalancesRequest, GetMyWeeklyBalancesQuery>()
.Map(dest => dest.WeekDefinitionId, src => src.WeekDefinitionId != null ? src.WeekDefinitionId.Value : (long?)null)
.Map(dest => dest.OnlyActive, src => src.OnlyActive)
.Map(dest => dest.PackageId, src => src.PackageId != null ? src.PackageId.Value : (long?)null)
.Map(dest => dest.PaginationState, src => new PaginationState
{
PageNumber = src.PageNumber > 0 ? src.PageNumber : 1,
@@ -199,6 +207,8 @@ public class CommissionProfile : IRegister
.Map(dest => dest.IsExpired, src => src.IsExpired)
.Map(dest => dest.CalculatedAt, src => src.CalculatedAt.HasValue
? Timestamp.FromDateTime(DateTime.SpecifyKind(src.CalculatedAt.Value, DateTimeKind.Utc))
: null);
: null)
.Map(dest => dest.PackageId, src => src.PackageId)
.Map(dest => dest.PackageTitle, src => src.PackageTitle);
}
}