f79affb44d
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 21m45s
- 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.
341 lines
14 KiB
Transact-SQL
341 lines
14 KiB
Transact-SQL
/*
|
||
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
|