fix(network): update network statistics and tree documentation
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 10m15s

- Updated README to reflect the new documentation location.
- Refactored GetNetworkStatisticsQueryHandler to improve method naming and logic for loading package holder counts.
- Enhanced GetNetworkStatisticsResponseDto and NetworkTreeDto to clarify the purpose of leg total properties.
- Updated Protobuf definitions to align with the new response structure for network statistics.
- Removed obsolete SQL scripts related to user package purchases and DayaLoan contracts cleanup.
This commit is contained in:
masoodafar-web
2026-08-28 18:55:48 +03:30
parent 87d61abc5b
commit 612d6fd141
24 changed files with 4036 additions and 256 deletions
@@ -0,0 +1,355 @@
/*
PHASE 3 — Remaining 16 users from WrongDaya→Manual list (no manualy Tx from Phase 1/2).
Users:
2,7,8,9,10,11,12,13,40,41,105,106,130,162,169,176
Already done in Phase 1+2 (22 users with manualy Tx): excluded here.
Per user (skip if UPP already exists for that UserId):
1) Reuse deposit Tx if WH links to Success Tx with Amount=56000000
2) Else fix WH.RefrenceId when CreatedBy hints an existing manualy Tx
3) Else CREATE Transaction (RefId FIX3-{UserId}) — no wallet charge
4) Link stub WH (Ref=0) to Tx OR insert history-only WH
5) INSERT UserPackagePurchases Manual(3)
User 162: skipped for UPP if any UPP already exists (has UPP from ManualPayment flow).
Does NOT change Users.PackagePurchaseMethod (Phase 4 later).
Defaults to ROLLBACK. Uncomment COMMIT after preview.
*/
SET NOCOUNT ON;
SET XACT_ABORT ON;
BEGIN TRAN;
DECLARE @Now DATETIME2 = SYSUTCDATETIME();
DECLARE @ChargeAmount BIGINT = 56000000;
DECLARE @BasePackageId BIGINT;
DECLARE @BasePackagePrice BIGINT;
SELECT TOP (1)
@BasePackageId = Id,
@BasePackagePrice = Price
FROM CMS.Packages
WHERE IsDeleted = 0 AND IsBasePackage = 1
ORDER BY Id;
IF @BasePackageId IS NULL
THROW 50001, 'Base package not found.', 1;
DECLARE @Phase3 TABLE (UserId BIGINT PRIMARY KEY);
INSERT INTO @Phase3 (UserId) VALUES
(2),(7),(8),(9),(10),(11),(12),(13),(40),(41),
(105),(106),(130),(162),(169),(176);
DECLARE @Phase3Count INT = (SELECT COUNT(*) FROM @Phase3);
PRINT CONCAT('Phase3 users: ', @Phase3Count);
------------------------------------------------------------
-- Preview: current ledger state
------------------------------------------------------------
SELECT
p.UserId,
u.Mobile,
u.FirstName,
u.LastName,
u.PackagePurchaseMethod,
(SELECT COUNT(*) FROM CMS.UserPackagePurchases upp
WHERE upp.UserId = p.UserId AND upp.IsDeleted = 0) AS UppCount,
(SELECT TOP (1) upp.Id FROM CMS.UserPackagePurchases upp
WHERE upp.UserId = p.UserId AND upp.IsDeleted = 0 ORDER BY upp.Id DESC) AS LatestUppId,
(SELECT COUNT(*) FROM CMS.UserWalletHistories h
INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0
WHERE w.UserId = p.UserId AND h.IsDeleted = 0) AS WhCount,
(SELECT COUNT(*) FROM CMS.UserWalletHistories h
INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0
WHERE w.UserId = p.UserId AND h.IsDeleted = 0
AND h.ChangeValue >= @ChargeAmount AND h.RefrenceId > 0) AS WhFullDepositCount,
CASE
WHEN EXISTS (
SELECT 1 FROM CMS.UserPackagePurchases upp
WHERE upp.UserId = p.UserId AND upp.IsDeleted = 0
) THEN N'SKIP_HAS_UPP'
ELSE N'NEEDS_UPP'
END AS UppPlan
FROM @Phase3 p
INNER JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0
ORDER BY p.UserId;
------------------------------------------------------------
-- Resolve Tx per user needing UPP
------------------------------------------------------------
SELECT
p.UserId,
u.Mobile,
COALESCE(
NULLIF(cm.LastPackageId, 0),
NULLIF(cm.FirstPackageId, 0),
@BasePackageId
) AS PackageId,
COALESCE(cm.ActivatedAt, cm.Created, @Now) AS PurchasedAt,
dep.TxId AS ExistingDepositTxId,
dep.WhId AS ExistingDepositWhId,
stub.StubWhId,
stub.StubCreatedBy,
CAST(NULL AS BIGINT) AS ResolvedTxId,
CAST(N'' AS NVARCHAR(40)) AS TxSource,
CAST(N'' AS NVARCHAR(40)) AS PlanAction
INTO #Plan
FROM @Phase3 p
INNER JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0
LEFT JOIN CMS.ClubMemberships cm ON cm.UserId = p.UserId AND cm.IsDeleted = 0
OUTER APPLY (
SELECT TOP (1)
t.Id AS TxId,
h.Id AS WhId
FROM CMS.UserWallets w
INNER JOIN CMS.UserWalletHistories h ON h.WalletId = w.Id AND h.IsDeleted = 0
INNER JOIN CMS.Transactions t ON t.Id = h.RefrenceId
AND t.IsDeleted = 0 AND t.PaymentStatus = 0 AND t.Amount = @ChargeAmount
WHERE w.UserId = p.UserId AND w.IsDeleted = 0
AND h.ChangeValue >= @ChargeAmount
AND h.IsIncrease = 1
ORDER BY h.Id ASC
) dep
OUTER APPLY (
SELECT TOP (1)
h.Id AS StubWhId,
h.CreatedBy AS StubCreatedBy
FROM CMS.UserWallets w
INNER JOIN CMS.UserWalletHistories h ON h.WalletId = w.Id AND h.IsDeleted = 0
WHERE w.UserId = p.UserId AND w.IsDeleted = 0
AND (h.RefrenceId IS NULL OR h.RefrenceId = 0)
ORDER BY h.Id ASC
) stub
WHERE NOT EXISTS (
SELECT 1 FROM CMS.UserPackagePurchases upp
WHERE upp.UserId = p.UserId AND upp.IsDeleted = 0
);
-- Pass 1: existing full deposit WH→Tx
UPDATE pl
SET
ResolvedTxId = pl.ExistingDepositTxId,
TxSource = N'WH_DEPOSIT',
PlanAction = N'CREATE_UPP_REUSE_TX'
FROM #Plan pl
WHERE pl.ExistingDepositTxId IS NOT NULL;
-- Pass 2: stub CreatedBy → manualy Tx
UPDATE pl
SET
ResolvedTxId = t.Id,
TxSource = N'WH_STUB_HINT',
PlanAction = N'FIX_STUB_LINK_UPP'
FROM #Plan pl
INNER JOIN CMS.Transactions t ON t.Id = TRY_CAST(pl.StubCreatedBy AS BIGINT)
AND t.IsDeleted = 0 AND t.PaymentStatus = 0 AND t.RefId LIKE N'manualy%'
WHERE pl.ResolvedTxId IS NULL
AND TRY_CAST(pl.StubCreatedBy AS BIGINT) > 0;
-- Pass 3: need new Tx
UPDATE pl
SET
TxSource = N'CREATE_TX',
PlanAction = N'CREATE_TX_WH_UPP'
FROM #Plan pl
WHERE pl.ResolvedTxId IS NULL;
SELECT
UserId, Mobile, PackageId, PurchasedAt,
ExistingDepositTxId, ExistingDepositWhId,
StubWhId, StubCreatedBy,
ResolvedTxId, TxSource, PlanAction
FROM #Plan
ORDER BY UserId;
DECLARE @NeedPlan INT = (SELECT COUNT(*) FROM #Plan);
PRINT CONCAT('Users needing UPP in Phase3: ', @NeedPlan);
------------------------------------------------------------
-- Execute: cursor per user
------------------------------------------------------------
DECLARE @UserId BIGINT;
DECLARE @Mobile NVARCHAR(50);
DECLARE @PackageId BIGINT;
DECLARE @PurchasedAt DATETIME2;
DECLARE @ExistingDepositTxId BIGINT;
DECLARE @StubWhId BIGINT;
DECLARE @ResolvedTxId BIGINT;
DECLARE @TxSource NVARCHAR(40);
DECLARE @TxId BIGINT;
DECLARE @WalletId BIGINT;
DECLARE @DiscountAmount BIGINT;
DECLARE @NetworkBalance BIGINT;
DECLARE @HistoryAt DATETIME2;
DECLARE @CreatedTx INT = 0;
DECLARE @CreatedUpp INT = 0;
DECLARE @CreatedWh INT = 0;
DECLARE @FixedWh INT = 0;
DECLARE cur CURSOR LOCAL FAST_FORWARD FOR
SELECT UserId, Mobile, PackageId, PurchasedAt,
ExistingDepositTxId, StubWhId, ResolvedTxId, TxSource
FROM #Plan;
OPEN cur;
FETCH NEXT FROM cur INTO
@UserId, @Mobile, @PackageId, @PurchasedAt,
@ExistingDepositTxId, @StubWhId, @ResolvedTxId, @TxSource;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @TxId = @ResolvedTxId;
IF @TxId IS NULL
BEGIN
INSERT INTO CMS.Transactions
(
Amount, Description, PaymentStatus, PaymentDate, RefId, Type,
Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted
)
VALUES
(
@ChargeAmount,
N'عضویت دستی باشگاه مشتریان - backfill Phase3 WrongDaya',
0,
@PurchasedAt,
CONCAT(N'FIX3-', @UserId),
2,
@PurchasedAt,
@Mobile,
@PurchasedAt,
@Mobile,
0
);
SET @TxId = SCOPE_IDENTITY();
SET @CreatedTx = @CreatedTx + 1;
END
IF @StubWhId IS NOT NULL
AND EXISTS (
SELECT 1 FROM CMS.UserWalletHistories h
WHERE h.Id = @StubWhId AND h.IsDeleted = 0
AND (h.RefrenceId IS NULL OR h.RefrenceId = 0)
)
BEGIN
UPDATE CMS.UserWalletHistories
SET RefrenceId = @TxId, LastModified = @Now
WHERE Id = @StubWhId;
SET @FixedWh = @FixedWh + @@ROWCOUNT;
END
SELECT @WalletId = w.Id, @NetworkBalance = COALESCE(w.NetworkBalance, 0)
FROM CMS.UserWallets w
WHERE w.UserId = @UserId AND w.IsDeleted = 0;
IF @WalletId IS NULL
BEGIN
INSERT INTO CMS.UserWallets
(UserId, Balance, NetworkBalance, DiscountBalance, WalletMode, Created, LastModified, IsDeleted)
VALUES (@UserId, 0, 0, 0, 0, @PurchasedAt, @PurchasedAt, 0);
SET @WalletId = SCOPE_IDENTITY();
SET @NetworkBalance = 0;
END
IF NOT EXISTS (
SELECT 1 FROM CMS.UserWalletHistories h
WHERE h.WalletId = @WalletId AND h.IsDeleted = 0 AND h.RefrenceId = @TxId
)
BEGIN
SELECT
@HistoryAt = COALESCE(t.PaymentDate, @PurchasedAt),
@DiscountAmount = CAST(ROUND(@ChargeAmount * COALESCE(pkg.DiscountMultiplier, 2.0), 0) AS BIGINT)
FROM CMS.Transactions t
LEFT JOIN CMS.Packages pkg ON pkg.Id = @PackageId AND pkg.IsDeleted = 0
WHERE t.Id = @TxId;
INSERT INTO CMS.UserWalletHistories
(
WalletId, CurrentBalance, ChangeValue, CurrentNetworkBalance, ChangeNerworkValue,
CurrentDiscountBalance, ChangeDiscountValue, IsIncrease, RefrenceId, PackageId,
Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted
)
VALUES
(
@WalletId, 0, @ChargeAmount, @NetworkBalance, 0,
0, @DiscountAmount, 1, @TxId, @PackageId,
@HistoryAt, NULL, @HistoryAt, NULL, 0
);
SET @CreatedWh = @CreatedWh + 1;
END
IF NOT EXISTS (
SELECT 1 FROM CMS.UserPackagePurchases upp
WHERE upp.UserId = @UserId AND upp.IsDeleted = 0 AND upp.TransactionId = @TxId
)
BEGIN
INSERT INTO CMS.UserPackagePurchases
(
UserId, PackageId, PurchaseMethod, PurchasedAt, Amount,
OrderId, TransactionId, Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted
)
VALUES
(
@UserId, @PackageId, 3,
@PurchasedAt, @ChargeAmount,
NULL, @TxId, @Now, NULL, @Now, NULL, 0
);
SET @CreatedUpp = @CreatedUpp + 1;
END
FETCH NEXT FROM cur INTO
@UserId, @Mobile, @PackageId, @PurchasedAt,
@ExistingDepositTxId, @StubWhId, @ResolvedTxId, @TxSource;
END
CLOSE cur;
DEALLOCATE cur;
DROP TABLE #Plan;
PRINT CONCAT('Tx created: ', @CreatedTx,
' | WH Ref fixed: ', @FixedWh,
' | WH created: ', @CreatedWh,
' | UPP created: ', @CreatedUpp);
------------------------------------------------------------
-- Verify all 16 have UPP
------------------------------------------------------------
SELECT
p.UserId,
u.Mobile,
CASE WHEN upp.UppId IS NOT NULL THEN N'OK' ELSE N'MISSING_UPP' END AS UppStatus,
upp.UppId,
upp.PurchaseMethod,
upp.TransactionId AS UppTxId,
t.RefId AS TxRefId
FROM @Phase3 p
INNER JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0
OUTER APPLY (
SELECT TOP (1)
upp2.Id AS UppId,
upp2.PurchaseMethod,
upp2.TransactionId
FROM CMS.UserPackagePurchases upp2
WHERE upp2.UserId = p.UserId AND upp2.IsDeleted = 0
ORDER BY upp2.Id DESC
) upp
LEFT JOIN CMS.Transactions t ON t.Id = upp.TransactionId
ORDER BY p.UserId;
SELECT N'Phase3 users still without UPP' AS CheckName, COUNT(*) AS Cnt
FROM @Phase3 p
WHERE NOT EXISTS (
SELECT 1 FROM CMS.UserPackagePurchases upp
WHERE upp.UserId = p.UserId AND upp.IsDeleted = 0
);
ROLLBACK;
-- COMMIT;
PRINT 'Done (rolled back by default). Uncomment COMMIT when preview looks correct.';