Files
CMS/scripts/usp_CleanupTestUser.sql
T
masoodafar-web f79affb44d
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 21m45s
feat(transactions): enhance transaction queries with user information
- Added UserFullName and UserId properties to transaction response models for better user context.
- Updated query handlers to populate user information from related entities, ensuring accurate user details in transaction responses.
- Modified Protobuf definitions to include new fields for user identification and display.
- Adjusted mapping profiles to accommodate new user-related fields in transaction data.
2026-09-24 19:28:01 +03:30

341 lines
14 KiB
Transact-SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
Cleanup all side-effects of a test FrontOffice user (register + package + club + wallet + invitations).
Usage:
EXEC dbo.usp_CleanupTestUser @Mobile = N'09037437157', @DryRun = 1;
EXEC dbo.usp_CleanupTestUser @Mobile = N'09037437157';
EXEC dbo.usp_CleanupTestUser @Mobile = N'09...', @ReparentChildren = 1;
EXEC dbo.usp_CleanupTestUser @Mobile = N'09...', @ReversePool = 1, @AbortIfPoolCalculated = 1;
Pool reverse: for each ClubMembershipCycle, subtract Packages.ActivationFee
(fallback: ClubMembership.InitialContribution) from CMS.WeeklyCommissionPools
for matching WeekDefinition × PackageId.
Does NOT delete pool rows (shared). Does NOT claw back commission already paid to OTHER users.
Does NOT touch: Packages master, Contracts master, WeekDefinitions, Roles, catalogs.
*/
CREATE OR ALTER PROCEDURE dbo.usp_CleanupTestUser
@UserId BIGINT = NULL,
@Mobile NVARCHAR(20) = NULL,
@HardDeleteUser BIT = 1,
@ReparentChildren BIT = 0,
@ReversePool BIT = 1,
@AbortIfPoolCalculated BIT = 0,
@DryRun BIT = 0
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
SET QUOTED_IDENTIFIER ON;
SET ANSI_NULLS ON;
IF @UserId IS NULL AND (@Mobile IS NULL OR LTRIM(RTRIM(@Mobile)) = N'')
BEGIN
RAISERROR(N'Provide @UserId and/or @Mobile.', 16, 1);
RETURN;
END;
DECLARE @MobileNorm NVARCHAR(20) = NULL;
IF @Mobile IS NOT NULL
BEGIN
SET @MobileNorm = LTRIM(RTRIM(@Mobile));
IF LEFT(@MobileNorm, 3) = N'+98' SET @MobileNorm = N'0' + SUBSTRING(@MobileNorm, 4, 20);
IF LEFT(@MobileNorm, 2) = N'98' AND LEN(@MobileNorm) = 12 SET @MobileNorm = N'0' + SUBSTRING(@MobileNorm, 3, 20);
IF LEFT(@MobileNorm, 1) = N'9' AND LEN(@MobileNorm) = 10 SET @MobileNorm = N'0' + @MobileNorm;
END;
IF @UserId IS NULL
BEGIN
SELECT TOP (1) @UserId = Id
FROM CMS.Users
WHERE Mobile = @MobileNorm
OR Mobile = @Mobile
OR REPLACE(Mobile, N'+98', N'0') = @MobileNorm
ORDER BY IsDeleted ASC, Id DESC;
END;
IF @UserId IS NULL
BEGIN
RAISERROR(N'User not found for given @UserId/@Mobile.', 16, 1);
RETURN;
END;
DECLARE @UserMobile NVARCHAR(20);
SELECT @UserMobile = Mobile FROM CMS.Users WHERE Id = @UserId;
IF @UserMobile IS NULL
BEGIN
RAISERROR(N'UserId %I64d not found.', 16, 1, @UserId);
RETURN;
END;
DECLARE @ChildCount INT =
(SELECT COUNT(*) FROM CMS.Users WHERE NetworkParentId = @UserId AND IsDeleted = 0);
IF @ChildCount > 0 AND @ReparentChildren = 0 AND @HardDeleteUser = 1
BEGIN
RAISERROR(N'User has %d active network children. Pass @ReparentChildren=1 or soft-delete only.', 16, 1, @ChildCount);
RETURN;
END;
PRINT N'=== usp_CleanupTestUser ===';
PRINT N'UserId=' + CAST(@UserId AS NVARCHAR(20)) + N' Mobile=' + ISNULL(@UserMobile, N'?')
+ N' DryRun=' + CAST(@DryRun AS NVARCHAR(1))
+ N' ReversePool=' + CAST(@ReversePool AS NVARCHAR(1));
DECLARE @Wallets TABLE (WalletId BIGINT PRIMARY KEY);
INSERT INTO @Wallets (WalletId)
SELECT Id FROM CMS.UserWallets WHERE UserId = @UserId;
DECLARE @Tx TABLE (TransactionId BIGINT PRIMARY KEY);
INSERT INTO @Tx (TransactionId)
SELECT DISTINCT x.TransactionId
FROM (
SELECT TransactionId FROM CMS.UserPackagePurchases WHERE UserId = @UserId AND TransactionId IS NOT NULL
UNION
SELECT TransactionId FROM CMS.PaymentTransactions WHERE UserId = @UserId AND TransactionId IS NOT NULL
UNION
SELECT TransactionId FROM CMS.UserOrders WHERE UserId = @UserId AND TransactionId IS NOT NULL
UNION
SELECT TransactionId FROM CMS.ManualPayments WHERE UserId = @UserId AND TransactionId IS NOT NULL
UNION
SELECT TransactionId FROM CMS.DayaLoanContracts WHERE UserId = @UserId AND TransactionId IS NOT NULL
UNION
SELECT TransactionId FROM CMS.DiscountOrders WHERE UserId = @UserId AND TransactionId IS NOT NULL
UNION
SELECT h.RefrenceId
FROM CMS.UserWalletHistories h
INNER JOIN @Wallets w ON w.WalletId = h.WalletId
WHERE h.RefrenceId IS NOT NULL
) x
WHERE x.TransactionId IS NOT NULL;
DECLARE @Orders TABLE (OrderId BIGINT PRIMARY KEY);
INSERT INTO @Orders (OrderId)
SELECT Id FROM CMS.UserOrders WHERE UserId = @UserId;
DECLARE @DiscountOrders TABLE (DiscountOrderId BIGINT PRIMARY KEY);
INSERT INTO @DiscountOrders (DiscountOrderId)
SELECT Id FROM CMS.DiscountOrders WHERE UserId = @UserId;
DECLARE @ClubMemberships TABLE (ClubMembershipId BIGINT PRIMARY KEY);
INSERT INTO @ClubMemberships (ClubMembershipId)
SELECT Id FROM CMS.ClubMemberships WHERE UserId = @UserId;
DECLARE @Cycles TABLE (CycleId BIGINT PRIMARY KEY);
INSERT INTO @Cycles (CycleId)
SELECT Id FROM CMS.ClubMembershipCycles WHERE UserId = @UserId
UNION
SELECT Id FROM CMS.ClubMembershipCycles WHERE ClubMembershipId IN (SELECT ClubMembershipId FROM @ClubMemberships);
DECLARE @Payouts TABLE (PayoutId BIGINT PRIMARY KEY);
INSERT INTO @Payouts (PayoutId)
SELECT Id FROM CMS.UserCommissionPayouts WHERE UserId = @UserId;
DECLARE @PoolReversals TABLE (
CycleId BIGINT,
PackageId BIGINT,
WeekDefinitionId BIGINT NULL,
PoolId BIGINT NULL,
Fee BIGINT,
PoolAmountBefore BIGINT NULL,
IsCalculated BIT NULL,
Note NVARCHAR(200)
);
INSERT INTO @PoolReversals (CycleId, PackageId, WeekDefinitionId, PoolId, Fee, PoolAmountBefore, IsCalculated, Note)
SELECT
c.Id,
c.PackageId,
wd.Id,
wp.Id,
ISNULL(NULLIF(cm.InitialContribution, 0), ISNULL(p.ActivationFee, 0)),
wp.TotalPoolAmount,
wp.IsCalculated,
CASE
WHEN wd.Id IS NULL THEN N'NO_WEEK_MATCH'
WHEN wp.Id IS NULL THEN N'NO_POOL_ROW'
WHEN wp.IsCalculated = 1 THEN N'POOL_ALREADY_CALCULATED'
ELSE N'OK'
END
FROM CMS.ClubMembershipCycles c
LEFT JOIN CMS.ClubMemberships cm ON cm.Id = c.ClubMembershipId
LEFT JOIN CMS.Packages p ON p.Id = c.PackageId
LEFT JOIN CMS.WeekDefinitions wd
ON CAST(c.PackagePurchasedAt AS DATE) >= CAST(wd.StartDate AS DATE)
AND CAST(c.PackagePurchasedAt AS DATE) <= CAST(wd.EndDate AS DATE)
AND wd.IsDeleted = 0
LEFT JOIN CMS.WeeklyCommissionPools wp
ON wp.WeekDefinitionId = wd.Id
AND wp.PackageId = c.PackageId
AND wp.IsDeleted = 0
WHERE c.Id IN (SELECT CycleId FROM @Cycles);
SELECT N'Users' AS Entity, COUNT(*) AS Cnt FROM CMS.Users WHERE Id = @UserId
UNION ALL SELECT N'OtpTokens', COUNT(*) FROM CMS.OtpTokens WHERE Mobile IN (@UserMobile, @MobileNorm, @Mobile)
UNION ALL SELECT N'UserInvitations', COUNT(*) FROM CMS.UserInvitations WHERE InviterUserId = @UserId OR InviteeUserId = @UserId
UNION ALL SELECT N'ClubMemberships', COUNT(*) FROM @ClubMemberships
UNION ALL SELECT N'ClubMembershipCycles', COUNT(*) FROM @Cycles
UNION ALL SELECT N'UserPackagePurchases', COUNT(*) FROM CMS.UserPackagePurchases WHERE UserId = @UserId
UNION ALL SELECT N'PaymentTransactions', COUNT(*) FROM CMS.PaymentTransactions WHERE UserId = @UserId OR Mobile = @UserMobile
UNION ALL SELECT N'UserWallets', COUNT(*) FROM @Wallets
UNION ALL SELECT N'UserWalletHistories', COUNT(*) FROM CMS.UserWalletHistories WHERE WalletId IN (SELECT WalletId FROM @Wallets)
UNION ALL SELECT N'Transactions(collected)', COUNT(*) FROM @Tx
UNION ALL SELECT N'NetworkChildren', @ChildCount
UNION ALL SELECT N'UserOrders', COUNT(*) FROM @Orders
UNION ALL SELECT N'DiscountOrders', COUNT(*) FROM @DiscountOrders
UNION ALL SELECT N'UserCommissionPayouts', COUNT(*) FROM @Payouts
UNION ALL SELECT N'PoolReversals(planned)', COUNT(*) FROM @PoolReversals WHERE Fee > 0;
SELECT N'--- Pool reverse plan ---' AS Info;
SELECT * FROM @PoolReversals;
IF @ReversePool = 1 AND @AbortIfPoolCalculated = 1
AND EXISTS (SELECT 1 FROM @PoolReversals WHERE IsCalculated = 1 AND Fee > 0)
BEGIN
RAISERROR(N'One or more target weekly pools are already calculated. Aborting (@AbortIfPoolCalculated=1).', 16, 1);
RETURN;
END;
IF @DryRun = 1
BEGIN
PRINT N'DryRun=1 — no changes committed.';
RETURN;
END;
BEGIN TRANSACTION;
BEGIN TRY
/* ---- Reverse weekly pool charges FIRST (needs cycle + package data) ---- */
IF @ReversePool = 1
BEGIN
UPDATE wp
SET wp.TotalPoolAmount = CASE
WHEN wp.TotalPoolAmount >= r.Fee THEN wp.TotalPoolAmount - r.Fee
ELSE 0
END,
wp.LastModified = SYSUTCDATETIME()
FROM CMS.WeeklyCommissionPools wp
INNER JOIN (
SELECT PoolId, SUM(Fee) AS Fee
FROM @PoolReversals
WHERE PoolId IS NOT NULL AND Fee > 0
GROUP BY PoolId
) r ON r.PoolId = wp.Id;
PRINT N'Pool reverse applied for ' + CAST(@@ROWCOUNT AS NVARCHAR(20)) + N' pool row(s).';
END;
/* ---- Club ---- */
DELETE h FROM CMS.ClubMembershipCycleHistories h
WHERE h.UserId = @UserId OR h.ClubMembershipCycleId IN (SELECT CycleId FROM @Cycles);
DELETE FROM CMS.ClubMembershipCycles
WHERE Id IN (SELECT CycleId FROM @Cycles) OR UserId = @UserId;
DELETE FROM CMS.ClubMembershipHistories WHERE UserId = @UserId
OR ClubMembershipId IN (SELECT ClubMembershipId FROM @ClubMemberships);
DELETE FROM CMS.UserClubFeatures WHERE UserId = @UserId
OR ClubMembershipId IN (SELECT ClubMembershipId FROM @ClubMemberships);
DELETE FROM CMS.ClubMemberships WHERE UserId = @UserId;
/* ---- Commission payouts of THIS user only ---- */
DELETE h FROM CMS.CommissionPayoutHistories h
WHERE h.UserId = @UserId OR h.UserCommissionPayoutId IN (SELECT PayoutId FROM @Payouts);
DELETE FROM CMS.UserCommissionPayouts WHERE UserId = @UserId;
/* ---- Network ---- */
DELETE FROM CMS.NetworkWeeklyBalances WHERE UserId = @UserId;
DELETE FROM CMS.NetworkMembershipHistories
WHERE UserId = @UserId OR OldParentId = @UserId OR NewParentId = @UserId;
IF @ChildCount > 0 AND @ReparentChildren = 1
UPDATE CMS.Users SET NetworkParentId = NULL, LastModified = SYSUTCDATETIME()
WHERE NetworkParentId = @UserId;
/* ---- Invitations ---- */
DELETE FROM CMS.UserInvitations
WHERE InviterUserId = @UserId OR InviteeUserId = @UserId;
/* ---- Package / payment ---- */
DELETE FROM CMS.UserPackagePurchases WHERE UserId = @UserId;
DELETE FROM CMS.PaymentTransactions
WHERE UserId = @UserId OR Mobile = @UserMobile OR Mobile = @MobileNorm;
/* ---- Manual / Daya ---- */
DELETE FROM CMS.ManualPayments WHERE UserId = @UserId;
DELETE FROM CMS.DayaLoanContracts WHERE UserId = @UserId;
/* ---- Discount shop ---- */
DELETE d FROM CMS.DiscountOrderDetails d
WHERE d.DiscountOrderId IN (SELECT DiscountOrderId FROM @DiscountOrders);
DELETE FROM CMS.DiscountOrders WHERE UserId = @UserId;
DELETE FROM CMS.DiscountShoppingCarts WHERE UserId = @UserId;
/* ---- Stock ---- */
DELETE FROM CMS.StockMovements
WHERE PerformedByUserId = @UserId
OR OrderId IN (SELECT OrderId FROM @Orders)
OR DiscountOrderId IN (SELECT DiscountOrderId FROM @DiscountOrders);
/* ---- Orders ---- */
DELETE FROM CMS.FactorDetails WHERE OrderId IN (SELECT OrderId FROM @Orders);
DELETE FROM CMS.OrderVATs WHERE OrderId IN (SELECT OrderId FROM @Orders);
DELETE FROM CMS.UserOrders WHERE UserId = @UserId;
/* ---- Wallet ---- */
DELETE FROM CMS.UserWalletHistories WHERE WalletId IN (SELECT WalletId FROM @Wallets);
DELETE FROM CMS.UserWallets WHERE UserId = @UserId;
/* ---- Cart / address / roles / contracts ---- */
DELETE FROM CMS.UserCarts WHERE UserId = @UserId;
DELETE FROM CMS.UserAddresses WHERE UserId = @UserId;
DELETE FROM CMS.UserRoles WHERE UserId = @UserId;
DELETE FROM CMS.UserContracts WHERE UserId = @UserId;
/* ---- Content authored by test user ---- */
UPDATE CMS.BlogPosts SET IsDeleted = 1, LastModified = SYSUTCDATETIME()
WHERE AuthorUserId = @UserId AND IsDeleted = 0;
UPDATE CMS.PublicMessages SET IsDeleted = 1, LastModified = SYSUTCDATETIME()
WHERE CreatedByUserId = @UserId AND IsDeleted = 0;
/* ---- Transactions ---- */
DELETE t
FROM CMS.Transactions t
WHERE t.Id IN (SELECT TransactionId FROM @Tx)
AND NOT EXISTS (SELECT 1 FROM CMS.UserPackagePurchases p WHERE p.TransactionId = t.Id)
AND NOT EXISTS (SELECT 1 FROM CMS.PaymentTransactions p WHERE p.TransactionId = t.Id)
AND NOT EXISTS (SELECT 1 FROM CMS.UserOrders o WHERE o.TransactionId = t.Id)
AND NOT EXISTS (SELECT 1 FROM CMS.ManualPayments m WHERE m.TransactionId = t.Id)
AND NOT EXISTS (SELECT 1 FROM CMS.DayaLoanContracts d WHERE d.TransactionId = t.Id)
AND NOT EXISTS (SELECT 1 FROM CMS.DiscountOrders d WHERE d.TransactionId = t.Id);
/* ---- OTP ---- */
DELETE FROM CMS.OtpTokens
WHERE Mobile IN (@UserMobile, @MobileNorm, ISNULL(@Mobile, N''));
/* ---- User ---- */
IF @HardDeleteUser = 1
DELETE FROM CMS.Users WHERE Id = @UserId;
ELSE
UPDATE CMS.Users
SET IsDeleted = 1, LastModified = SYSUTCDATETIME()
WHERE Id = @UserId;
COMMIT TRANSACTION;
PRINT N'Cleanup completed successfully.';
SELECT N'DONE' AS Status, @UserId AS UserId, @UserMobile AS Mobile,
@HardDeleteUser AS HardDeleted, @ReversePool AS PoolReversed;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
DECLARE @Err NVARCHAR(4000) = ERROR_MESSAGE();
RAISERROR(N'Cleanup failed: %s', 16, 1, @Err);
END CATCH
END;
GO