Merge branch 'kub-stage' into production
Build and Deploy to Production / build-and-deploy (push) Successful in 10m25s

This commit is contained in:
masoodafar-web
2026-05-04 23:55:16 +03:30
14 changed files with 5612 additions and 142 deletions
@@ -24,6 +24,7 @@ BEGIN
DECLARE @MaxBalancesPerLeg INT;
DECLARE @MaxNetworkLevel INT;
DECLARE @CalculatedAt DATETIME = GETDATE();
DECLARE @HasPackageActivityUntilWeek BIT = 0;
-- تعیین PackageId پیش‌فرض (پکیج پایه)
IF @PackageId IS NULL
@@ -66,20 +67,48 @@ BEGIN
FROM CMS.WeekDefinitions
WHERE Id = @WeekDefinitionId;
-- اگر تا پایان این هفته هنوز هیچ Cycle برای این پکیج وجود نداشته،
-- این پکیج نباید برای هفته‌های قبل از شروعش هیچ رکوردی بسازد.
IF EXISTS (
SELECT 1
FROM CMS.ClubMembershipCycles cc
WHERE cc.PackageId = @PackageId
AND cc.IsDeleted = 0
AND cc.PackagePurchasedAt <= @EndDate
)
BEGIN
SET @HasPackageActivityUntilWeek = 1;
END
IF @HasPackageActivityUntilWeek = 0
BEGIN
SET @RowCount = 0;
COMMIT TRANSACTION;
RETURN;
END
-- =============================================
-- 2. بررسی محاسبه قبلی
-- =============================================
IF EXISTS (SELECT 1 FROM CMS.NetworkWeeklyBalances WHERE WeekDefinitionId = @WeekDefinitionId)
IF EXISTS (
SELECT 1
FROM CMS.NetworkWeeklyBalances
WHERE WeekDefinitionId = @WeekDefinitionId
AND PackageId = @PackageId
)
BEGIN
IF @ForceRecalculate = 0
BEGIN
SET @ErrorMessage = N'تعادل‌های هفته ' + CAST(@WeekDefinitionId AS NVARCHAR(20)) + N' قبلاً محاسبه شده است. برای محاسبه مجدد از ForceRecalculate استفاده کنید';
SET @ErrorMessage = N'تعادل‌های هفته ' + CAST(@WeekDefinitionId AS NVARCHAR(20))
+ N' (پکیج ' + CAST(@PackageId AS NVARCHAR(20)) + N') قبلاً محاسبه شده است. برای محاسبه مجدد از ForceRecalculate استفاده کنید';
RAISERROR(@ErrorMessage, 16, 1);
RETURN;
END
-- حذف محاسبات قبلی
DELETE FROM CMS.NetworkWeeklyBalances WHERE WeekDefinitionId = @WeekDefinitionId;
-- حذف محاسبات قبلی فقط برای همین پکیج
DELETE FROM CMS.NetworkWeeklyBalances
WHERE WeekDefinitionId = @WeekDefinitionId
AND PackageId = @PackageId;
END
-- =============================================
@@ -96,7 +125,7 @@ BEGIN
-- @MaxBalancesPerLeg و @MaxNetworkLevel قبلاً مقداردهی شده‌اند
-- =============================================
-- 5. ایجاد جدول موقت برای نتایج
-- 5. ایجاد جداول موقت برای نتایج
-- =============================================
CREATE TABLE #Balances (
UserId BIGINT PRIMARY KEY,
@@ -114,31 +143,18 @@ BEGIN
SubordinateBalances INT DEFAULT 0
);
-- =============================================
-- 6. دریافت کاربران فعال باشگاه
-- =============================================
INSERT INTO #Balances (UserId)
SELECT DISTINCT u.Id
FROM CMS.Users u
INNER JOIN CMS.ClubMemberships cm ON cm.UserId = u.Id AND cm.IsActive = 1
WHERE cm.LastPackageId = @PackageId;
CREATE TABLE #LeftNewMembers (
UserId BIGINT PRIMARY KEY,
NewMembersCount INT NOT NULL
);
CREATE TABLE #RightNewMembers (
UserId BIGINT PRIMARY KEY,
NewMembersCount INT NOT NULL
);
-- =============================================
-- 7. دریافت باقیمانده هفته قبل
-- =============================================
IF @PreviousWeekDefinitionId IS NOT NULL
BEGIN
UPDATE b
SET b.LeftLegCarryover = ISNULL(nb.LeftLegRemainder, 0),
b.RightLegCarryover = ISNULL(nb.RightLegRemainder, 0)
FROM #Balances b
LEFT JOIN CMS.NetworkWeeklyBalances nb ON nb.UserId = b.UserId
AND nb.WeekDefinitionId = @PreviousWeekDefinitionId
AND nb.PackageId = @PackageId;
END
-- =============================================
-- 8. محاسبه اعضای جدید هر پا با CTE (بهینه!)
-- 6. محاسبه اعضای جدید هر پا با CTE (بهینه!)
-- =============================================
-- CTE برای شمارش اعضای جدید شاخه چپ
@@ -169,13 +185,15 @@ BEGIN
COUNT(DISTINCT cte.ChildId) AS NewMembersCount
FROM LeftLegCTE cte
INNER JOIN CMS.ClubMembershipCycles cc ON cc.UserId = cte.ChildId
WHERE cc.PackagePurchasedAt >= @StartDate AND cc.PackagePurchasedAt <= @EndDate
WHERE cc.PackagePurchasedAt >= @StartDate
AND cc.PackagePurchasedAt <= @EndDate
AND cc.PackageId = @PackageId
AND cc.IsDeleted = 0
GROUP BY cte.ParentId
)
UPDATE b
SET b.LeftLegNewMembers = ISNULL(lnm.NewMembersCount, 0)
FROM #Balances b
LEFT JOIN LeftNewMembers lnm ON lnm.UserId = b.UserId
INSERT INTO #LeftNewMembers (UserId, NewMembersCount)
SELECT UserId, NewMembersCount
FROM LeftNewMembers
OPTION (MAXRECURSION 100);
-- CTE برای شمارش اعضای جدید شاخه راست
@@ -206,14 +224,65 @@ BEGIN
COUNT(DISTINCT cte.ChildId) AS NewMembersCount
FROM RightLegCTE cte
INNER JOIN CMS.ClubMembershipCycles cc ON cc.UserId = cte.ChildId
WHERE cc.PackagePurchasedAt >= @StartDate AND cc.PackagePurchasedAt <= @EndDate
WHERE cc.PackagePurchasedAt >= @StartDate
AND cc.PackagePurchasedAt <= @EndDate
AND cc.PackageId = @PackageId
AND cc.IsDeleted = 0
GROUP BY cte.ParentId
)
INSERT INTO #RightNewMembers (UserId, NewMembersCount)
SELECT UserId, NewMembersCount
FROM RightNewMembers
OPTION (MAXRECURSION 100);
-- =============================================
-- 7. انتخاب parentهایی که باید برای این پکیج/هفته row بگیرند
-- شرط ورود:
-- - عضو فعال باشگاه باشند
-- - یا از هفته قبل برای همین پکیج carryover داشته باشند
-- - یا این هفته recruit جدید همین پکیج در چپ/راست subtree داشته باشند
-- =============================================
INSERT INTO #Balances (UserId)
SELECT DISTINCT cm.UserId
FROM CMS.ClubMemberships cm
INNER JOIN CMS.Users u ON u.Id = cm.UserId
LEFT JOIN #LeftNewMembers lnm ON lnm.UserId = cm.UserId
LEFT JOIN #RightNewMembers rnm ON rnm.UserId = cm.UserId
LEFT JOIN CMS.NetworkWeeklyBalances prev ON prev.UserId = cm.UserId
AND prev.WeekDefinitionId = @PreviousWeekDefinitionId
AND prev.PackageId = @PackageId
WHERE cm.IsActive = 1
AND u.IsDeleted = 0
AND (
ISNULL(lnm.NewMembersCount, 0) > 0
OR ISNULL(rnm.NewMembersCount, 0) > 0
OR ISNULL(prev.LeftLegRemainder, 0) > 0
OR ISNULL(prev.RightLegRemainder, 0) > 0
);
-- =============================================
-- 8. دریافت باقیمانده هفته قبل + اعمال counts محاسبه‌شده
-- =============================================
IF @PreviousWeekDefinitionId IS NOT NULL
BEGIN
UPDATE b
SET b.LeftLegCarryover = ISNULL(nb.LeftLegRemainder, 0),
b.RightLegCarryover = ISNULL(nb.RightLegRemainder, 0)
FROM #Balances b
LEFT JOIN CMS.NetworkWeeklyBalances nb ON nb.UserId = b.UserId
AND nb.WeekDefinitionId = @PreviousWeekDefinitionId
AND nb.PackageId = @PackageId;
END
UPDATE b
SET b.LeftLegNewMembers = ISNULL(lnm.NewMembersCount, 0)
FROM #Balances b
LEFT JOIN #LeftNewMembers lnm ON lnm.UserId = b.UserId;
UPDATE b
SET b.RightLegNewMembers = ISNULL(rnm.NewMembersCount, 0)
FROM #Balances b
LEFT JOIN RightNewMembers rnm ON rnm.UserId = b.UserId
OPTION (MAXRECURSION 100);
LEFT JOIN #RightNewMembers rnm ON rnm.UserId = b.UserId;
-- =============================================
-- 9. محاسبه تعادل‌ها
@@ -346,11 +415,25 @@ BEGIN
'SP', -- CreatedBy
@CalculatedAt, -- LastModified
'SP' -- LastModifiedBy
FROM #Balances;
FROM #Balances
WHERE LeftLegNewMembers <> 0
OR RightLegNewMembers <> 0
OR LeftLegCarryover <> 0
OR RightLegCarryover <> 0
OR LeftLegTotal <> 0
OR RightLegTotal <> 0
OR TotalBalances <> 0
OR LeftLegRemainder <> 0
OR RightLegRemainder <> 0
OR FlushedPerSide <> 0
OR TotalFlushed <> 0
OR SubordinateBalances <> 0;
SET @RowCount = @@ROWCOUNT;
-- پاکسازی
DROP TABLE #RightNewMembers;
DROP TABLE #LeftNewMembers;
DROP TABLE #Balances;
COMMIT TRANSACTION;
@@ -361,6 +444,12 @@ BEGIN
ROLLBACK TRANSACTION;
-- پاکسازی در صورت خطا
IF OBJECT_ID('tempdb..#RightNewMembers') IS NOT NULL
DROP TABLE #RightNewMembers;
IF OBJECT_ID('tempdb..#LeftNewMembers') IS NOT NULL
DROP TABLE #LeftNewMembers;
IF OBJECT_ID('tempdb..#Balances') IS NOT NULL
DROP TABLE #Balances;
@@ -28,9 +28,9 @@ BEGIN
-- =============================================
-- 1. پیدا کردن Pool هفته (فیلتر بر اساس PackageId)
-- =============================================
SELECT @PoolId = Id, @TotalPoolAmount = TotalPoolAmount
SELECT @PoolId = MIN(Id), @TotalPoolAmount = ISNULL(SUM(TotalPoolAmount), 0)
FROM CMS.WeeklyCommissionPools
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId;
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0;
-- اگر Pool وجود ندارد (هیچ فعال‌سازی در این هفته نبوده)، یک رکورد خالی ایجاد می‌کنیم
IF @PoolId IS NULL
@@ -50,7 +50,15 @@ BEGIN
-- =============================================
-- 2. بررسی محاسبات قبلی (بر اساس همین Pool نه کل هفته)
-- =============================================
IF EXISTS (SELECT 1 FROM CMS.UserCommissionPayouts WHERE WeeklyPoolId = @PoolId)
IF EXISTS (
SELECT 1
FROM CMS.UserCommissionPayouts
WHERE WeeklyPoolId IN (
SELECT Id
FROM CMS.WeeklyCommissionPools
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0
)
)
BEGIN
IF @ForceRecalculate = 0
BEGIN
@@ -68,43 +76,80 @@ BEGIN
UPDATE uw
SET uw.NetworkBalance = uw.NetworkBalance - ISNULL(
(SELECT SUM(wl.ChangeNerworkValue)
FROM CMS.UserWalletChangeLogs wl
FROM CMS.UserWalletHistories wl
WHERE wl.WalletId = uw.Id
AND wl.RefrenceId IN (SELECT Id FROM CMS.UserCommissionPayouts WHERE WeeklyPoolId = @PoolId)
AND wl.RefrenceId IN (
SELECT Id
FROM CMS.UserCommissionPayouts
WHERE WeeklyPoolId IN (
SELECT Id
FROM CMS.WeeklyCommissionPools
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0
)
)
), 0)
FROM CMS.UserWallets uw
WHERE uw.Id IN (
SELECT DISTINCT wl.WalletId
FROM CMS.UserWalletChangeLogs wl
WHERE wl.RefrenceId IN (SELECT Id FROM CMS.UserCommissionPayouts WHERE WeeklyPoolId = @PoolId)
FROM CMS.UserWalletHistories wl
WHERE wl.RefrenceId IN (
SELECT Id
FROM CMS.UserCommissionPayouts
WHERE WeeklyPoolId IN (
SELECT Id
FROM CMS.WeeklyCommissionPools
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0
)
)
);
-- حذف لاگ‌های تغییرات قبلی
DELETE FROM CMS.UserWalletChangeLogs
WHERE RefrenceId IN (SELECT Id FROM CMS.UserCommissionPayouts WHERE WeeklyPoolId = @PoolId);
DELETE FROM CMS.UserWalletHistories
WHERE RefrenceId IN (
SELECT Id
FROM CMS.UserCommissionPayouts
WHERE WeeklyPoolId IN (
SELECT Id
FROM CMS.WeeklyCommissionPools
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0
)
);
-- حذف تاریخچه پرداخت
DELETE FROM CMS.CommissionPayoutHistories
WHERE UserCommissionPayoutId IN (SELECT Id FROM CMS.UserCommissionPayouts WHERE WeeklyPoolId = @PoolId);
WHERE UserCommissionPayoutId IN (
SELECT Id
FROM CMS.UserCommissionPayouts
WHERE WeeklyPoolId IN (
SELECT Id
FROM CMS.WeeklyCommissionPools
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0
)
);
-- حذف پرداخت‌های قبلی این Pool
DELETE FROM CMS.UserCommissionPayouts WHERE WeeklyPoolId = @PoolId;
DELETE FROM CMS.UserCommissionPayouts
WHERE WeeklyPoolId IN (
SELECT Id
FROM CMS.WeeklyCommissionPools
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0
);
-- Reset وضعیت Pool
UPDATE CMS.WeeklyCommissionPools
SET IsCalculated = 0
WHERE Id = @PoolId;
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0;
END
-- =============================================
-- 4. بررسی وجود تعادل‌های هفتگی
-- =============================================
IF NOT EXISTS (SELECT 1 FROM CMS.NetworkWeeklyBalances WHERE WeekDefinitionId = @WeekDefinitionId)
IF NOT EXISTS (SELECT 1 FROM CMS.NetworkWeeklyBalances WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId)
BEGIN
-- بالانسی محاسبه نشده — pool را به عنوان "محاسبه شده بدون پرداخت" علامت می‌زنیم
UPDATE CMS.WeeklyCommissionPools
SET IsCalculated = 1, CalculatedAt = @CalculatedAt
WHERE Id = @PoolId;
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0;
COMMIT TRANSACTION;
RETURN;
@@ -115,14 +160,14 @@ BEGIN
-- =============================================
SELECT @TotalBalances = SUM(TotalBalances)
FROM CMS.NetworkWeeklyBalances
WHERE WeekDefinitionId = @WeekDefinitionId AND TotalBalances > 0;
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND TotalBalances > 0;
IF @TotalBalances IS NULL OR @TotalBalances = 0
BEGIN
-- هیچ تعادلی برای توزیع وجود ندارد — pool محاسبه شده اما پرداختی ندارد
UPDATE CMS.WeeklyCommissionPools
SET IsCalculated = 1, CalculatedAt = @CalculatedAt
WHERE Id = @PoolId;
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0;
COMMIT TRANSACTION;
RETURN;
@@ -140,6 +185,7 @@ BEGIN
UserId,
WeekDefinitionId,
WeeklyPoolId,
PackageId,
BalancesEarned,
ValuePerBalance,
TotalAmount,
@@ -155,6 +201,7 @@ BEGIN
nb.UserId,
@WeekDefinitionId,
@PoolId,
@PackageId,
nb.TotalBalances,
@ValuePerBalance,
nb.TotalBalances * @ValuePerBalance,
@@ -166,7 +213,7 @@ BEGIN
@CalculatedAt,
'SP'
FROM CMS.NetworkWeeklyBalances nb
WHERE nb.WeekDefinitionId = @WeekDefinitionId AND nb.TotalBalances > 0;
WHERE nb.WeekDefinitionId = @WeekDefinitionId AND nb.PackageId = @PackageId AND nb.TotalBalances > 0;
-- =============================================
-- 8. ثبت تاریخچه پرداخت
@@ -205,7 +252,11 @@ BEGIN
@CalculatedAt,
'SP'
FROM CMS.UserCommissionPayouts cp
WHERE cp.WeeklyPoolId = @PoolId;
WHERE cp.WeeklyPoolId IN (
SELECT Id
FROM CMS.WeeklyCommissionPools
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0
);
-- =============================================
-- 9. شارژ کیف پول کاربران
@@ -216,10 +267,14 @@ BEGIN
SET uw.NetworkBalance = uw.NetworkBalance + cp.TotalAmount
FROM CMS.UserWallets uw
INNER JOIN CMS.UserCommissionPayouts cp ON cp.UserId = uw.UserId
WHERE cp.WeeklyPoolId = @PoolId;
WHERE cp.WeeklyPoolId IN (
SELECT Id
FROM CMS.WeeklyCommissionPools
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0
);
-- ثبت لاگ تغییرات کیف پول
INSERT INTO CMS.UserWalletChangeLogs (
INSERT INTO CMS.UserWalletHistories (
WalletId,
CurrentBalance,
ChangeValue,
@@ -252,7 +307,11 @@ BEGIN
'SP'
FROM CMS.UserCommissionPayouts cp
INNER JOIN CMS.UserWallets uw ON uw.UserId = cp.UserId
WHERE cp.WeeklyPoolId = @PoolId;
WHERE cp.WeeklyPoolId IN (
SELECT Id
FROM CMS.WeeklyCommissionPools
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0
);
-- =============================================
-- 10. بروزرسانی Pool
@@ -265,7 +324,7 @@ BEGIN
ValuePerBalance = @ValuePerBalance,
LastModified = @CalculatedAt,
LastModifiedBy = 'SP'
WHERE Id = @PoolId;
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId AND IsDeleted = 0;
COMMIT TRANSACTION;
@@ -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;