feat: enhance sp_CalculateWeeklyBalances to track package activity and optimize member calculations
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 10m21s

This commit is contained in:
masoodafar-web
2026-05-04 23:54:13 +03:30
parent d09db638cc
commit b905c308c1
@@ -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,6 +67,26 @@ 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. بررسی محاسبه قبلی
-- =============================================
@@ -104,7 +125,7 @@ BEGIN
-- @MaxBalancesPerLeg و @MaxNetworkLevel قبلاً مقداردهی شده‌اند
-- =============================================
-- 5. ایجاد جدول موقت برای نتایج
-- 5. ایجاد جداول موقت برای نتایج
-- =============================================
CREATE TABLE #Balances (
UserId BIGINT PRIMARY KEY,
@@ -122,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 برای شمارش اعضای جدید شاخه چپ
@@ -177,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 برای شمارش اعضای جدید شاخه راست
@@ -214,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. محاسبه تعادل‌ها
@@ -354,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;
@@ -369,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;