Add migration to rename index and create stored procedure for user weekly balances
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 9m55s
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 9m55s
- Added migration to rename index from IX_NetworkWeeklyBalances_PackageId to IX_NetworkWeeklyBalance_PackageId in the NetworkWeeklyBalances table. - Created stored procedure sp_GetUserWeeklyBalances to retrieve weekly balances with pagination and various filters.
This commit is contained in:
+35
-61
@@ -15,75 +15,49 @@ public class GetUserWeeklyBalancesQueryHandler : IRequestHandler<GetUserWeeklyBa
|
|||||||
|
|
||||||
public async Task<GetUserWeeklyBalancesResponseDto> Handle(GetUserWeeklyBalancesQuery request, CancellationToken cancellationToken)
|
public async Task<GetUserWeeklyBalancesResponseDto> Handle(GetUserWeeklyBalancesQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var query = _context.NetworkWeeklyBalances
|
var pageSize = request.PaginationState?.PageSize > 0 ? request.PaginationState.PageSize : PaginationDefaults.PageSize;
|
||||||
.Include(x => x.WeekDefinition)
|
var pageNumber = request.PaginationState?.PageNumber > 0 ? request.PaginationState.PageNumber : PaginationDefaults.PageNumber;
|
||||||
.Include(x => x.User)
|
|
||||||
.Include(x => x.Package)
|
|
||||||
.AsNoTracking()
|
|
||||||
.AsQueryable();
|
|
||||||
|
|
||||||
// UserId > 0 → filter by that user
|
// تشخیص جهت مرتبسازی از SortBy (پیشفرض: نزولی)
|
||||||
// UserId == 0 or null → show ALL users (admin mode)
|
var sortBy = request.SortBy ?? "-WeekDefinitionId";
|
||||||
// Customer endpoints resolve UserId from JWT before calling this handler
|
int sortDescending = sortBy.StartsWith("-") ? 1 : 0;
|
||||||
long? userId = request.UserId;
|
|
||||||
|
|
||||||
if (userId.HasValue && userId.Value > 0)
|
long? userId = request.UserId.HasValue && request.UserId.Value > 0 ? request.UserId : null;
|
||||||
{
|
long? weekDefinitionId = request.WeekDefinitionId.HasValue ? request.WeekDefinitionId : null;
|
||||||
query = query.Where(x => x.UserId == userId.Value);
|
long? packageId = request.PackageId.HasValue && request.PackageId.Value > 0 ? request.PackageId : null;
|
||||||
}
|
int onlyActive = request.OnlyActive.HasValue && request.OnlyActive.Value ? 1 : 0;
|
||||||
|
|
||||||
// فیلتر بر اساس WeekDefinitionId (روش ترجیحی)
|
var rows = await _context.Database
|
||||||
if (request.WeekDefinitionId.HasValue)
|
.SqlQuery<GetUserWeeklyBalancesResponseModel>(
|
||||||
{
|
$"""
|
||||||
query = query.Where(x => x.WeekDefinitionId == request.WeekDefinitionId.Value);
|
EXEC [CMS].[sp_GetUserWeeklyBalances]
|
||||||
}
|
@UserId = {userId},
|
||||||
|
@WeekDefinitionId = {weekDefinitionId},
|
||||||
|
@PackageId = {packageId},
|
||||||
if (request.OnlyActive.HasValue && request.OnlyActive.Value)
|
@OnlyActive = {onlyActive},
|
||||||
{
|
@SortDescending = {sortDescending},
|
||||||
query = query.Where(x => !x.IsExpired);
|
@PageNumber = {pageNumber},
|
||||||
}
|
@PageSize = {pageSize}
|
||||||
|
""")
|
||||||
// فیلتر بر اساس پکیج
|
|
||||||
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");
|
|
||||||
|
|
||||||
var meta = await query.GetMetaData(request.PaginationState, cancellationToken);
|
|
||||||
|
|
||||||
var models = await query
|
|
||||||
.PaginatedListAsync(paginationState: request.PaginationState)
|
|
||||||
.Select(x => new GetUserWeeklyBalancesResponseModel
|
|
||||||
{
|
|
||||||
Id = x.Id,
|
|
||||||
UserId = x.UserId,
|
|
||||||
UserFullName = x.User != null ? $"{x.User.FirstName} {x.User.LastName}".Trim() : "",
|
|
||||||
WeekDefinitionId = x.WeekDefinitionId,
|
|
||||||
WeekDisplayName = x.WeekDefinition != null ? x.WeekDefinition.DisplayName : "",
|
|
||||||
LeftLegNewMembers = x.LeftLegNewMembers,
|
|
||||||
LeftLegCarryover = x.LeftLegCarryover,
|
|
||||||
LeftLegTotal = x.LeftLegTotal,
|
|
||||||
RightLegNewMembers = x.RightLegNewMembers,
|
|
||||||
RightLegCarryover = x.RightLegCarryover,
|
|
||||||
RightLegTotal = x.RightLegTotal,
|
|
||||||
TotalBalances = x.TotalBalances,
|
|
||||||
WeeklyPoolContribution = x.WeeklyPoolContribution,
|
|
||||||
CalculatedAt = x.CalculatedAt,
|
|
||||||
IsExpired = x.IsExpired,
|
|
||||||
Created = x.Created,
|
|
||||||
PackageId = x.PackageId,
|
|
||||||
PackageTitle = x.Package != null ? x.Package.Title : ""
|
|
||||||
})
|
|
||||||
.ToListAsync(cancellationToken);
|
.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
|
var totalCount = rows.Count > 0 ? rows[0].TotalCount : 0;
|
||||||
|
var totalPageCount = (int)Math.Ceiling(totalCount / (double)pageSize);
|
||||||
|
|
||||||
|
var meta = new MetaData
|
||||||
|
{
|
||||||
|
CurrentPage = pageNumber,
|
||||||
|
PageSize = pageSize,
|
||||||
|
TotalCount = totalCount,
|
||||||
|
TotalPage = totalPageCount,
|
||||||
|
HasNext = pageNumber < totalPageCount,
|
||||||
|
HasPrevious = pageNumber > 1
|
||||||
|
};
|
||||||
|
|
||||||
return new GetUserWeeklyBalancesResponseDto
|
return new GetUserWeeklyBalancesResponseDto
|
||||||
{
|
{
|
||||||
MetaData = meta,
|
MetaData = meta,
|
||||||
Models = models
|
Models = rows
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -33,4 +33,7 @@ public class GetUserWeeklyBalancesResponseModel
|
|||||||
// Package info
|
// Package info
|
||||||
public long PackageId { get; set; }
|
public long PackageId { get; set; }
|
||||||
public string PackageTitle { get; set; } = string.Empty;
|
public string PackageTitle { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
// نتیجه COUNT(*) OVER() از SP — فقط در خواندن از SP پر میشود
|
||||||
|
public int TotalCount { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -56,5 +56,9 @@ public class NetworkWeeklyBalanceConfiguration : IEntityTypeConfiguration<Networ
|
|||||||
// Index برای IsExpired
|
// Index برای IsExpired
|
||||||
builder.HasIndex(e => e.IsExpired)
|
builder.HasIndex(e => e.IsExpired)
|
||||||
.HasDatabaseName("IX_NetworkWeeklyBalance_IsExpired");
|
.HasDatabaseName("IX_NetworkWeeklyBalance_IsExpired");
|
||||||
|
|
||||||
|
// Index برای PackageId — برای فیلتر در sp_GetUserWeeklyBalances
|
||||||
|
builder.HasIndex(e => e.PackageId)
|
||||||
|
.HasDatabaseName("IX_NetworkWeeklyBalance_PackageId");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5204
File diff suppressed because it is too large
Load Diff
+30
@@ -0,0 +1,30 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace CMSMicroservice.Infrastructure.Persistence.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddNetworkWeeklyBalance_PackageIdIndex : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_NetworkWeeklyBalances_PackageId",
|
||||||
|
schema: "CMS",
|
||||||
|
table: "NetworkWeeklyBalances",
|
||||||
|
newName: "IX_NetworkWeeklyBalance_PackageId");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_NetworkWeeklyBalance_PackageId",
|
||||||
|
schema: "CMS",
|
||||||
|
table: "NetworkWeeklyBalances",
|
||||||
|
newName: "IX_NetworkWeeklyBalances_PackageId");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -2478,7 +2478,8 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
|
|||||||
b.HasIndex("IsExpired")
|
b.HasIndex("IsExpired")
|
||||||
.HasDatabaseName("IX_NetworkWeeklyBalance_IsExpired");
|
.HasDatabaseName("IX_NetworkWeeklyBalance_IsExpired");
|
||||||
|
|
||||||
b.HasIndex("PackageId");
|
b.HasIndex("PackageId")
|
||||||
|
.HasDatabaseName("IX_NetworkWeeklyBalance_PackageId");
|
||||||
|
|
||||||
b.HasIndex("WeekDefinitionId")
|
b.HasIndex("WeekDefinitionId")
|
||||||
.HasDatabaseName("IX_NetworkWeeklyBalance_WeekDefinitionId");
|
.HasDatabaseName("IX_NetworkWeeklyBalance_WeekDefinitionId");
|
||||||
|
|||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
-- =============================================
|
||||||
|
-- Stored Procedure: sp_GetUserWeeklyBalances
|
||||||
|
-- Description: دریافت تعادلهای هفتگی با صفحهبندی و فیلترهای مختلف
|
||||||
|
-- Author: System
|
||||||
|
-- Created: 2026-05-04
|
||||||
|
-- =============================================
|
||||||
|
|
||||||
|
CREATE OR ALTER PROCEDURE [CMS].[sp_GetUserWeeklyBalances]
|
||||||
|
@UserId BIGINT = NULL,
|
||||||
|
@WeekDefinitionId BIGINT = NULL,
|
||||||
|
@PackageId BIGINT = NULL,
|
||||||
|
@OnlyActive BIT = 0,
|
||||||
|
@SortDescending BIT = 1, -- 1 = نزولی (جدیدترین اول)، 0 = صعودی
|
||||||
|
@PageNumber INT = 1,
|
||||||
|
@PageSize INT = 10
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON;
|
||||||
|
|
||||||
|
DECLARE @Skip INT = @PageSize * (@PageNumber - 1);
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
n.Id,
|
||||||
|
n.UserId,
|
||||||
|
LTRIM(RTRIM(ISNULL(u.FirstName, '') + ' ' + ISNULL(u.LastName, ''))) AS UserFullName,
|
||||||
|
n.WeekDefinitionId,
|
||||||
|
ISNULL(wd.DisplayName, '') AS WeekDisplayName,
|
||||||
|
n.LeftLegNewMembers,
|
||||||
|
n.LeftLegCarryover,
|
||||||
|
n.LeftLegTotal,
|
||||||
|
n.RightLegNewMembers,
|
||||||
|
n.RightLegCarryover,
|
||||||
|
n.RightLegTotal,
|
||||||
|
n.TotalBalances,
|
||||||
|
n.WeeklyPoolContribution,
|
||||||
|
n.CalculatedAt,
|
||||||
|
n.IsExpired,
|
||||||
|
n.Created,
|
||||||
|
n.PackageId,
|
||||||
|
ISNULL(p.Title, '') AS PackageTitle,
|
||||||
|
COUNT(*) OVER() AS TotalCount
|
||||||
|
FROM [CMS].[NetworkWeeklyBalances] n
|
||||||
|
LEFT JOIN [CMS].[Users] u ON u.Id = n.UserId
|
||||||
|
LEFT JOIN [CMS].[WeekDefinitions] wd ON wd.Id = n.WeekDefinitionId
|
||||||
|
LEFT JOIN [CMS].[Packages] p ON p.Id = n.PackageId
|
||||||
|
WHERE n.IsDeleted = 0
|
||||||
|
AND (@UserId IS NULL OR n.UserId = @UserId)
|
||||||
|
AND (@WeekDefinitionId IS NULL OR n.WeekDefinitionId = @WeekDefinitionId)
|
||||||
|
AND (@PackageId IS NULL OR n.PackageId = @PackageId)
|
||||||
|
AND (@OnlyActive = 0 OR n.IsExpired = 0)
|
||||||
|
ORDER BY
|
||||||
|
CASE WHEN @SortDescending = 1 THEN n.WeekDefinitionId END DESC,
|
||||||
|
CASE WHEN @SortDescending = 0 THEN n.WeekDefinitionId END ASC
|
||||||
|
OFFSET @Skip ROWS
|
||||||
|
FETCH NEXT @PageSize ROWS ONLY;
|
||||||
|
END;
|
||||||
Reference in New Issue
Block a user