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)
|
||||
{
|
||||
var query = _context.NetworkWeeklyBalances
|
||||
.Include(x => x.WeekDefinition)
|
||||
.Include(x => x.User)
|
||||
.Include(x => x.Package)
|
||||
.AsNoTracking()
|
||||
.AsQueryable();
|
||||
var pageSize = request.PaginationState?.PageSize > 0 ? request.PaginationState.PageSize : PaginationDefaults.PageSize;
|
||||
var pageNumber = request.PaginationState?.PageNumber > 0 ? request.PaginationState.PageNumber : PaginationDefaults.PageNumber;
|
||||
|
||||
// UserId > 0 → filter by that user
|
||||
// UserId == 0 or null → show ALL users (admin mode)
|
||||
// Customer endpoints resolve UserId from JWT before calling this handler
|
||||
long? userId = request.UserId;
|
||||
// تشخیص جهت مرتبسازی از SortBy (پیشفرض: نزولی)
|
||||
var sortBy = request.SortBy ?? "-WeekDefinitionId";
|
||||
int sortDescending = sortBy.StartsWith("-") ? 1 : 0;
|
||||
|
||||
if (userId.HasValue && userId.Value > 0)
|
||||
{
|
||||
query = query.Where(x => x.UserId == userId.Value);
|
||||
}
|
||||
long? userId = request.UserId.HasValue && request.UserId.Value > 0 ? request.UserId : null;
|
||||
long? weekDefinitionId = request.WeekDefinitionId.HasValue ? request.WeekDefinitionId : null;
|
||||
long? packageId = request.PackageId.HasValue && request.PackageId.Value > 0 ? request.PackageId : null;
|
||||
int onlyActive = request.OnlyActive.HasValue && request.OnlyActive.Value ? 1 : 0;
|
||||
|
||||
// فیلتر بر اساس WeekDefinitionId (روش ترجیحی)
|
||||
if (request.WeekDefinitionId.HasValue)
|
||||
{
|
||||
query = query.Where(x => x.WeekDefinitionId == request.WeekDefinitionId.Value);
|
||||
}
|
||||
|
||||
|
||||
if (request.OnlyActive.HasValue && request.OnlyActive.Value)
|
||||
{
|
||||
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");
|
||||
|
||||
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 : ""
|
||||
})
|
||||
var rows = await _context.Database
|
||||
.SqlQuery<GetUserWeeklyBalancesResponseModel>(
|
||||
$"""
|
||||
EXEC [CMS].[sp_GetUserWeeklyBalances]
|
||||
@UserId = {userId},
|
||||
@WeekDefinitionId = {weekDefinitionId},
|
||||
@PackageId = {packageId},
|
||||
@OnlyActive = {onlyActive},
|
||||
@SortDescending = {sortDescending},
|
||||
@PageNumber = {pageNumber},
|
||||
@PageSize = {pageSize}
|
||||
""")
|
||||
.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
|
||||
{
|
||||
MetaData = meta,
|
||||
Models = models
|
||||
Models = rows
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -33,4 +33,7 @@ public class GetUserWeeklyBalancesResponseModel
|
||||
// Package info
|
||||
public long PackageId { get; set; }
|
||||
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
|
||||
builder.HasIndex(e => e.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")
|
||||
.HasDatabaseName("IX_NetworkWeeklyBalance_IsExpired");
|
||||
|
||||
b.HasIndex("PackageId");
|
||||
b.HasIndex("PackageId")
|
||||
.HasDatabaseName("IX_NetworkWeeklyBalance_PackageId");
|
||||
|
||||
b.HasIndex("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