From 612d6fd1416e2e13b20f39d803b09dd7e2cc0ce3 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Fri, 28 Aug 2026 18:55:48 +0330 Subject: [PATCH] fix(network): update network statistics and tree documentation - 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. --- README.md | 2 +- .../GetNetworkStatisticsQueryHandler.cs | 110 +-- .../GetNetworkStatisticsResponseDto.cs | 5 +- .../Queries/GetNetworkTree/NetworkTreeDto.cs | 8 +- .../Protos/networkmembership.proto | 4 +- ...rPackagePurchases_FromClubMemberships.sql} | 0 .../10-Diagnose_Manualy_Transaction_Map.sql | 246 ++++++ src/dbbkup/10-result.csv | 104 +++ .../11-Diagnose_PackageHolderCounts_ByLeg.sql | 77 ++ ...ollback_Backfill_UserPackagePurchases.sql} | 0 ...ate_DayaLoanContracts_ContractNumbers.sql} | 0 ...4-Fix_Daya_ActiveExcel_ProcessMissing.sql} | 165 ++-- ...-Fix_WrongDaya_ToManual_PurchaseMethod.sql | 547 +++++++++++++ ...Phase1_Create_UPP_Manualy_Linked_WH_Tx.sql | 295 +++++++ ...e2_Fix_WH_Link_And_Create_UPP_Tx_56-68.sql | 368 +++++++++ ...c-Phase3_Create_UPP_Remaining_16_Users.sql | 355 +++++++++ ...ectPurchase_ToManual_FromManualPayment.sql | 740 ++++++++++++++++++ ...UserWalletHistory_ForManualPayment_Txs.sql | 215 +++++ ...ose_WrongDaya_Ledger_FromWalletHistory.sql | 431 ++++++++++ src/dbbkup/9-result.csv | 415 ++++++++++ .../Fix_WrongDaya_ToManual_PurchaseMethod.sql | 157 ---- src/dbbkup/Transactions.csv | 23 + src/dbbkup/UserWalletHistories.csv | 18 + src/dbbkup/UserWalletHistories2.csv | 7 + 24 files changed, 4036 insertions(+), 256 deletions(-) rename src/dbbkup/{Backfill_UserPackagePurchases_FromClubMemberships.sql => 1-Backfill_UserPackagePurchases_FromClubMemberships.sql} (100%) create mode 100644 src/dbbkup/10-Diagnose_Manualy_Transaction_Map.sql create mode 100644 src/dbbkup/10-result.csv create mode 100644 src/dbbkup/11-Diagnose_PackageHolderCounts_ByLeg.sql rename src/dbbkup/{Rollback_Backfill_UserPackagePurchases.sql => 2-Rollback_Backfill_UserPackagePurchases.sql} (100%) rename src/dbbkup/{Update_DayaLoanContracts_ContractNumbers.sql => 3-Update_DayaLoanContracts_ContractNumbers.sql} (100%) rename src/dbbkup/{Fix_Daya_ActiveExcel_ProcessMissing.sql => 4-Fix_Daya_ActiveExcel_ProcessMissing.sql} (77%) create mode 100644 src/dbbkup/6-Fix_WrongDaya_ToManual_PurchaseMethod.sql create mode 100644 src/dbbkup/6a-Phase1_Create_UPP_Manualy_Linked_WH_Tx.sql create mode 100644 src/dbbkup/6b-Phase2_Fix_WH_Link_And_Create_UPP_Tx_56-68.sql create mode 100644 src/dbbkup/6c-Phase3_Create_UPP_Remaining_16_Users.sql create mode 100644 src/dbbkup/7-Fix_WrongDirectPurchase_ToManual_FromManualPayment.sql create mode 100644 src/dbbkup/8-Backfill_UserWalletHistory_ForManualPayment_Txs.sql create mode 100644 src/dbbkup/9-Diagnose_WrongDaya_Ledger_FromWalletHistory.sql create mode 100644 src/dbbkup/9-result.csv delete mode 100644 src/dbbkup/Fix_WrongDaya_ToManual_PurchaseMethod.sql create mode 100644 src/dbbkup/Transactions.csv create mode 100644 src/dbbkup/UserWalletHistories.csv create mode 100644 src/dbbkup/UserWalletHistories2.csv diff --git a/README.md b/README.md index 06b3f36..b4153ef 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ # CMS Microservice Documentation moved to [totalDoc/INDEX.md](../totalDoc/INDEX.md). - \ No newline at end of file + \ No newline at end of file diff --git a/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkStatistics/GetNetworkStatisticsQueryHandler.cs b/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkStatistics/GetNetworkStatisticsQueryHandler.cs index b6e4828..5621355 100644 --- a/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkStatistics/GetNetworkStatisticsQueryHandler.cs +++ b/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkStatistics/GetNetworkStatisticsQueryHandler.cs @@ -126,7 +126,7 @@ public class GetNetworkStatisticsQueryHandler : IRequestHandler - /// آخرین Left/RightLegTotal طلایی و نقره‌ای فقط برای خود کاربر (نوار آمار شجره). + /// تعداد اعضای فعال باشگاه با پکیج جاری (IsCurrentCycle) در پای چپ/راست. /// - private async Task<(int GoldLeft, int GoldRight, int SilverLeft, int SilverRight)> LoadLatestPackageLegScoresAsync( - long userId, + private async Task<(int GoldLeft, int GoldRight, int SilverLeft, int SilverRight)> LoadPackageHolderCountsByLegAsync( + User? leftChild, + User? rightChild, + List allUsers, + CancellationToken cancellationToken) + { + var leftLegUserIds = leftChild != null ? GetSubtreeUserIds(leftChild.Id, allUsers) : new HashSet(); + var rightLegUserIds = rightChild != null ? GetSubtreeUserIds(rightChild.Id, allUsers) : new HashSet(); + + if (leftLegUserIds.Count == 0 && rightLegUserIds.Count == 0) + return (0, 0, 0, 0); + + var (goldPackageId, silverPackageId) = await ResolveGoldSilverPackageIdsAsync(cancellationToken); + if (!goldPackageId.HasValue && !silverPackageId.HasValue) + return (0, 0, 0, 0); + + var allLegUserIds = leftLegUserIds.Union(rightLegUserIds).ToList(); + + var userPackages = await ( + from cm in _context.ClubMemberships.AsNoTracking() + join cc in _context.ClubMembershipCycles.AsNoTracking() on cm.UserId equals cc.UserId + where cm.IsActive + && !cm.IsDeleted + && cc.IsCurrentCycle + && allLegUserIds.Contains(cm.UserId) + select new { cm.UserId, cc.PackageId } + ).ToListAsync(cancellationToken); + + var packageByUser = userPackages + .GroupBy(x => x.UserId) + .ToDictionary(g => g.Key, g => g.First().PackageId); + + int goldLeft = 0, goldRight = 0, silverLeft = 0, silverRight = 0; + + if (goldPackageId.HasValue) + { + goldLeft = leftLegUserIds.Count(id => + packageByUser.TryGetValue(id, out var packageId) && packageId == goldPackageId.Value); + goldRight = rightLegUserIds.Count(id => + packageByUser.TryGetValue(id, out var packageId) && packageId == goldPackageId.Value); + } + + if (silverPackageId.HasValue) + { + silverLeft = leftLegUserIds.Count(id => + packageByUser.TryGetValue(id, out var packageId) && packageId == silverPackageId.Value); + silverRight = rightLegUserIds.Count(id => + packageByUser.TryGetValue(id, out var packageId) && packageId == silverPackageId.Value); + } + + return (goldLeft, goldRight, silverLeft, silverRight); + } + + private async Task<(long? GoldPackageId, long? SilverPackageId)> ResolveGoldSilverPackageIdsAsync( CancellationToken cancellationToken) { var packages = await _context.Packages @@ -168,49 +220,15 @@ public class GetNetworkStatisticsQueryHandler : IRequestHandler !p.IsBasePackage)?.Id; - var packageIds = new List(); - if (goldPackageId.HasValue) packageIds.Add(goldPackageId.Value); - if (silverPackageId.HasValue && silverPackageId != goldPackageId) - packageIds.Add(silverPackageId.Value); + return (goldPackageId, silverPackageId); + } - if (packageIds.Count == 0) - return (0, 0, 0, 0); - - var balances = await _context.NetworkWeeklyBalances - .AsNoTracking() - .Where(b => b.UserId == userId && packageIds.Contains(b.PackageId)) - .Select(b => new { b.PackageId, b.WeekDefinitionId, b.LeftLegTotal, b.RightLegTotal }) - .ToListAsync(cancellationToken); - - int goldLeft = 0, goldRight = 0, silverLeft = 0, silverRight = 0; - - if (goldPackageId.HasValue) - { - var gold = balances - .Where(b => b.PackageId == goldPackageId.Value) - .OrderByDescending(b => b.WeekDefinitionId) - .FirstOrDefault(); - if (gold != null) - { - goldLeft = gold.LeftLegTotal; - goldRight = gold.RightLegTotal; - } - } - - if (silverPackageId.HasValue) - { - var silver = balances - .Where(b => b.PackageId == silverPackageId.Value) - .OrderByDescending(b => b.WeekDefinitionId) - .FirstOrDefault(); - if (silver != null) - { - silverLeft = silver.LeftLegTotal; - silverRight = silver.RightLegTotal; - } - } - - return (goldLeft, goldRight, silverLeft, silverRight); + private HashSet GetSubtreeUserIds(long rootUserId, List allUsers) + { + var ids = new HashSet { rootUserId }; + foreach (var descendant in GetAllDescendants(rootUserId, allUsers)) + ids.Add(descendant.Id); + return ids; } /// diff --git a/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkStatistics/GetNetworkStatisticsResponseDto.cs b/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkStatistics/GetNetworkStatisticsResponseDto.cs index 75da530..19e0dc6 100644 --- a/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkStatistics/GetNetworkStatisticsResponseDto.cs +++ b/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkStatistics/GetNetworkStatisticsResponseDto.cs @@ -14,10 +14,13 @@ public class GetNetworkStatisticsResponseDto public List MonthlyGrowth { get; set; } = new(); public List TopUsers { get; set; } = new(); - /// آخرین LeftLegTotal پکیج طلایی برای همین کاربر + /// تعداد اعضای فعال باشگاه با پکیج طلایی جاری در پای چپ public int GoldLeftLegTotal { get; set; } + /// تعداد اعضای فعال باشگاه با پکیج طلایی جاری در پای راست public int GoldRightLegTotal { get; set; } + /// تعداد اعضای فعال باشگاه با پکیج نقره‌ای جاری در پای چپ public int SilverLeftLegTotal { get; set; } + /// تعداد اعضای فعال باشگاه با پکیج نقره‌ای جاری در پای راست public int SilverRightLegTotal { get; set; } public string WeakerLeg => LeftLegCount <= RightLegCount ? "Left" : "Right"; diff --git a/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkTree/NetworkTreeDto.cs b/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkTree/NetworkTreeDto.cs index c273e84..a595699 100644 --- a/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkTree/NetworkTreeDto.cs +++ b/src/CMSMicroservice.Application/NetworkMembershipCQ/Queries/GetNetworkTree/NetworkTreeDto.cs @@ -60,16 +60,16 @@ public class NetworkTreeDto public long? PackageId { get; set; } - /// آخرین LeftLegTotal پکیج طلایی (پایه) + /// تعداد اعضای فعال با پکیج طلایی جاری در پای چپ (stats bar) public int GoldLeftLegTotal { get; set; } - /// آخرین RightLegTotal پکیج طلایی (پایه) + /// تعداد اعضای فعال با پکیج طلایی جاری در پای راست (stats bar) public int GoldRightLegTotal { get; set; } - /// آخرین LeftLegTotal پکیج نقره‌ای + /// تعداد اعضای فعال با پکیج نقره‌ای جاری در پای چپ (stats bar) public int SilverLeftLegTotal { get; set; } - /// آخرین RightLegTotal پکیج نقره‌ای + /// تعداد اعضای فعال با پکیج نقره‌ای جاری در پای راست (stats bar) public int SilverRightLegTotal { get; set; } public NetworkTreeDto? LeftChild { get; set; } diff --git a/src/CMSMicroservice.Protobuf/Protos/networkmembership.proto b/src/CMSMicroservice.Protobuf/Protos/networkmembership.proto index 0a32e63..3170492 100644 --- a/src/CMSMicroservice.Protobuf/Protos/networkmembership.proto +++ b/src/CMSMicroservice.Protobuf/Protos/networkmembership.proto @@ -209,7 +209,7 @@ message NetworkTreeNodeModel google.protobuf.BoolValue is_new_activation = 22; // true=اولین فعال‌سازی، false=خرید مجدد، null=بدون Cycle string package_name = 23; // نام پکیج موثر google.protobuf.Int64Value package_id = 24; // شناسه پکیج - // آخرین NetworkWeeklyBalance: امتیاز پای چپ/راست برای پکیج طلایی و نقره‌ای (D3) + // تعداد اعضای فعال با پکیج جاری در پای چپ/راست (طلایی و نقره‌ای) int32 gold_left_leg_total = 25; int32 gold_right_leg_total = 26; int32 silver_left_leg_total = 27; @@ -328,7 +328,7 @@ message GetMyNetworkStatisticsResponse string my_network_leg = 11; string my_referral_code = 12; CustomerLastMemberModel last_member = 13; - // آخرین NetworkWeeklyBalance خود کاربر — برای نوار آمار پایین شجره (D3) + // تعداد اعضای فعال با پکیج جاری در پای چپ/راست — نوار آمار پایین شجره (D3) int32 gold_left_leg_total = 14; int32 gold_right_leg_total = 15; int32 silver_left_leg_total = 16; diff --git a/src/dbbkup/Backfill_UserPackagePurchases_FromClubMemberships.sql b/src/dbbkup/1-Backfill_UserPackagePurchases_FromClubMemberships.sql similarity index 100% rename from src/dbbkup/Backfill_UserPackagePurchases_FromClubMemberships.sql rename to src/dbbkup/1-Backfill_UserPackagePurchases_FromClubMemberships.sql diff --git a/src/dbbkup/10-Diagnose_Manualy_Transaction_Map.sql b/src/dbbkup/10-Diagnose_Manualy_Transaction_Map.sql new file mode 100644 index 0000000..df46e96 --- /dev/null +++ b/src/dbbkup/10-Diagnose_Manualy_Transaction_Map.sql @@ -0,0 +1,246 @@ +/* + DIAGNOSTIC ONLY — maps RefId LIKE 'manualy%' transactions to Users / WalletHistory. + + Background (ChargeUserWallets.sql): + RefId = 'manualy' + ChangeLogId at charge time (original UserWalletChangeLogs id). + After migration/rebuild, WH ids shifted; RefrenceId on some rows stayed 0. + When RefrenceId=0, CreatedBy may store the Transaction Id as a fallback hint — + but Tx may never have been created; do NOT infer Tx from mobile or manualy suffix alone. + + Rules used here: + - WH.RefrenceId > 0 → trusted link to Tx + - WH.RefrenceId = 0 → Tx ONLY if CreatedBy is numeric AND that Tx exists with RefId manualy% + - Tx → User via mobile (CreatedBy/LastModifiedBy) is informational, not used alone for Ref=0 WH + - manualy{N} suffix N = original ChangeLog id (may differ from current WH.Id) + + Run on staging before script 6. +*/ + +SET NOCOUNT ON; + +DECLARE @ManualyTx TABLE ( + TransactionId BIGINT PRIMARY KEY, + RefId NVARCHAR(100) NOT NULL, + OriginalChangeLogId BIGINT NULL, + Amount BIGINT, + TxCreatedBy NVARCHAR(200), + TxLastModifiedBy NVARCHAR(200), + PaymentDate DATETIME2 +); + +INSERT INTO @ManualyTx (TransactionId, RefId, OriginalChangeLogId, Amount, TxCreatedBy, TxLastModifiedBy, PaymentDate) +SELECT + t.Id, + t.RefId, + TRY_CAST( + SUBSTRING(t.RefId, LEN(N'manualy') + 1, 20) + AS BIGINT + ), + t.Amount, + t.CreatedBy, + t.LastModifiedBy, + t.PaymentDate +FROM CMS.Transactions t +WHERE t.IsDeleted = 0 + AND t.RefId LIKE N'manualy%'; + +DECLARE @ManualyTxCount INT = (SELECT COUNT(*) FROM @ManualyTx); +PRINT CONCAT('manualy transactions in DB: ', @ManualyTxCount); + +------------------------------------------------------------ +-- 1) Each manualy Tx → User(s) via WH.RefrenceId / CreatedBy hint / mobile +------------------------------------------------------------ +PRINT '=== 1) manualy Tx → User resolution ==='; + +SELECT + mt.TransactionId, + mt.RefId, + mt.OriginalChangeLogId, + mt.Amount, + mt.PaymentDate, + mt.TxCreatedBy, + mt.TxLastModifiedBy, + u_mobile.Id AS UserByMobile, + u_mobile.Mobile AS UserByMobilePhone, + u_mobile.FirstName AS UserByMobileFirst, + u_mobile.LastName AS UserByMobileLast, + h_linked.Id AS WhIdViaRef, + h_linked.WalletId AS WhWalletViaRef, + u_wh.Id AS UserViaWhRef, + h_hint.Id AS WhIdViaCreatedByHint, + h_hint.WalletId AS WhWalletViaHint, + u_hint.Id AS UserViaWhHint, + CASE + WHEN u_wh.Id IS NOT NULL THEN N'WH_REFRENCE_ID' + WHEN u_hint.Id IS NOT NULL THEN N'WH_CREATEDBY_HINT' + WHEN u_mobile.Id IS NOT NULL THEN N'TX_MOBILE_ONLY' + ELSE N'UNRESOLVED' + END AS PrimaryLink, + CASE + WHEN u_wh.Id IS NOT NULL AND u_hint.Id IS NOT NULL AND u_wh.Id <> u_hint.Id + THEN N'CONFLICT_WH_REF_VS_HINT' + WHEN u_wh.Id IS NOT NULL AND u_mobile.Id IS NOT NULL AND u_wh.Id <> u_mobile.Id + THEN N'CONFLICT_WH_REF_VS_MOBILE' + WHEN u_wh.Id IS NULL AND u_hint.Id IS NULL AND u_mobile.Id IS NULL + THEN N'NO_USER_FOUND' + ELSE N'OK' + END AS LinkQuality +FROM @ManualyTx mt +LEFT JOIN CMS.Users u_mobile ON u_mobile.IsDeleted = 0 + AND u_mobile.Mobile IN ( + NULLIF(LTRIM(RTRIM(mt.TxCreatedBy)), N''), + NULLIF(LTRIM(RTRIM(mt.TxLastModifiedBy)), N'') + ) +LEFT JOIN CMS.UserWalletHistories h_linked ON h_linked.IsDeleted = 0 + AND h_linked.RefrenceId = mt.TransactionId +LEFT JOIN CMS.UserWallets w_linked ON w_linked.Id = h_linked.WalletId AND w_linked.IsDeleted = 0 +LEFT JOIN CMS.Users u_wh ON u_wh.Id = w_linked.UserId AND u_wh.IsDeleted = 0 +LEFT JOIN CMS.UserWalletHistories h_hint ON h_hint.IsDeleted = 0 + AND (h_hint.RefrenceId IS NULL OR h_hint.RefrenceId = 0) + AND TRY_CAST(h_hint.CreatedBy AS BIGINT) = mt.TransactionId +LEFT JOIN CMS.UserWallets w_hint ON w_hint.Id = h_hint.WalletId AND w_hint.IsDeleted = 0 +LEFT JOIN CMS.Users u_hint ON u_hint.Id = w_hint.UserId AND u_hint.IsDeleted = 0 +ORDER BY mt.TransactionId; + +------------------------------------------------------------ +-- 2) WH rows with RefrenceId=0 — CreatedBy hint analysis +------------------------------------------------------------ +PRINT '=== 2) WalletHistory RefrenceId=0 (manualy charge candidates) ==='; + +SELECT + h.Id AS WalletHistoryId, + h.WalletId, + w.UserId AS WalletUserId, + u.Mobile AS WalletUserMobile, + h.RefrenceId AS WhRefrenceId, + h.ChangeValue, + h.Created AS WhCreated, + h.CreatedBy AS WhCreatedBy, + h.LastModifiedBy AS WhLastModifiedBy, + t_hint.Id AS TxByCreatedByHint, + t_hint.RefId AS TxHintRefId, + t_hint.Amount AS TxHintAmount, + u_hint_mobile.Id AS TxHintUserByMobile, + CASE + WHEN TRY_CAST(h.CreatedBy AS BIGINT) IS NULL OR TRY_CAST(h.CreatedBy AS BIGINT) = 0 + THEN N'NO_NUMERIC_HINT' + WHEN t_hint.Id IS NULL + THEN N'HINT_POINTS_TO_MISSING_TX' + WHEN t_hint.RefId NOT LIKE N'manualy%' + THEN N'HINT_TX_NOT_MANUALY' + WHEN w.UserId = u_hint_mobile.Id + THEN N'FIX_LINK_WH_TO_HINT_TX' + WHEN u_hint_mobile.Id IS NOT NULL AND w.UserId <> u_hint_mobile.Id + THEN N'HINT_TX_USER_MISMATCH_WALLET' + ELSE N'FIX_LINK_REVIEW_MOBILE' + END AS WhZeroRefVerdict, + CASE + WHEN t_hint.Id IS NOT NULL AND t_hint.RefId LIKE N'manualy%' + THEN CONCAT(N'UPDATE WH ', h.Id, N' SET RefrenceId=', t_hint.Id) + WHEN TRY_CAST(h.CreatedBy AS BIGINT) IS NULL OR TRY_CAST(h.CreatedBy AS BIGINT) = 0 + THEN N'Cannot auto-link — no CreatedBy Tx hint' + ELSE N'Tx from hint missing — may need manual charge review' + END AS SuggestedAction +FROM CMS.UserWalletHistories h +INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 +LEFT JOIN CMS.Users u ON u.Id = w.UserId AND u.IsDeleted = 0 +LEFT JOIN CMS.Transactions t_hint ON t_hint.Id = TRY_CAST(h.CreatedBy AS BIGINT) + AND t_hint.IsDeleted = 0 +LEFT JOIN CMS.Users u_hint_mobile ON u_hint_mobile.IsDeleted = 0 + AND u_hint_mobile.Mobile IN ( + NULLIF(LTRIM(RTRIM(t_hint.CreatedBy)), N''), + NULLIF(LTRIM(RTRIM(t_hint.LastModifiedBy)), N'') + ) +WHERE h.IsDeleted = 0 + AND (h.RefrenceId IS NULL OR h.RefrenceId = 0) + AND ( + TRY_CAST(h.CreatedBy AS BIGINT) IS NOT NULL + OR h.LastModifiedBy LIKE N'09%' + OR EXISTS ( + SELECT 1 FROM @ManualyTx mt + WHERE mt.OriginalChangeLogId = h.Id + ) + ) +ORDER BY h.Id; + +------------------------------------------------------------ +-- 3) manualy suffix vs current WH.Id (id-shift detector) +------------------------------------------------------------ +PRINT '=== 3) manualy suffix N vs current WH.Id (id shift) ==='; + +SELECT + mt.TransactionId, + mt.RefId, + mt.OriginalChangeLogId AS ManualySuffixN, + h_by_suffix.Id AS CurrentWhIdWithSameIdAsSuffix, + h_by_suffix.RefrenceId AS ThatWhRefrenceId, + h_by_suffix.WalletId, + CASE + WHEN h_by_suffix.Id IS NULL THEN N'SUFFIX_WH_ID_GONE' + WHEN h_by_suffix.RefrenceId = mt.TransactionId THEN N'SUFFIX_WH_LINKED_OK' + WHEN h_by_suffix.RefrenceId IS NULL OR h_by_suffix.RefrenceId = 0 + THEN N'SUFFIX_WH_EXISTS_BROKEN_REF' + ELSE N'SUFFIX_WH_POINTS_OTHER_TX' + END AS SuffixMatchStatus +FROM @ManualyTx mt +LEFT JOIN CMS.UserWalletHistories h_by_suffix ON h_by_suffix.Id = mt.OriginalChangeLogId + AND h_by_suffix.IsDeleted = 0 +ORDER BY mt.TransactionId; + +------------------------------------------------------------ +-- 4) Distinct users in scope for script 6 (manualy-linked only) +------------------------------------------------------------ +PRINT '=== 4) Users in manualy fix scope ==='; + +;WITH ScopeUsers AS ( + SELECT DISTINCT w.UserId, mt.TransactionId, N'WH_REF' AS Source + FROM @ManualyTx mt + INNER JOIN CMS.UserWalletHistories h ON h.RefrenceId = mt.TransactionId AND h.IsDeleted = 0 + INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 + + UNION + + SELECT DISTINCT w.UserId, t.Id, N'WH_CREATEDBY_HINT' + FROM CMS.UserWalletHistories h + INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 + INNER JOIN CMS.Transactions t ON t.Id = TRY_CAST(h.CreatedBy AS BIGINT) + AND t.IsDeleted = 0 AND t.RefId LIKE N'manualy%' + WHERE h.IsDeleted = 0 + AND (h.RefrenceId IS NULL OR h.RefrenceId = 0) + AND TRY_CAST(h.CreatedBy AS BIGINT) > 0 + + UNION + + SELECT DISTINCT u.Id, mt.TransactionId, N'TX_MOBILE' + FROM @ManualyTx mt + INNER JOIN CMS.Users u ON u.IsDeleted = 0 + AND u.Mobile IN ( + NULLIF(LTRIM(RTRIM(mt.TxCreatedBy)), N''), + NULLIF(LTRIM(RTRIM(mt.TxLastModifiedBy)), N'') + ) +) +SELECT + su.UserId, + u.Mobile, + u.FirstName, + u.LastName, + u.PackagePurchaseMethod, + MIN(su.TransactionId) AS SampleManualyTxId, + STRING_AGG(su.Source, N', ') WITHIN GROUP (ORDER BY su.Source) AS LinkSources, + CASE WHEN EXISTS ( + SELECT 1 FROM CMS.Transactions t2 + WHERE t2.IsDeleted = 0 AND t2.RefId LIKE N'C4%' + AND EXISTS ( + SELECT 1 FROM CMS.Users ux + WHERE ux.Id = su.UserId AND ux.IsDeleted = 0 + AND ux.Mobile IN (NULLIF(t2.CreatedBy,N''), NULLIF(t2.LastModifiedBy,N'')) + ) + ) THEN 1 ELSE 0 END AS AlsoHasC4Tx, + (SELECT COUNT(*) FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = su.UserId AND upp.IsDeleted = 0) AS UppCount +FROM ScopeUsers su +INNER JOIN CMS.Users u ON u.Id = su.UserId AND u.IsDeleted = 0 +GROUP BY su.UserId, u.Mobile, u.FirstName, u.LastName, u.PackagePurchaseMethod +ORDER BY su.UserId; + +PRINT 'Done (diagnostic only — no changes).'; diff --git a/src/dbbkup/10-result.csv b/src/dbbkup/10-result.csv new file mode 100644 index 0000000..7e7237d --- /dev/null +++ b/src/dbbkup/10-result.csv @@ -0,0 +1,104 @@ +"TransactionId","RefId","OriginalChangeLogId","Amount","PaymentDate","TxCreatedBy","TxLastModifiedBy","UserByMobile","UserByMobilePhone","UserByMobileFirst","UserByMobileLast","WhIdViaRef","WhWalletViaRef","UserViaWhRef","WhIdViaCreatedByHint","WhWalletViaHint","UserViaWhHint","PrimaryLink","LinkQuality" +"23","manualy24","24","56000000","19/11/2025 01:24:24",,,,,,,"102","38","75",,,,"WH_REFRENCE_ID","OK" +"23","manualy24","24","56000000","19/11/2025 01:24:24",,,,,,,"216","24","47",,,,"WH_REFRENCE_ID","OK" +"24","manualy25","25","56000000","19/11/2025 01:24:24",,,,,,,"103","46","93",,,,"WH_REFRENCE_ID","OK" +"24","manualy25","25","56000000","19/11/2025 01:24:24",,,,,,,"217","6","50",,,,"WH_REFRENCE_ID","OK" +"25","manualy26","26","56000000","19/11/2025 01:24:24",,,,,,,"104","47","96","218","34","71","WH_REFRENCE_ID","CONFLICT_WH_REF_VS_HINT" +"26","manualy27","27","56000000","19/11/2025 01:24:24",,,,,,,"105","49","99","219","37","74","WH_REFRENCE_ID","CONFLICT_WH_REF_VS_HINT" +"28","manualy29","29","56000000","19/11/2025 01:24:24",,,,,,,"106","24","47",,,,"WH_REFRENCE_ID","OK" +"28","manualy29","29","56000000","19/11/2025 01:24:24",,,,,,,"221","42","88",,,,"WH_REFRENCE_ID","OK" +"29","manualy30","30","56000000","19/11/2025 01:24:24",,,,,,,"107","22","43",,,,"WH_REFRENCE_ID","OK" +"29","manualy30","30","56000000","19/11/2025 01:24:24",,,,,,,"222","62","114",,,,"WH_REFRENCE_ID","OK" +"30","manualy31","31","56000000","19/11/2025 01:24:24",,,,,,,"108","23","45",,,,"WH_REFRENCE_ID","OK" +"30","manualy31","31","56000000","19/11/2025 01:24:24",,,,,,,"223","13","7",,,,"WH_REFRENCE_ID","OK" +"31","manualy32","32","56000000","28/11/2025 05:27:38",,,,,,,"122","26","52",,,,"WH_REFRENCE_ID","OK" +"31","manualy32","32","56000000","28/11/2025 05:27:38",,,,,,,"224","15","9",,,,"WH_REFRENCE_ID","OK" +"42","manualy43","43","56000000","3/12/2025 09:49:45.92","09014638673","09014638673","116","09014638673","سالار","رضائی","138","64","116",,,,"WH_REFRENCE_ID","OK" +"42","manualy43","43","56000000","3/12/2025 09:49:45.92","09014638673","09014638673","116","09014638673","سالار","رضائی","235","24","47",,,,"WH_REFRENCE_ID","CONFLICT_WH_REF_VS_MOBILE" +"43","manualy44","44","56000000","3/12/2025 09:49:45.92","09056365323","09056365323","115","09056365323","حامد","دهقانی","139","63","115","236","32","69","WH_REFRENCE_ID","CONFLICT_WH_REF_VS_HINT" +"44","manualy45","45","56000000","3/12/2025 09:49:45.92","09126092994","09126092994","119","09126092994","علیرضا ","کریمی پیروز ","140","67","119",,,,"WH_REFRENCE_ID","OK" +"44","manualy45","45","56000000","3/12/2025 09:49:45.92","09126092994","09126092994","119","09126092994","علیرضا ","کریمی پیروز ","237","38","75",,,,"WH_REFRENCE_ID","CONFLICT_WH_REF_VS_MOBILE" +"45","manualy46","46","56000000","3/12/2025 09:49:45.92","09177325630","09177325630","113","09177325630","کاوس","بیگ اینالو","141","61","113",,,,"WH_REFRENCE_ID","OK" +"45","manualy46","46","56000000","3/12/2025 09:49:45.92","09177325630","09177325630","113","09177325630","کاوس","بیگ اینالو","238","6","50",,,,"WH_REFRENCE_ID","CONFLICT_WH_REF_VS_MOBILE" +"46","manualy47","47","56000000","3/12/2025 09:49:45.92","09384366040","09384366040","103","09384366040","علی ","دلال زاده","142","51","103",,,,"WH_REFRENCE_ID","OK" +"46","manualy47","47","56000000","3/12/2025 09:49:45.92","09384366040","09384366040","103","09384366040","علی ","دلال زاده","239","13","7",,,,"WH_REFRENCE_ID","CONFLICT_WH_REF_VS_MOBILE" +"56","manualy57","57","56000000","3/12/2025 09:49:45.92","09015793338","09015793338","71","09015793338","حمیدرضا","مرجانی","249","62","114","118","34","71","WH_REFRENCE_ID","CONFLICT_WH_REF_VS_HINT" +"57","manualy58","58","56000000","19/11/2025 01:24:24","09961354257","09961354257",,,,,"250","13","7","124","35","72","WH_REFRENCE_ID","CONFLICT_WH_REF_VS_HINT" +"58","manualy59","59","56000000","19/11/2025 01:24:24","09217672935","09217672935","69","09217672935","مهدی ","گیوی ","251","15","9","119","32","69","WH_REFRENCE_ID","CONFLICT_WH_REF_VS_HINT" +"59","manualy60","60","56000000","19/11/2025 01:24:24","09101692049","09101692049","74","09101692049","سجاد ","اداوی","252","22","43","120","37","74","WH_REFRENCE_ID","CONFLICT_WH_REF_VS_HINT" +"68","manualy69","69","56000000","8/12/2025 12:30:53.536666","09399172812","09399172812","142","09399172812","صغری","شبانکاره ",,,,,,,"TX_MOBILE_ONLY","OK" +"107","manualy292","292","56000000","30/12/2025 01:24:24",,,,,,,"186","15","9",,,,"WH_REFRENCE_ID","OK" +"107","manualy292","292","56000000","30/12/2025 01:24:24",,,,,,,"292","118","170",,,,"WH_REFRENCE_ID","OK" +"107","manualy292","292","56000000","30/12/2025 01:24:24",,,,,,,"40399","34","71",,,,"WH_REFRENCE_ID","OK" +"108","manualy293","293","56000000","31/12/2025 01:24:24",,,,,,,"187","22","43",,,,"WH_REFRENCE_ID","OK" +"108","manualy293","293","56000000","31/12/2025 01:24:24",,,,,,,"293","119","171",,,,"WH_REFRENCE_ID","OK" +"108","manualy293","293","56000000","31/12/2025 01:24:24",,,,,,,"40400","38","75",,,,"WH_REFRENCE_ID","OK" +"109","manualy294","294","56000000","31/12/2025 01:24:24",,,,,,,"188","23","45",,,,"WH_REFRENCE_ID","OK" +"109","manualy294","294","56000000","31/12/2025 01:24:24",,,,,,,"294","120","172",,,,"WH_REFRENCE_ID","OK" +"109","manualy294","294","56000000","31/12/2025 01:24:24",,,,,,,"40401","59","111",,,,"WH_REFRENCE_ID","OK" +"110","manualy295","295","56000000","1/1/2026 17:07:53.2301978",,,,,,,"189","24","47",,,,"WH_REFRENCE_ID","OK" +"110","manualy295","295","56000000","1/1/2026 17:07:53.2301978",,,,,,,"295","123","175",,,,"WH_REFRENCE_ID","OK" +"110","manualy295","295","56000000","1/1/2026 17:07:53.2301978",,,,,,,"40402","134","186",,,,"WH_REFRENCE_ID","OK" +"118","34","71","09015793338","0","1","3/12/2025 09:49:45.92","56","09015793338","56","manualy57","56000000","71","FIX_LINK_WH_TO_HINT_TX","UPDATE WH 118 SET RefrenceId=56" +"119","32","69","09217672935","0","1","19/11/2025 01:24:24","58","09217672935","58","manualy59","56000000","69","FIX_LINK_WH_TO_HINT_TX","UPDATE WH 119 SET RefrenceId=58" +"120","37","74","09101692049","0","1","19/11/2025 01:24:24","59","09101692049","59","manualy60","56000000","74","FIX_LINK_WH_TO_HINT_TX","UPDATE WH 120 SET RefrenceId=59" +"121","12","2","09387342688","0","1","19/12/2025 22:00:40.276666","0","09387342688",,,,,"NO_NUMERIC_HINT","Cannot auto-link — no CreatedBy Tx hint" +"124","35","72","09124678697","0","1","19/11/2025 01:24:24","57","09961354257","57","manualy58","56000000",,"FIX_LINK_REVIEW_MOBILE","UPDATE WH 124 SET RefrenceId=57" +"201","110","162","09199877503","0","1","20/12/2025 02:24:42.771904","92","162",,,,,"HINT_POINTS_TO_MISSING_TX","Tx from hint missing — may need manual charge review" +"209","32","69","09217672935","0","0","20/12/2025 10:30:49.186666","16","SP","16","localwallet-d0870aee-8a21-4cfc-a5a0-362b25795af0","10000",,"HINT_TX_NOT_MANUALY","Tx from hint missing — may need manual charge review" +"218","34","71","09015793338","0","0","20/12/2025 10:31:12.52","25","SP","25","manualy26","56000000",,"FIX_LINK_REVIEW_MOBILE","UPDATE WH 218 SET RefrenceId=25" +"219","37","74","09101692049","0","0","20/12/2025 10:31:12.52","26","SP","26","manualy27","56000000",,"FIX_LINK_REVIEW_MOBILE","UPDATE WH 219 SET RefrenceId=26" +"236","32","69","09217672935","0","0","20/12/2025 10:38:43.333333","43","SP","43","manualy44","56000000","115","HINT_TX_USER_MISMATCH_WALLET","UPDATE WH 236 SET RefrenceId=43" +"245","34","71","09015793338","0","0","20/12/2025 10:39:58.833333","52","SP","52","localwallet-533cd27c-9ff5-497b-b23d-68df374c1107","37035000",,"HINT_TX_NOT_MANUALY","Tx from hint missing — may need manual charge review" +"246","37","74","09101692049","0","0","20/12/2025 10:39:58.833333","53","SP","53","C4_N9894294","56000000","88","HINT_TX_NOT_MANUALY","Tx from hint missing — may need manual charge review" +"23","manualy24","24",,,,"SUFFIX_WH_ID_GONE" +"24","manualy25","25",,,,"SUFFIX_WH_ID_GONE" +"25","manualy26","26",,,,"SUFFIX_WH_ID_GONE" +"26","manualy27","27",,,,"SUFFIX_WH_ID_GONE" +"28","manualy29","29",,,,"SUFFIX_WH_ID_GONE" +"29","manualy30","30",,,,"SUFFIX_WH_ID_GONE" +"30","manualy31","31",,,,"SUFFIX_WH_ID_GONE" +"31","manualy32","32",,,,"SUFFIX_WH_ID_GONE" +"42","manualy43","43",,,,"SUFFIX_WH_ID_GONE" +"43","manualy44","44",,,,"SUFFIX_WH_ID_GONE" +"44","manualy45","45",,,,"SUFFIX_WH_ID_GONE" +"45","manualy46","46",,,,"SUFFIX_WH_ID_GONE" +"46","manualy47","47",,,,"SUFFIX_WH_ID_GONE" +"56","manualy57","57",,,,"SUFFIX_WH_ID_GONE" +"57","manualy58","58",,,,"SUFFIX_WH_ID_GONE" +"58","manualy59","59",,,,"SUFFIX_WH_ID_GONE" +"59","manualy60","60",,,,"SUFFIX_WH_ID_GONE" +"68","manualy69","69",,,,"SUFFIX_WH_ID_GONE" +"107","manualy292","292","292","107","118","SUFFIX_WH_LINKED_OK" +"108","manualy293","293","293","108","119","SUFFIX_WH_LINKED_OK" +"109","manualy294","294","294","109","120","SUFFIX_WH_LINKED_OK" +"110","manualy295","295","295","110","123","SUFFIX_WH_LINKED_OK" +"7","09128676640","مهدی","صیفی","3","30","WH_REF, WH_REF, WH_REF","0","0" +"9","09387095611","مهدی","مرجانی","3","31","WH_REF, WH_REF, WH_REF","0","0" +"43","09039033341","کریم","خادمی ","3","29","WH_REF, WH_REF, WH_REF","0","0" +"45","09121150062","علی","دلال زاده","3","30","WH_REF, WH_REF","0","0" +"47","09123122544","صدیقه","منعمیان","3","23","WH_REF, WH_REF, WH_REF, WH_REF","0","0" +"50","09207316560","مرتضی ","اینالو","1","24","WH_REF, WH_REF","0","1" +"52","09178327020","حمیدرضا ","اسمعیلی ","3","31","WH_REF","0","0" +"69","09217672935","مهدی ","گیوی ","3","43","TX_MOBILE, WH_CREATEDBY_HINT, WH_CREATEDBY_HINT","0","0" +"71","09015793338","حمیدرضا","مرجانی","3","25","TX_MOBILE, WH_CREATEDBY_HINT, WH_CREATEDBY_HINT, WH_REF","0","0" +"72","09124678697","مژگان","گیوی","3","57","WH_CREATEDBY_HINT","0","0" +"74","09101692049","سجاد ","اداوی","3","26","TX_MOBILE, WH_CREATEDBY_HINT, WH_CREATEDBY_HINT","0","0" +"75","09353851578","پویا","عبدی ","3","23","WH_REF, WH_REF, WH_REF","0","0" +"88","09172606097","کریم","رعیت پیشه","1","28","WH_REF","1","0" +"93","09122156286","ریحانه سادات ","هاشمی نصر ","3","24","WH_REF","0","0" +"96","09125020729","غلامرضا ","عبدی ","3","25","WH_REF","0","0" +"99","09106519822","هستی","خادمی","3","26","WH_REF","0","0" +"103","09384366040","علی ","دلال زاده","3","46","TX_MOBILE, WH_REF","0","0" +"111","09352828086","انسیه","توسلیان","1","109","WH_REF","0","0" +"113","09177325630","کاوس","بیگ اینالو","3","45","TX_MOBILE, WH_REF","0","0" +"114","09397939699","اکرم","دهقانی","1","29","WH_REF, WH_REF","1","0" +"115","09056365323","حامد","دهقانی","3","43","TX_MOBILE, WH_REF","0","0" +"116","09014638673","سالار","رضائی","3","42","TX_MOBILE, WH_REF","0","0" +"119","09126092994","علیرضا ","کریمی پیروز ","3","44","TX_MOBILE, WH_REF","0","0" +"142","09399172812","صغری","شبانکاره ","3","68","TX_MOBILE","0","0" +"170","09120991323","لیلا","خدارحمی دره میانه","3","107","WH_REF","0","0" +"171","09375724408","مژده","بنی هاشمی","3","108","WH_REF","0","0" +"172","09121355832","مهرافشان","زاهدنیا","3","109","WH_REF","0","0" +"175","09122332219","ناهید ","حسن زاده مژدهی","3","110","WH_REF","0","0" +"186","09395618852","احمد","عالم","2","110","WH_REF","0","2" diff --git a/src/dbbkup/11-Diagnose_PackageHolderCounts_ByLeg.sql b/src/dbbkup/11-Diagnose_PackageHolderCounts_ByLeg.sql new file mode 100644 index 0000000..2d01f66 --- /dev/null +++ b/src/dbbkup/11-Diagnose_PackageHolderCounts_ByLeg.sql @@ -0,0 +1,77 @@ +-- ============================================= +-- Diagnose: Package holder counts per leg (read-only) +-- Compares OLD source (NetworkWeeklyBalances) vs NEW (active members + current cycle) +-- Usage: SET @RootUserId to the tree owner UserId +-- ============================================= + +DECLARE @RootUserId BIGINT = 1; -- ← change to target user + +DECLARE @GoldPackageId BIGINT = ( + SELECT TOP 1 Id FROM CMS.Packages + WHERE IsDeleted = 0 AND IsActive = 1 AND IsBasePackage = 1 + ORDER BY Id +); +DECLARE @SilverPackageId BIGINT = ( + SELECT TOP 1 Id FROM CMS.Packages + WHERE IsDeleted = 0 AND IsActive = 1 AND IsBasePackage = 0 + AND (Title LIKE N'%نقر%' OR MaxBalancesPerLeg <= 30) + ORDER BY Id +); + +DECLARE @LeftChildId BIGINT = ( + SELECT Id FROM CMS.Users + WHERE NetworkParentId = @RootUserId AND LegPosition = 0 AND IsDeleted = 0 +); +DECLARE @RightChildId BIGINT = ( + SELECT Id FROM CMS.Users + WHERE NetworkParentId = @RootUserId AND LegPosition = 1 AND IsDeleted = 0 +); + +;WITH LegUsers AS ( + SELECT @LeftChildId AS RootLegUserId, 0 AS LegSide + WHERE @LeftChildId IS NOT NULL + UNION ALL + SELECT @RightChildId, 1 + WHERE @RightChildId IS NOT NULL +), +Subtree AS ( + SELECT lu.RootLegUserId, lu.LegSide, lu.RootLegUserId AS UserId + FROM LegUsers lu + + UNION ALL + + SELECT s.RootLegUserId, s.LegSide, u.Id + FROM Subtree s + INNER JOIN CMS.Users u ON u.NetworkParentId = s.UserId AND u.IsDeleted = 0 +), +ActivePackageHolders AS ( + SELECT + s.LegSide, + cc.PackageId, + COUNT(DISTINCT s.UserId) AS HolderCount + FROM Subtree s + INNER JOIN CMS.ClubMemberships cm ON cm.UserId = s.UserId AND cm.IsActive = 1 AND cm.IsDeleted = 0 + INNER JOIN CMS.ClubMembershipCycles cc ON cc.UserId = s.UserId AND cc.IsCurrentCycle = 1 + GROUP BY s.LegSide, cc.PackageId +), +LatestNwb AS ( + SELECT PackageId, LeftLegTotal, RightLegTotal, WeekDefinitionId, + ROW_NUMBER() OVER (PARTITION BY PackageId ORDER BY WeekDefinitionId DESC) AS rn + FROM CMS.NetworkWeeklyBalances + WHERE UserId = @RootUserId + AND PackageId IN (@GoldPackageId, @SilverPackageId) +) +SELECT + @RootUserId AS RootUserId, + @GoldPackageId AS GoldPackageId, + @SilverPackageId AS SilverPackageId, + -- NEW: real holder counts + ISNULL((SELECT HolderCount FROM ActivePackageHolders WHERE LegSide = 0 AND PackageId = @GoldPackageId), 0) AS New_GoldLeft, + ISNULL((SELECT HolderCount FROM ActivePackageHolders WHERE LegSide = 1 AND PackageId = @GoldPackageId), 0) AS New_GoldRight, + ISNULL((SELECT HolderCount FROM ActivePackageHolders WHERE LegSide = 0 AND PackageId = @SilverPackageId), 0) AS New_SilverLeft, + ISNULL((SELECT HolderCount FROM ActivePackageHolders WHERE LegSide = 1 AND PackageId = @SilverPackageId), 0) AS New_SilverRight, + -- OLD: weekly balance scores (previous wrong source) + ISNULL((SELECT LeftLegTotal FROM LatestNwb WHERE PackageId = @GoldPackageId AND rn = 1), 0) AS Old_Nwb_GoldLeft, + ISNULL((SELECT RightLegTotal FROM LatestNwb WHERE PackageId = @GoldPackageId AND rn = 1), 0) AS Old_Nwb_GoldRight, + ISNULL((SELECT LeftLegTotal FROM LatestNwb WHERE PackageId = @SilverPackageId AND rn = 1), 0) AS Old_Nwb_SilverLeft, + ISNULL((SELECT RightLegTotal FROM LatestNwb WHERE PackageId = @SilverPackageId AND rn = 1), 0) AS Old_Nwb_SilverRight; diff --git a/src/dbbkup/Rollback_Backfill_UserPackagePurchases.sql b/src/dbbkup/2-Rollback_Backfill_UserPackagePurchases.sql similarity index 100% rename from src/dbbkup/Rollback_Backfill_UserPackagePurchases.sql rename to src/dbbkup/2-Rollback_Backfill_UserPackagePurchases.sql diff --git a/src/dbbkup/Update_DayaLoanContracts_ContractNumbers.sql b/src/dbbkup/3-Update_DayaLoanContracts_ContractNumbers.sql similarity index 100% rename from src/dbbkup/Update_DayaLoanContracts_ContractNumbers.sql rename to src/dbbkup/3-Update_DayaLoanContracts_ContractNumbers.sql diff --git a/src/dbbkup/Fix_Daya_ActiveExcel_ProcessMissing.sql b/src/dbbkup/4-Fix_Daya_ActiveExcel_ProcessMissing.sql similarity index 77% rename from src/dbbkup/Fix_Daya_ActiveExcel_ProcessMissing.sql rename to src/dbbkup/4-Fix_Daya_ActiveExcel_ProcessMissing.sql index 2cdd54b..00de7bf 100644 --- a/src/dbbkup/Fix_Daya_ActiveExcel_ProcessMissing.sql +++ b/src/dbbkup/4-Fix_Daya_ActiveExcel_ProcessMissing.sql @@ -5,10 +5,12 @@ Classification: DONE — credit + processed + Daya UPP PARTIAL — HasReceivedDayaCredit OR IsProcessed OR existing «اعتبار دایا» Tx in wallet - NOT_PROCESSED — none of the above (will create Tx + charge) + NOT_PROCESSED — none of the above (will create Tx + ledger WH) If ExistingDayaTxId found (wallet RefrenceId → Tx Description LIKE '%اعتبار دایا%' - OR Tx.RefId = ContractNumber): REUSE that Tx — do NOT create Transaction / do NOT charge wallet. + OR Tx.RefId = ContractNumber): REUSE that Tx — do NOT create Transaction. + + NO wallet Balance/DiscountBalance charge — UserWalletHistory is ledger-only when needed. Special UserId mapping (shared NationalCode): C4_D8815963 / 2490371436 → UserId 50 @@ -185,12 +187,68 @@ SELECT ContractNumber, NationalCode, UserId, DayaContractId, HasCredit, IsProces FROM @Work ORDER BY Verdict, ContractNumber; +------------------------------------------------------------ +-- PREVIEW: ledger actions (no wallet charge) +------------------------------------------------------------ +PRINT '=== LEDGER PREVIEW (Tx + WH history-only — NO wallet charge) ==='; + +SELECT + w.ContractNumber, + w.NationalCode, + w.UserId, + w.Verdict, + w.HasCredit, + w.ExistingDayaTxId, + CASE + WHEN w.UserId IS NULL THEN N'SKIP_NO_USER' + WHEN w.ExistingDayaTxId IS NOT NULL THEN N'REUSE_TX_ENSURE_WH_UPP' + WHEN w.HasCredit = 0 THEN N'CREATE_TX_WH_UPP' + ELSE N'SET_FLAGS_ONLY_UPP' + END AS LedgerAction +FROM @Work w +WHERE w.Verdict IN (N'NOT_PROCESSED', N'PARTIAL') +ORDER BY LedgerAction, w.ContractNumber; + +SELECT + CASE + WHEN w.UserId IS NULL THEN N'SKIP_NO_USER' + WHEN w.ExistingDayaTxId IS NOT NULL THEN N'REUSE_TX_ENSURE_WH_UPP' + WHEN w.HasCredit = 0 THEN N'CREATE_TX_WH_UPP' + ELSE N'SET_FLAGS_ONLY_UPP' + END AS LedgerAction, + COUNT(*) AS Cnt +FROM @Work w +WHERE w.Verdict IN (N'NOT_PROCESSED', N'PARTIAL') +GROUP BY + CASE + WHEN w.UserId IS NULL THEN N'SKIP_NO_USER' + WHEN w.ExistingDayaTxId IS NOT NULL THEN N'REUSE_TX_ENSURE_WH_UPP' + WHEN w.HasCredit = 0 THEN N'CREATE_TX_WH_UPP' + ELSE N'SET_FLAGS_ONLY_UPP' + END +ORDER BY LedgerAction; + +DECLARE @PreviewCreateTxCount INT = ( + SELECT COUNT(*) + FROM @Work w + WHERE w.Verdict IN (N'NOT_PROCESSED', N'PARTIAL') + AND w.UserId IS NOT NULL + AND w.ExistingDayaTxId IS NULL + AND w.HasCredit = 0 +); +PRINT CONCAT('>>> CREATE_TX (no wallet charge) count = ', @PreviewCreateTxCount); + BEGIN TRAN; DECLARE @ContractNumber NVARCHAR(50), @NationalCode NVARCHAR(20), @UserId BIGINT; DECLARE @DayaContractId BIGINT, @HasCredit BIT, @IsProcessed BIT, @HasDayaUpp BIT, @Verdict NVARCHAR(20); DECLARE @ExistingDayaTxId BIGINT; -DECLARE @TxId BIGINT, @WalletId BIGINT, @Action NVARCHAR(200); +DECLARE @TxId BIGINT, @WalletId BIGINT, @NetworkBalance BIGINT, @Action NVARCHAR(200); + +DECLARE @CreateTxCount INT = 0; +DECLARE @ReuseCount INT = 0; +DECLARE @SkipFlagsOnlyCount INT = 0; +DECLARE @WhCreatedCount INT = 0; DECLARE @Log TABLE ( ContractNumber NVARCHAR(50), @@ -254,12 +312,13 @@ BEGIN END ------------------------------------------------------------ - -- اگر تراکنش/شارژ «اعتبار دایا» از قبل هست → همان Tx را بگیر؛ شارژ نکن + -- Resolve Tx (reuse existing or create ledger Tx — NO wallet charge) ------------------------------------------------------------ IF @ExistingDayaTxId IS NOT NULL BEGIN SET @TxId = @ExistingDayaTxId; SET @Action = @Action + CONCAT(N'REUSE_EXISTING_DAYA_TX=', @TxId, N';'); + SET @ReuseCount = @ReuseCount + 1; UPDATE CMS.Users SET @@ -270,11 +329,10 @@ BEGIN WHERE Id = @UserId; SET @HasCredit = 1; - SET @Action = @Action + N'SET_USER_FLAGS(no charge);'; + SET @Action = @Action + N'SET_USER_FLAGS;'; END ELSE IF @HasCredit = 0 BEGIN - -- Full wallet charge only if never credited and no existing Daya tx INSERT INTO CMS.Transactions ( Amount, Description, PaymentStatus, PaymentDate, RefId, Type, @@ -284,61 +342,28 @@ BEGIN ( @PackagePrice, CONCAT(N'دریافت اعتبار دایا - قرارداد ', @ContractNumber), - 0, -- Success + 0, @Now, @ContractNumber, - 2, -- DepositExternal1 + 2, @Now, NULL, @Now, NULL, 0 ); SET @TxId = SCOPE_IDENTITY(); - - SELECT @WalletId = Id FROM CMS.UserWallets WHERE UserId = @UserId; - IF @WalletId IS NULL - BEGIN - INSERT INTO CMS.UserWallets (UserId, Balance, NetworkBalance, DiscountBalance, WalletMode, Created, LastModified, IsDeleted) - VALUES (@UserId, 0, 0, 0, 0, @Now, @Now, 0); - SET @WalletId = SCOPE_IDENTITY(); - END - - UPDATE CMS.UserWallets - SET - Balance = Balance + @PackagePrice, - DiscountBalance = DiscountBalance + @DiscountAmount, - LastModified = @Now - WHERE Id = @WalletId; - - INSERT INTO CMS.UserWalletHistories - ( - WalletId, CurrentBalance, ChangeValue, CurrentNetworkBalance, ChangeNerworkValue, - CurrentDiscountBalance, ChangeDiscountValue, IsIncrease, RefrenceId, PackageId, - Created, LastModified, IsDeleted - ) - VALUES - ( - @WalletId, 0, @PackagePrice, 0, 0, - 0, 0, 1, @TxId, @PackageId, - @Now, @Now, 0 - ), - ( - @WalletId, 0, 0, 0, 0, - 0, @DiscountAmount, 1, @TxId, @PackageId, - @Now, @Now, 0 - ); + SET @CreateTxCount = @CreateTxCount + 1; UPDATE CMS.Users SET HasReceivedDayaCredit = 1, DayaCreditReceivedAt = @Now, - PackagePurchaseMethod = 1, -- DayaLoan + PackagePurchaseMethod = 1, LastModified = @Now WHERE Id = @UserId; SET @HasCredit = 1; - SET @Action = @Action + N'CHARGE_WALLET+USER_FLAGS;'; + SET @Action = @Action + N'CREATE_TX+USER_FLAGS;'; END ELSE BEGIN - -- HasReceivedDayaCredit=1 ولی ExistingDayaTx پیدا نشد UPDATE CMS.Users SET PackagePurchaseMethod = 1, @@ -346,7 +371,51 @@ BEGIN DayaCreditReceivedAt = COALESCE(DayaCreditReceivedAt, @Now), LastModified = @Now WHERE Id = @UserId; - SET @Action = @Action + N'SKIP_CHARGE(HasReceivedDayaCredit);'; + SET @SkipFlagsOnlyCount = @SkipFlagsOnlyCount + 1; + SET @Action = @Action + N'SET_FLAGS_ONLY;'; + END + + ------------------------------------------------------------ + -- UserWalletHistory for Tx (ledger-only — NO Balance/Discount charge) + ------------------------------------------------------------ + IF @TxId IS NOT NULL + BEGIN + SELECT @WalletId = Id, @NetworkBalance = COALESCE(NetworkBalance, 0) + FROM CMS.UserWallets + WHERE UserId = @UserId AND 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, @Now, @Now, 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 + INSERT INTO CMS.UserWalletHistories + ( + WalletId, CurrentBalance, ChangeValue, CurrentNetworkBalance, ChangeNerworkValue, + CurrentDiscountBalance, ChangeDiscountValue, IsIncrease, RefrenceId, PackageId, + Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted + ) + VALUES + ( + @WalletId, 0, @PackagePrice, @NetworkBalance, 0, + 0, @DiscountAmount, 1, @TxId, @PackageId, + @Now, NULL, @Now, NULL, 0 + ); + SET @WhCreatedCount = @WhCreatedCount + 1; + SET @Action = @Action + N'INSERT_WH_HISTORY;'; + END END ------------------------------------------------------------ @@ -414,6 +483,12 @@ END CLOSE cur; DEALLOCATE cur; +PRINT '=== LEDGER SUMMARY (no wallet charge) ==='; +PRINT CONCAT('CREATE_TX count = ', @CreateTxCount); +PRINT CONCAT('REUSE_TX count = ', @ReuseCount); +PRINT CONCAT('SET_FLAGS_ONLY count = ', @SkipFlagsOnlyCount); +PRINT CONCAT('WH history created = ', @WhCreatedCount); + PRINT '=== Actions ==='; SELECT * FROM @Log ORDER BY VerdictBefore, ContractNumber; diff --git a/src/dbbkup/6-Fix_WrongDaya_ToManual_PurchaseMethod.sql b/src/dbbkup/6-Fix_WrongDaya_ToManual_PurchaseMethod.sql new file mode 100644 index 0000000..edeb16b --- /dev/null +++ b/src/dbbkup/6-Fix_WrongDaya_ToManual_PurchaseMethod.sql @@ -0,0 +1,547 @@ +/* + Fix users wrongly marked DayaLoan who were manually charged (RefId LIKE 'manualy%'). + + Scope: ONLY users linked to manualy transactions — NOT the full 47-user WrongDaya list. + Real Daya users (RefId LIKE 'C4%') are excluded automatically. + + Actions: + - PurchaseMethod 1→3 on Users / Club / Cycle / UPP + - Clear HasReceivedDayaCredit / DayaCreditReceivedAt + - Soft-delete stub DayaLoanContracts (unprocessed, no Tx) + - Fix broken WH.RefrenceId where CreatedBy hint points to existing manualy Tx + - Create missing UPP Manual(3) reusing existing manualy Tx (never create new Tx) + - Create missing WH rows only when Tx exists but no WH links to it (history-only, no charge) + + RefrenceId=0 rule: + Tx is resolved ONLY via numeric CreatedBy hint when that Tx exists with RefId manualy%. + Mobile-only or manualy{N} suffix alone is NOT used to assume a Tx exists. + + PackagePurchaseMethod: None=0, DayaLoan=1, DirectPurchase=2, Manual=3 + + Defaults to ROLLBACK. Uncomment COMMIT after verifying PRINT output. + Run 10-Diagnose_Manualy_Transaction_Map.sql first. +*/ + +SET NOCOUNT ON; +SET XACT_ABORT ON; + +BEGIN TRAN; + +DECLARE @Now DATETIME2 = SYSUTCDATETIME(); + +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; + +------------------------------------------------------------ +-- Scope: users linked to manualy transactions +-- (duplicate WH→Tx links exist from migration; rank by mobile match + charge amount + date) +------------------------------------------------------------ +DECLARE @ManualyUsers TABLE ( + UserId BIGINT NOT NULL PRIMARY KEY, + ManualyTxId BIGINT NULL, + LinkSource NVARCHAR(50) NULL +); + +SELECT t.Id AS TxId, t.RefId, t.Amount, t.PaymentDate, t.CreatedBy, t.LastModifiedBy +INTO #ManualyTx +FROM CMS.Transactions t +WHERE t.IsDeleted = 0 AND t.RefId LIKE N'manualy%'; + +SELECT + mt.TxId, + w.UserId, + h.Id AS WhId, + h.ChangeValue, + CASE + WHEN NULLIF(LTRIM(RTRIM(mt.CreatedBy)), N'') LIKE N'09%' + AND u.Mobile = NULLIF(LTRIM(RTRIM(mt.CreatedBy)), N'') THEN 1 + WHEN NULLIF(LTRIM(RTRIM(mt.LastModifiedBy)), N'') LIKE N'09%' + AND u.Mobile = NULLIF(LTRIM(RTRIM(mt.LastModifiedBy)), N'') THEN 1 + ELSE 0 + END AS MobileMatch, + CASE WHEN h.ChangeValue >= mt.Amount THEN 1 ELSE 0 END AS FullCharge, + ABS(DATEDIFF(SECOND, h.Created, mt.PaymentDate)) AS TimeDeltaSec +INTO #WhLinks +FROM #ManualyTx mt +INNER JOIN CMS.UserWalletHistories h ON h.RefrenceId = mt.TxId AND h.IsDeleted = 0 +INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 +INNER JOIN CMS.Users u ON u.Id = w.UserId AND u.IsDeleted = 0; + +SELECT UserId, TxId, WhId, MobileMatch, FullCharge, + ROW_NUMBER() OVER ( + PARTITION BY TxId + ORDER BY MobileMatch DESC, FullCharge DESC, TimeDeltaSec ASC, WhId ASC + ) AS rn +INTO #BestWhPerTx +FROM #WhLinks; + +INSERT INTO @ManualyUsers (UserId, ManualyTxId, LinkSource) +SELECT b.UserId, b.TxId, N'WH_REF_BEST' +FROM #BestWhPerTx b +WHERE b.rn = 1 + AND (b.MobileMatch = 1 OR b.FullCharge = 1); + +INSERT INTO @ManualyUsers (UserId, ManualyTxId, LinkSource) +SELECT DISTINCT w.UserId, t.Id, N'WH_CREATEDBY_HINT' +FROM CMS.UserWalletHistories h +INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 +INNER JOIN CMS.Transactions t ON t.Id = TRY_CAST(h.CreatedBy AS BIGINT) + AND t.IsDeleted = 0 AND t.RefId LIKE N'manualy%' +INNER JOIN CMS.Users u ON u.Id = w.UserId AND u.IsDeleted = 0 +WHERE h.IsDeleted = 0 + AND (h.RefrenceId IS NULL OR h.RefrenceId = 0) + AND TRY_CAST(h.CreatedBy AS BIGINT) > 0 + AND ( + NULLIF(LTRIM(RTRIM(t.CreatedBy)), N'') NOT LIKE N'09%' + OR u.Mobile IN ( + NULLIF(LTRIM(RTRIM(t.CreatedBy)), N''), + NULLIF(LTRIM(RTRIM(t.LastModifiedBy)), N'') + ) + ) + AND NOT EXISTS (SELECT 1 FROM @ManualyUsers m WHERE m.UserId = w.UserId); + +INSERT INTO @ManualyUsers (UserId, ManualyTxId, LinkSource) +SELECT DISTINCT u.Id, t.Id, N'TX_MOBILE' +FROM CMS.Transactions t +INNER JOIN CMS.Users u ON u.IsDeleted = 0 + AND u.Mobile IN ( + NULLIF(LTRIM(RTRIM(t.CreatedBy)), N''), + NULLIF(LTRIM(RTRIM(t.LastModifiedBy)), N'') + ) +WHERE t.IsDeleted = 0 AND t.RefId LIKE N'manualy%' + AND NOT EXISTS (SELECT 1 FROM @ManualyUsers m WHERE m.UserId = u.Id); + +-- Txs without mobile on row: keep best full-charge WH only (early batch 23-31) +INSERT INTO @ManualyUsers (UserId, ManualyTxId, LinkSource) +SELECT b.UserId, b.TxId, N'WH_REF_NO_MOBILE' +FROM #BestWhPerTx b +INNER JOIN #ManualyTx mt ON mt.TxId = b.TxId +WHERE b.rn = 1 + AND b.FullCharge = 1 + AND (NULLIF(LTRIM(RTRIM(mt.CreatedBy)), N'') IS NULL OR NULLIF(LTRIM(RTRIM(mt.CreatedBy)), N'') NOT LIKE N'09%') + AND (NULLIF(LTRIM(RTRIM(mt.LastModifiedBy)), N'') IS NULL OR NULLIF(LTRIM(RTRIM(mt.LastModifiedBy)), N'') NOT LIKE N'09%') + AND NOT EXISTS (SELECT 1 FROM @ManualyUsers m WHERE m.UserId = b.UserId); + +DROP TABLE #BestWhPerTx; +DROP TABLE #WhLinks; +DROP TABLE #ManualyTx; + +DECLARE @ScopeCount INT = (SELECT COUNT(*) FROM @ManualyUsers); +PRINT CONCAT('manualy scope users: ', @ScopeCount); +PRINT CONCAT('BasePackageId=', @BasePackageId, ' Price=', @BasePackagePrice); + +SELECT mu.UserId, u.Mobile, u.FirstName, u.LastName, + u.PackagePurchaseMethod, mu.ManualyTxId, mu.LinkSource +FROM @ManualyUsers mu +INNER JOIN CMS.Users u ON u.Id = mu.UserId AND u.IsDeleted = 0 +ORDER BY mu.UserId; + +------------------------------------------------------------ +-- Preview +------------------------------------------------------------ +SELECT 'Users with manualy Tx resolved' AS CheckName, COUNT(*) AS Cnt +FROM @ManualyUsers WHERE ManualyTxId IS NOT NULL +UNION ALL +SELECT 'Users in scope without resolved Tx', COUNT(*) +FROM @ManualyUsers WHERE ManualyTxId IS NULL +UNION ALL +SELECT 'Broken WH rows fixable via CreatedBy hint', COUNT(*) +FROM CMS.UserWalletHistories h +INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 +INNER JOIN @ManualyUsers mu ON mu.UserId = w.UserId +INNER JOIN CMS.Transactions t ON t.Id = TRY_CAST(h.CreatedBy AS BIGINT) + AND t.IsDeleted = 0 AND t.RefId LIKE N'manualy%' +WHERE h.IsDeleted = 0 + AND (h.RefrenceId IS NULL OR h.RefrenceId = 0) + AND TRY_CAST(h.CreatedBy AS BIGINT) > 0 +UNION ALL +SELECT 'Missing UPP in scope', COUNT(*) +FROM @ManualyUsers mu +WHERE NOT EXISTS ( + SELECT 1 FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = mu.UserId AND upp.IsDeleted = 0 +); + +------------------------------------------------------------ +-- 1) Fix broken WH.RefrenceId (CreatedBy hint → existing manualy Tx) +------------------------------------------------------------ +UPDATE h +SET + h.RefrenceId = t.Id, + h.LastModified = @Now +FROM CMS.UserWalletHistories h +INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 +INNER JOIN @ManualyUsers mu ON mu.UserId = w.UserId +INNER JOIN CMS.Transactions t ON t.Id = TRY_CAST(h.CreatedBy AS BIGINT) + AND t.IsDeleted = 0 + AND t.RefId LIKE N'manualy%' + AND t.PaymentStatus = 0 +WHERE h.IsDeleted = 0 + AND (h.RefrenceId IS NULL OR h.RefrenceId = 0) + AND TRY_CAST(h.CreatedBy AS BIGINT) > 0; + +PRINT CONCAT('WalletHistory RefrenceId fixed: ', @@ROWCOUNT); + +------------------------------------------------------------ +-- 2) Users — DayaLoan → Manual +------------------------------------------------------------ +UPDATE u +SET + u.PackagePurchaseMethod = 3, + u.HasReceivedDayaCredit = 0, + u.DayaCreditReceivedAt = NULL, + u.LastModified = @Now +FROM CMS.Users u +INNER JOIN @ManualyUsers mu ON mu.UserId = u.Id +WHERE u.IsDeleted = 0 + AND ( + u.PackagePurchaseMethod = 1 + OR u.HasReceivedDayaCredit = 1 + OR u.DayaCreditReceivedAt IS NOT NULL + ); + +PRINT CONCAT('Users updated: ', @@ROWCOUNT); + +------------------------------------------------------------ +-- 3) ClubMemberships +------------------------------------------------------------ +UPDATE m +SET m.PurchaseMethod = 3, m.LastModified = @Now +FROM CMS.ClubMemberships m +INNER JOIN @ManualyUsers mu ON mu.UserId = m.UserId +WHERE m.IsDeleted = 0 AND m.PurchaseMethod IN (0, 1); + +PRINT CONCAT('ClubMemberships updated: ', @@ROWCOUNT); + +------------------------------------------------------------ +-- 4) ClubMembershipCycles +------------------------------------------------------------ +UPDATE c +SET c.PurchaseMethod = 3, c.LastModified = @Now +FROM CMS.ClubMembershipCycles c +INNER JOIN @ManualyUsers mu ON mu.UserId = c.UserId +WHERE c.IsDeleted = 0 AND c.PurchaseMethod IN (0, 1); + +PRINT CONCAT('ClubMembershipCycles updated: ', @@ROWCOUNT); + +------------------------------------------------------------ +-- 5) UserPackagePurchases (existing rows Daya → Manual) +------------------------------------------------------------ +UPDATE upp +SET upp.PurchaseMethod = 3, upp.LastModified = @Now +FROM CMS.UserPackagePurchases upp +INNER JOIN @ManualyUsers mu ON mu.UserId = upp.UserId +WHERE upp.IsDeleted = 0 AND upp.PurchaseMethod = 1; + +PRINT CONCAT('UserPackagePurchases updated: ', @@ROWCOUNT); + +------------------------------------------------------------ +-- 6) Soft-delete stub DayaLoanContracts +------------------------------------------------------------ +UPDATE d +SET d.IsDeleted = 1, d.LastModified = @Now +FROM CMS.DayaLoanContracts d +INNER JOIN @ManualyUsers mu ON mu.UserId = d.UserId +WHERE d.IsDeleted = 0 + AND d.IsProcessed = 0 + AND d.TransactionId IS NULL + AND d.ProcessedDate IS NULL; + +PRINT CONCAT('DayaLoanContracts soft-deleted (stubs): ', @@ROWCOUNT); + +------------------------------------------------------------ +-- 7) Resolve best manualy Tx per user (post WH fix) +------------------------------------------------------------ +;WITH TxCandidates AS ( + SELECT mu.UserId, t.Id AS TxId, N'WH_REF' AS Src, 1 AS Pri + FROM @ManualyUsers mu + INNER JOIN CMS.UserWallets w ON w.UserId = mu.UserId AND w.IsDeleted = 0 + 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.RefId LIKE N'manualy%' AND t.PaymentStatus = 0 + + UNION ALL + + SELECT mu.UserId, t.Id, N'WH_HINT', 2 + FROM @ManualyUsers mu + INNER JOIN CMS.UserWallets w ON w.UserId = mu.UserId AND w.IsDeleted = 0 + INNER JOIN CMS.UserWalletHistories h ON h.WalletId = w.Id AND h.IsDeleted = 0 + INNER JOIN CMS.Transactions t ON t.Id = TRY_CAST(h.CreatedBy AS BIGINT) + AND t.IsDeleted = 0 AND t.RefId LIKE N'manualy%' AND t.PaymentStatus = 0 + WHERE (h.RefrenceId IS NULL OR h.RefrenceId = 0) + AND TRY_CAST(h.CreatedBy AS BIGINT) > 0 + + UNION ALL + + SELECT mu.UserId, t.Id, N'TX_MOBILE', 3 + FROM @ManualyUsers mu + INNER JOIN CMS.Users u ON u.Id = mu.UserId AND u.IsDeleted = 0 + INNER JOIN CMS.Transactions t ON t.IsDeleted = 0 + AND t.RefId LIKE N'manualy%' AND t.PaymentStatus = 0 + AND u.Mobile IN ( + NULLIF(LTRIM(RTRIM(t.CreatedBy)), N''), + NULLIF(LTRIM(RTRIM(t.LastModifiedBy)), N'') + ) + + UNION ALL + + SELECT mu.UserId, mu.ManualyTxId, mu.LinkSource, 4 + FROM @ManualyUsers mu + WHERE mu.ManualyTxId IS NOT NULL +), +BestTx AS ( + SELECT UserId, TxId, Src, + ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY Pri, TxId DESC) AS rn + FROM TxCandidates + WHERE TxId IS NOT NULL +) +SELECT + mu.UserId, + bt.TxId, + bt.Src AS TxSource, + COALESCE(NULLIF(cm.LastPackageId, 0), NULLIF(cm.FirstPackageId, 0), @BasePackageId) AS PackageId, + COALESCE(t.Amount, @BasePackagePrice) AS Amount, + COALESCE(t.PaymentDate, cm.ActivatedAt, @Now) AS PurchasedAt +INTO #ManualyUppPlan +FROM @ManualyUsers mu +LEFT JOIN BestTx bt ON bt.UserId = mu.UserId AND bt.rn = 1 +LEFT JOIN CMS.Transactions t ON t.Id = bt.TxId AND t.IsDeleted = 0 +LEFT JOIN CMS.ClubMemberships cm ON cm.UserId = mu.UserId AND cm.IsDeleted = 0 +WHERE NOT EXISTS ( + SELECT 1 FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = mu.UserId AND upp.IsDeleted = 0 +); + +DECLARE @UppPlanCount INT = (SELECT COUNT(*) FROM #ManualyUppPlan); +PRINT CONCAT('UPP to create: ', @UppPlanCount); + +SELECT UserId, TxId, TxSource, PackageId, Amount, PurchasedAt, + CASE WHEN TxId IS NULL THEN N'SKIP_NO_MANUALY_TX' ELSE N'CREATE_UPP' END AS PlanAction +FROM #ManualyUppPlan +ORDER BY UserId; + +DECLARE @UserId BIGINT; +DECLARE @TxId BIGINT; +DECLARE @PackageId BIGINT; +DECLARE @Amount BIGINT; +DECLARE @PurchasedAt DATETIME2; +DECLARE @CreatedUpp INT = 0; +DECLARE @SkippedNoTx INT = 0; + +DECLARE curUpp CURSOR LOCAL FAST_FORWARD FOR + SELECT UserId, TxId, PackageId, Amount, PurchasedAt + FROM #ManualyUppPlan; + +OPEN curUpp; +FETCH NEXT FROM curUpp INTO @UserId, @TxId, @PackageId, @Amount, @PurchasedAt; + +WHILE @@FETCH_STATUS = 0 +BEGIN + IF @TxId IS NULL OR @PackageId IS NULL OR @Amount IS NULL OR @Amount <= 0 + BEGIN + SET @SkippedNoTx = @SkippedNoTx + 1; + END + ELSE + BEGIN + INSERT INTO CMS.UserPackagePurchases + ( + UserId, PackageId, PurchaseMethod, PurchasedAt, Amount, + OrderId, TransactionId, Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted + ) + VALUES + ( + @UserId, @PackageId, 3, + @PurchasedAt, @Amount, + NULL, @TxId, @PurchasedAt, NULL, @PurchasedAt, NULL, 0 + ); + SET @CreatedUpp = @CreatedUpp + 1; + END + + FETCH NEXT FROM curUpp INTO @UserId, @TxId, @PackageId, @Amount, @PurchasedAt; +END + +CLOSE curUpp; +DEALLOCATE curUpp; +DROP TABLE #ManualyUppPlan; + +PRINT CONCAT('UPP created: ', @CreatedUpp, ' | Skipped (no manualy Tx): ', @SkippedNoTx); + +------------------------------------------------------------ +-- 8) Missing WH for resolved manualy Tx (history-only, no wallet charge) +------------------------------------------------------------ +;WITH TxCandidates AS ( + SELECT mu.UserId, t.Id AS TxId, 1 AS Pri + FROM @ManualyUsers mu + INNER JOIN CMS.UserWallets w ON w.UserId = mu.UserId AND w.IsDeleted = 0 + 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.RefId LIKE N'manualy%' + + UNION ALL + + SELECT mu.UserId, t.Id, 2 + FROM @ManualyUsers mu + INNER JOIN CMS.Users u ON u.Id = mu.UserId AND u.IsDeleted = 0 + INNER JOIN CMS.Transactions t ON t.IsDeleted = 0 AND t.RefId LIKE N'manualy%' + AND u.Mobile IN ( + NULLIF(LTRIM(RTRIM(t.CreatedBy)), N''), + NULLIF(LTRIM(RTRIM(t.LastModifiedBy)), N'') + ) +), +BestTx AS ( + SELECT UserId, TxId, + ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY Pri, TxId DESC) AS rn + FROM TxCandidates +) +SELECT + bt.UserId, + bt.TxId, + w.Id AS WalletId, + COALESCE(t.Amount, @BasePackagePrice) AS Amount, + COALESCE(t.PaymentDate, @Now) AS HistoryAt, + COALESCE( + NULLIF(cm.LastPackageId, 0), + NULLIF(cm.FirstPackageId, 0), + @BasePackageId + ) AS PackageId, + CAST(ROUND(COALESCE(t.Amount, @BasePackagePrice) * COALESCE(p.DiscountMultiplier, 2.0), 0) AS BIGINT) AS DiscountAmount, + COALESCE(w.NetworkBalance, 0) AS NetworkBalance +INTO #WhToCreate +FROM BestTx bt +INNER JOIN CMS.Transactions t ON t.Id = bt.TxId AND t.IsDeleted = 0 +LEFT JOIN CMS.UserWallets w ON w.UserId = bt.UserId AND w.IsDeleted = 0 +LEFT JOIN CMS.ClubMemberships cm ON cm.UserId = bt.UserId AND cm.IsDeleted = 0 +LEFT JOIN CMS.Packages p ON p.Id = COALESCE( + NULLIF(cm.LastPackageId, 0), + NULLIF(cm.FirstPackageId, 0), + @BasePackageId +) AND p.IsDeleted = 0 +WHERE bt.rn = 1 + AND NOT EXISTS ( + SELECT 1 + FROM CMS.UserWalletHistories h + INNER JOIN CMS.UserWallets wh ON wh.Id = h.WalletId AND wh.IsDeleted = 0 + WHERE wh.UserId = bt.UserId + AND h.IsDeleted = 0 + AND h.RefrenceId = bt.TxId + ); + +DECLARE @WhPlanCount INT = (SELECT COUNT(*) FROM #WhToCreate); +PRINT CONCAT('WalletHistory to create (no charge): ', @WhPlanCount); + +SELECT UserId, TxId, WalletId, Amount, HistoryAt, N'CREATE_HISTORY_ONLY' AS PlanAction +FROM #WhToCreate +ORDER BY UserId; + +DECLARE @WalletId BIGINT; +DECLARE @DiscountAmount BIGINT; +DECLARE @HistoryAt DATETIME2; +DECLARE @NetworkBalance BIGINT; +DECLARE @CreatedWh INT = 0; + +DECLARE curWh CURSOR LOCAL FAST_FORWARD FOR + SELECT UserId, TxId, WalletId, Amount, PackageId, DiscountAmount, HistoryAt, NetworkBalance + FROM #WhToCreate; + +OPEN curWh; +FETCH NEXT FROM curWh INTO + @UserId, @TxId, @WalletId, @Amount, @PackageId, @DiscountAmount, @HistoryAt, @NetworkBalance; + +WHILE @@FETCH_STATUS = 0 +BEGIN + IF @WalletId IS NULL + BEGIN + INSERT INTO CMS.UserWallets + (UserId, Balance, NetworkBalance, DiscountBalance, WalletMode, Created, LastModified, IsDeleted) + VALUES (@UserId, 0, 0, 0, 0, @HistoryAt, @HistoryAt, 0); + SET @WalletId = SCOPE_IDENTITY(); + SET @NetworkBalance = 0; + END + + INSERT INTO CMS.UserWalletHistories + ( + WalletId, CurrentBalance, ChangeValue, CurrentNetworkBalance, ChangeNerworkValue, + CurrentDiscountBalance, ChangeDiscountValue, IsIncrease, RefrenceId, PackageId, + Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted + ) + VALUES + ( + @WalletId, 0, @Amount, @NetworkBalance, 0, + 0, @DiscountAmount, 1, @TxId, @PackageId, + @HistoryAt, NULL, @HistoryAt, NULL, 0 + ); + + SET @CreatedWh = @CreatedWh + 1; + + FETCH NEXT FROM curWh INTO + @UserId, @TxId, @WalletId, @Amount, @PackageId, @DiscountAmount, @HistoryAt, @NetworkBalance; +END + +CLOSE curWh; +DEALLOCATE curWh; +DROP TABLE #WhToCreate; + +PRINT CONCAT('WalletHistory created (no charge): ', @CreatedWh); + +------------------------------------------------------------ +-- Verify +------------------------------------------------------------ +SELECT 'Users still Daya in scope' AS CheckName, COUNT(*) AS Cnt +FROM CMS.Users u +INNER JOIN @ManualyUsers mu ON mu.UserId = u.Id +WHERE u.IsDeleted = 0 AND u.PackagePurchaseMethod = 1 +UNION ALL +SELECT 'Still missing UPP in scope', COUNT(*) +FROM @ManualyUsers mu +WHERE NOT EXISTS ( + SELECT 1 FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = mu.UserId AND upp.IsDeleted = 0 +) +UNION ALL +SELECT 'Broken WH Ref=0 with valid hint remaining', COUNT(*) +FROM CMS.UserWalletHistories h +INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 +INNER JOIN @ManualyUsers mu ON mu.UserId = w.UserId +WHERE h.IsDeleted = 0 + AND (h.RefrenceId IS NULL OR h.RefrenceId = 0) + AND TRY_CAST(h.CreatedBy AS BIGINT) > 0 + AND EXISTS ( + SELECT 1 FROM CMS.Transactions t + WHERE t.Id = TRY_CAST(h.CreatedBy AS BIGINT) + AND t.IsDeleted = 0 AND t.RefId LIKE N'manualy%' + ) +UNION ALL +SELECT 'Active stub Daya contracts in scope', COUNT(*) +FROM CMS.DayaLoanContracts d +INNER JOIN @ManualyUsers mu ON mu.UserId = d.UserId +WHERE d.IsDeleted = 0 + AND d.IsProcessed = 0 + AND d.TransactionId IS NULL + AND d.ProcessedDate IS NULL; + +SELECT u.Id AS UserId, u.Mobile, u.FirstName, u.LastName, + u.PackagePurchaseMethod, + (SELECT COUNT(*) FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = u.Id AND upp.IsDeleted = 0) AS UppCnt, + (SELECT COUNT(*) FROM CMS.UserWalletHistories h + INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId + WHERE w.UserId = u.Id AND h.IsDeleted = 0) AS WhCnt +FROM CMS.Users u +INNER JOIN @ManualyUsers mu ON mu.UserId = u.Id +WHERE u.IsDeleted = 0 +ORDER BY u.Id; + +ROLLBACK; +-- COMMIT; + +PRINT 'Done (rolled back by default).'; diff --git a/src/dbbkup/6a-Phase1_Create_UPP_Manualy_Linked_WH_Tx.sql b/src/dbbkup/6a-Phase1_Create_UPP_Manualy_Linked_WH_Tx.sql new file mode 100644 index 0000000..238e6c9 --- /dev/null +++ b/src/dbbkup/6a-Phase1_Create_UPP_Manualy_Linked_WH_Tx.sql @@ -0,0 +1,295 @@ +/* + PHASE 1 — Create UserPackagePurchases (Manual=3) only. + + Scope: 17 users with verified manualy charge — both WalletHistory AND Transaction exist + and WH.RefrenceId already points to the Tx. + + Hardcoded mapping (from UserWalletHistories.csv + Transactions.csv): + + UserId WH Tx + ------ ---- ---- + 75 102 23 + 93 103 24 + 96 104 25 + 99 105 26 + 47 106 28 + 43 107 29 + 45 108 30 + 52 122 31 + 116 138 42 + 115 139 43 + 119 140 44 + 113 141 45 + 103 142 46 + 170 292 107 + 171 293 108 + 172 294 109 + 175 295 110 + + Does NOT: + - change Users / Club / Cycle PurchaseMethod + - create or modify Transactions or WalletHistory + - re-charge wallet + + PackagePurchaseMethod on UPP: Manual = 3 + + Defaults to ROLLBACK. Uncomment COMMIT after reviewing preview + counts. +*/ + +SET NOCOUNT ON; +SET XACT_ABORT ON; + +BEGIN TRAN; + +DECLARE @Now DATETIME2 = SYSUTCDATETIME(); + +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; + +------------------------------------------------------------ +-- Expected mapping +------------------------------------------------------------ +DECLARE @Phase1 TABLE ( + UserId BIGINT NOT NULL, + WalletHistoryId BIGINT NOT NULL, + TransactionId BIGINT NOT NULL, + PRIMARY KEY (UserId) +); + +INSERT INTO @Phase1 (UserId, WalletHistoryId, TransactionId) VALUES +(75, 102, 23), +(93, 103, 24), +(96, 104, 25), +(99, 105, 26), +(47, 106, 28), +(43, 107, 29), +(45, 108, 30), +(52, 122, 31), +(116, 138, 42), +(115, 139, 43), +(119, 140, 44), +(113, 141, 45), +(103, 142, 46), +(170, 292, 107), +(171, 293, 108), +(172, 294, 109), +(175, 295, 110); + +DECLARE @Phase1Count INT = (SELECT COUNT(*) FROM @Phase1); +PRINT CONCAT('Phase1 expected rows: ', @Phase1Count); + +------------------------------------------------------------ +-- Validate live DB matches expected mapping +------------------------------------------------------------ +SELECT + p.UserId, + u.Mobile, + u.FirstName, + u.LastName, + p.WalletHistoryId AS ExpectedWhId, + p.TransactionId AS ExpectedTxId, + h.Id AS ActualWhId, + h.RefrenceId AS ActualWhRefrenceId, + h.ChangeValue AS WhChangeValue, + t.Id AS ActualTxId, + t.RefId AS TxRefId, + t.Amount AS TxAmount, + t.PaymentStatus, + w.UserId AS WhWalletUserId, + CASE + WHEN u.Id IS NULL THEN N'USER_MISSING' + WHEN h.Id IS NULL THEN N'WH_MISSING' + WHEN t.Id IS NULL THEN N'TX_MISSING' + WHEN h.RefrenceId <> p.TransactionId THEN N'WH_REF_MISMATCH' + WHEN w.UserId <> p.UserId THEN N'WH_WALLET_USER_MISMATCH' + WHEN t.RefId NOT LIKE N'manualy%' THEN N'TX_NOT_MANUALY' + WHEN t.PaymentStatus <> 0 THEN N'TX_NOT_SUCCESS' + ELSE N'OK' + END AS ValidationStatus +FROM @Phase1 p +LEFT JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0 +LEFT JOIN CMS.UserWalletHistories h ON h.Id = p.WalletHistoryId AND h.IsDeleted = 0 +LEFT JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 +LEFT JOIN CMS.Transactions t ON t.Id = p.TransactionId AND t.IsDeleted = 0 +ORDER BY p.UserId; + +DECLARE @BadValidation INT = ( + SELECT COUNT(*) + FROM @Phase1 p + LEFT JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0 + LEFT JOIN CMS.UserWalletHistories h ON h.Id = p.WalletHistoryId AND h.IsDeleted = 0 + LEFT JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 + LEFT JOIN CMS.Transactions t ON t.Id = p.TransactionId AND t.IsDeleted = 0 + WHERE u.Id IS NULL + OR h.Id IS NULL + OR t.Id IS NULL + OR h.RefrenceId <> p.TransactionId + OR w.UserId <> p.UserId + OR t.RefId NOT LIKE N'manualy%' + OR t.PaymentStatus <> 0 +); + +IF @BadValidation > 0 +BEGIN + DECLARE @BadMsg NVARCHAR(200); + SET @BadMsg = CONCAT( + N'Validation failed for ', @BadValidation, + N' row(s). Fix before creating UPP.' + ); + ROLLBACK; + RAISERROR(@BadMsg, 16, 1); + RETURN; +END + +PRINT 'Validation OK for all 17 rows.'; + +------------------------------------------------------------ +-- Preview: who already has UPP / UPP on this Tx +------------------------------------------------------------ +SELECT + p.UserId, + u.Mobile, + p.TransactionId, + CASE WHEN upp_any.Id IS NOT NULL THEN N'YES' ELSE N'NO' END AS HasAnyUpp, + upp_any.Id AS ExistingUppId, + upp_any.PurchaseMethod AS ExistingUppMethod, + upp_any.TransactionId AS ExistingUppTxId, + CASE + WHEN upp_tx.Id IS NOT NULL THEN N'SKIP_UPP_EXISTS_FOR_TX' + WHEN upp_any.Id IS NOT NULL THEN N'SKIP_USER_HAS_OTHER_UPP' + ELSE N'CREATE_UPP' + END AS PlanAction +FROM @Phase1 p +INNER JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0 +OUTER APPLY ( + SELECT TOP (1) upp.Id, upp.PurchaseMethod, upp.TransactionId + FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = p.UserId AND upp.IsDeleted = 0 + ORDER BY upp.Id DESC +) upp_any +OUTER APPLY ( + SELECT TOP (1) upp.Id + FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = p.UserId + AND upp.IsDeleted = 0 + AND upp.TransactionId = p.TransactionId + ORDER BY upp.Id DESC +) upp_tx +ORDER BY p.UserId; + +------------------------------------------------------------ +-- Build UPP insert plan +------------------------------------------------------------ +SELECT + p.UserId, + p.TransactionId, + COALESCE( + NULLIF(cm.LastPackageId, 0), + NULLIF(cm.FirstPackageId, 0), + @BasePackageId + ) AS PackageId, + COALESCE(t.Amount, @BasePackagePrice) AS Amount, + COALESCE(t.PaymentDate, cm.ActivatedAt, @Now) AS PurchasedAt +INTO #UppPlan +FROM @Phase1 p +INNER JOIN CMS.Transactions t ON t.Id = p.TransactionId AND t.IsDeleted = 0 +LEFT JOIN CMS.ClubMemberships cm ON cm.UserId = p.UserId AND cm.IsDeleted = 0 +WHERE NOT EXISTS ( + SELECT 1 + FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = p.UserId + AND upp.IsDeleted = 0 + AND upp.TransactionId = p.TransactionId +); + +DECLARE @ToCreate INT = (SELECT COUNT(*) FROM #UppPlan); +DECLARE @Skipped INT = (SELECT COUNT(*) FROM @Phase1) - @ToCreate; + +PRINT CONCAT('UPP to create: ', @ToCreate, ' | Already linked (skip): ', @Skipped); + +SELECT + pl.UserId, + u.Mobile, + u.FirstName, + u.LastName, + pl.TransactionId, + pl.PackageId, + pl.Amount, + pl.PurchasedAt, + N'INSERT_UPP_MANUAL_3' AS Action +FROM #UppPlan pl +INNER JOIN CMS.Users u ON u.Id = pl.UserId AND u.IsDeleted = 0 +ORDER BY pl.UserId; + +------------------------------------------------------------ +-- Insert UPP +------------------------------------------------------------ +INSERT INTO CMS.UserPackagePurchases +( + UserId, PackageId, PurchaseMethod, PurchasedAt, Amount, + OrderId, TransactionId, Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted +) +SELECT + pl.UserId, + pl.PackageId, + 3, -- Manual + pl.PurchasedAt, + pl.Amount, + NULL, + pl.TransactionId, + @Now, + NULL, + @Now, + NULL, + 0 +FROM #UppPlan pl +WHERE pl.PackageId IS NOT NULL + AND pl.Amount > 0; + +PRINT CONCAT('UPP inserted: ', @@ROWCOUNT); + +DROP TABLE #UppPlan; + +------------------------------------------------------------ +-- Verify +------------------------------------------------------------ +SELECT + p.UserId, + u.Mobile, + p.TransactionId, + CASE WHEN upp.Id IS NOT NULL THEN N'OK' ELSE N'MISSING_UPP' END AS UppStatus, + upp.Id AS UppId, + upp.PurchaseMethod, + upp.TransactionId AS UppTxId +FROM @Phase1 p +INNER JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0 +LEFT JOIN CMS.UserPackagePurchases upp + ON upp.UserId = p.UserId + AND upp.IsDeleted = 0 + AND upp.TransactionId = p.TransactionId +ORDER BY p.UserId; + +SELECT N'Missing UPP after run' AS CheckName, COUNT(*) AS Cnt +FROM @Phase1 p +WHERE NOT EXISTS ( + SELECT 1 + FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = p.UserId + AND upp.IsDeleted = 0 + AND upp.TransactionId = p.TransactionId +); + +ROLLBACK; +-- COMMIT; + +PRINT 'Done (rolled back by default). Uncomment COMMIT when preview looks correct.'; diff --git a/src/dbbkup/6b-Phase2_Fix_WH_Link_And_Create_UPP_Tx_56-68.sql b/src/dbbkup/6b-Phase2_Fix_WH_Link_And_Create_UPP_Tx_56-68.sql new file mode 100644 index 0000000..cae4bec --- /dev/null +++ b/src/dbbkup/6b-Phase2_Fix_WH_Link_And_Create_UPP_Tx_56-68.sql @@ -0,0 +1,368 @@ +/* + PHASE 2 — Fix broken WH.RefrenceId + create UPP for 5 remaining manualy txs. + + Tx exists; WH either RefrenceId=0 (CreatedBy = Tx Id hint) or missing (Tx 68). + + Hardcoded mapping (UserWalletHistories2.csv + Transactions.csv): + + UserId WH Tx Notes + ------ ----- --- ----- + 71 118 56 WH Ref=0, CreatedBy=56 + 72 124 57 WH Ref=0, CreatedBy=57 + 69 119 58 WH Ref=0, CreatedBy=58 + 74 120 59 WH Ref=0, CreatedBy=59 + 142 — 68 no WH — insert history-only (no wallet charge) + + Steps: + 1) Validate WH hint + Tx manualy% + user/wallet + 2) UPDATE WH.RefrenceId for rows 118,124,119,120 + 3) INSERT UserWalletHistory for User 142 / Tx 68 if missing + 4) INSERT UserPackagePurchases Manual(3) for all 5 txs + + Does NOT change Users.PackagePurchaseMethod or wallet Balance. + + Defaults to ROLLBACK. Uncomment COMMIT after preview. +*/ + +SET NOCOUNT ON; +SET XACT_ABORT ON; + +BEGIN TRAN; + +DECLARE @Now DATETIME2 = SYSUTCDATETIME(); + +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 @Phase2 TABLE ( + UserId BIGINT NOT NULL, + WalletHistoryId BIGINT NULL, + TransactionId BIGINT NOT NULL, + PRIMARY KEY (TransactionId) +); + +INSERT INTO @Phase2 (UserId, WalletHistoryId, TransactionId) VALUES +(71, 118, 56), +(72, 124, 57), +(69, 119, 58), +(74, 120, 59), +(142, NULL, 68); + +DECLARE @Phase2Count INT = (SELECT COUNT(*) FROM @Phase2); +PRINT CONCAT('Phase2 expected rows: ', @Phase2Count); + +------------------------------------------------------------ +-- 1) Validate before changes +------------------------------------------------------------ +SELECT + p.UserId, + u.Mobile AS UserMobile, + u.FirstName, + u.LastName, + p.WalletHistoryId AS ExpectedWhId, + p.TransactionId AS ExpectedTxId, + h.Id AS ActualWhId, + h.RefrenceId AS WhRefrenceId, + h.CreatedBy AS WhCreatedBy, + h.ChangeValue AS WhChangeValue, + w.UserId AS WhWalletUserId, + t.Id AS ActualTxId, + t.RefId AS TxRefId, + t.Amount AS TxAmount, + t.CreatedBy AS TxCreatedBy, + t.LastModifiedBy AS TxLastModifiedBy, + CASE + WHEN u.Id IS NULL THEN N'USER_MISSING' + WHEN t.Id IS NULL THEN N'TX_MISSING' + WHEN t.RefId NOT LIKE N'manualy%' THEN N'TX_NOT_MANUALY' + WHEN t.PaymentStatus <> 0 THEN N'TX_NOT_SUCCESS' + WHEN p.WalletHistoryId IS NULL THEN N'NO_WH_EXPECTED_CREATE' + WHEN h.Id IS NULL THEN N'WH_MISSING' + WHEN w.UserId <> p.UserId THEN N'WH_WALLET_USER_MISMATCH' + WHEN TRY_CAST(h.CreatedBy AS BIGINT) <> p.TransactionId THEN N'WH_CREATEDBY_HINT_MISMATCH' + WHEN h.RefrenceId = p.TransactionId THEN N'WH_ALREADY_LINKED' + WHEN h.RefrenceId IS NOT NULL AND h.RefrenceId <> 0 AND h.RefrenceId <> p.TransactionId + THEN N'WH_REF_POINTS_OTHER_TX' + ELSE N'OK_FIX_REF' + END AS WhValidation, + CASE + WHEN u.Mobile IN ( + NULLIF(LTRIM(RTRIM(t.CreatedBy)), N''), + NULLIF(LTRIM(RTRIM(t.LastModifiedBy)), N'') + ) THEN N'MOBILE_OK' + WHEN NULLIF(LTRIM(RTRIM(t.CreatedBy)), N'') LIKE N'09%' THEN N'TX_MOBILE_USER_MISMATCH' + ELSE N'TX_NO_MOBILE_ON_ROW' + END AS MobileCheck +FROM @Phase2 p +LEFT JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0 +LEFT JOIN CMS.Transactions t ON t.Id = p.TransactionId AND t.IsDeleted = 0 +LEFT JOIN CMS.UserWalletHistories h ON h.Id = p.WalletHistoryId AND h.IsDeleted = 0 +LEFT JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 +ORDER BY p.TransactionId; + +DECLARE @BadWh INT = ( + SELECT COUNT(*) + FROM @Phase2 p + LEFT JOIN CMS.UserWalletHistories h ON h.Id = p.WalletHistoryId AND h.IsDeleted = 0 + LEFT JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 + LEFT JOIN CMS.Transactions t ON t.Id = p.TransactionId AND t.IsDeleted = 0 + LEFT JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0 + WHERE t.Id IS NULL + OR u.Id IS NULL + OR t.RefId NOT LIKE N'manualy%' + OR t.PaymentStatus <> 0 + OR ( + p.WalletHistoryId IS NOT NULL + AND ( + h.Id IS NULL + OR w.UserId <> p.UserId + OR TRY_CAST(h.CreatedBy AS BIGINT) <> p.TransactionId + OR (h.RefrenceId IS NOT NULL AND h.RefrenceId <> 0 AND h.RefrenceId <> p.TransactionId) + ) + ) +); + +IF @BadWh > 0 +BEGIN + DECLARE @BadMsg NVARCHAR(200); + SET @BadMsg = CONCAT(N'Validation failed for ', @BadWh, N' row(s). Aborting.'); + ROLLBACK; + RAISERROR(@BadMsg, 16, 1); + RETURN; +END + +PRINT 'Validation OK.'; + +------------------------------------------------------------ +-- 2) Fix WH.RefrenceId (118,124,119,120) +------------------------------------------------------------ +SELECT + p.UserId, + p.WalletHistoryId, + p.TransactionId, + h.RefrenceId AS OldRefrenceId, + N'UPDATE RefrenceId' AS Action +FROM @Phase2 p +INNER JOIN CMS.UserWalletHistories h ON h.Id = p.WalletHistoryId AND h.IsDeleted = 0 +WHERE p.WalletHistoryId IS NOT NULL + AND (h.RefrenceId IS NULL OR h.RefrenceId = 0 OR h.RefrenceId <> p.TransactionId); + +UPDATE h +SET + h.RefrenceId = p.TransactionId, + h.LastModified = @Now +FROM @Phase2 p +INNER JOIN CMS.UserWalletHistories h ON h.Id = p.WalletHistoryId AND h.IsDeleted = 0 +WHERE p.WalletHistoryId IS NOT NULL + AND (h.RefrenceId IS NULL OR h.RefrenceId = 0); + +PRINT CONCAT('WalletHistory RefrenceId updated: ', @@ROWCOUNT); + +------------------------------------------------------------ +-- 3) User 142 / Tx 68 — history-only WH if missing +------------------------------------------------------------ +SELECT + p.UserId, + p.TransactionId, + w.Id AS WalletId, + h.Id AS ExistingWhId, + CASE WHEN h.Id IS NOT NULL THEN N'SKIP_WH_EXISTS' ELSE N'CREATE_WH_HISTORY' END AS WhPlan +FROM @Phase2 p +LEFT JOIN CMS.UserWallets w ON w.UserId = p.UserId AND w.IsDeleted = 0 +LEFT JOIN CMS.UserWalletHistories h ON h.IsDeleted = 0 AND h.RefrenceId = p.TransactionId + AND h.WalletId = w.Id +WHERE p.WalletHistoryId IS NULL; + +DECLARE @UserId BIGINT = 142; +DECLARE @TxId BIGINT = 68; +DECLARE @WalletId BIGINT; +DECLARE @PackageId BIGINT; +DECLARE @Amount BIGINT; +DECLARE @HistoryAt DATETIME2; +DECLARE @DiscountAmount BIGINT; +DECLARE @NetworkBalance BIGINT; + +IF EXISTS (SELECT 1 FROM @Phase2 WHERE TransactionId = 68 AND WalletHistoryId IS NULL) +BEGIN + SELECT + @WalletId = w.Id, + @PackageId = COALESCE( + NULLIF(cm.LastPackageId, 0), + NULLIF(cm.FirstPackageId, 0), + @BasePackageId + ), + @Amount = t.Amount, + @HistoryAt = COALESCE(t.PaymentDate, @Now), + @NetworkBalance = COALESCE(w.NetworkBalance, 0), + @DiscountAmount = CAST(ROUND(t.Amount * COALESCE(pkg.DiscountMultiplier, 2.0), 0) AS BIGINT) + FROM CMS.Transactions t + INNER JOIN CMS.Users u ON u.Id = 142 AND u.IsDeleted = 0 + LEFT JOIN CMS.UserWallets w ON w.UserId = u.Id AND w.IsDeleted = 0 + LEFT JOIN CMS.ClubMemberships cm ON cm.UserId = u.Id AND cm.IsDeleted = 0 + LEFT JOIN CMS.Packages pkg ON pkg.Id = COALESCE( + NULLIF(cm.LastPackageId, 0), + NULLIF(cm.FirstPackageId, 0), + @BasePackageId + ) AND pkg.IsDeleted = 0 + WHERE t.Id = 68 AND t.IsDeleted = 0; + + IF @WalletId IS NULL + BEGIN + INSERT INTO CMS.UserWallets + (UserId, Balance, NetworkBalance, DiscountBalance, WalletMode, Created, LastModified, IsDeleted) + VALUES (142, 0, 0, 0, 0, @HistoryAt, @HistoryAt, 0); + SET @WalletId = SCOPE_IDENTITY(); + SET @NetworkBalance = 0; + PRINT CONCAT('Wallet created for User 142: ', @WalletId); + END + + IF NOT EXISTS ( + SELECT 1 + FROM CMS.UserWalletHistories h + WHERE h.WalletId = @WalletId + AND h.IsDeleted = 0 + AND h.RefrenceId = 68 + ) + BEGIN + INSERT INTO CMS.UserWalletHistories + ( + WalletId, CurrentBalance, ChangeValue, CurrentNetworkBalance, ChangeNerworkValue, + CurrentDiscountBalance, ChangeDiscountValue, IsIncrease, RefrenceId, PackageId, + Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted + ) + VALUES + ( + @WalletId, 0, @Amount, @NetworkBalance, 0, + 0, @DiscountAmount, 1, 68, @PackageId, + @HistoryAt, NULL, @HistoryAt, NULL, 0 + ); + PRINT CONCAT('WalletHistory created for Tx 68 (no charge): WH Id=', SCOPE_IDENTITY()); + END + ELSE + PRINT 'WalletHistory for Tx 68 already exists — skipped.'; +END + +------------------------------------------------------------ +-- 4) UPP preview + insert +------------------------------------------------------------ +SELECT + p.UserId, + u.Mobile, + p.TransactionId, + CASE WHEN upp.Id IS NOT NULL THEN N'SKIP_UPP_EXISTS' ELSE N'CREATE_UPP' END AS UppPlan, + upp.Id AS ExistingUppId +FROM @Phase2 p +INNER JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0 +LEFT JOIN CMS.UserPackagePurchases upp + ON upp.UserId = p.UserId + AND upp.IsDeleted = 0 + AND upp.TransactionId = p.TransactionId +ORDER BY p.TransactionId; + +SELECT + p.UserId, + p.TransactionId, + COALESCE( + NULLIF(cm.LastPackageId, 0), + NULLIF(cm.FirstPackageId, 0), + @BasePackageId + ) AS PackageId, + COALESCE(t.Amount, @BasePackagePrice) AS Amount, + COALESCE(t.PaymentDate, cm.ActivatedAt, @Now) AS PurchasedAt +INTO #UppPlan +FROM @Phase2 p +INNER JOIN CMS.Transactions t ON t.Id = p.TransactionId AND t.IsDeleted = 0 +LEFT JOIN CMS.ClubMemberships cm ON cm.UserId = p.UserId AND cm.IsDeleted = 0 +WHERE NOT EXISTS ( + SELECT 1 + FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = p.UserId + AND upp.IsDeleted = 0 + AND upp.TransactionId = p.TransactionId +); + +DECLARE @UppToCreate INT = (SELECT COUNT(*) FROM #UppPlan); +PRINT CONCAT('UPP to create: ', @UppToCreate); + +INSERT INTO CMS.UserPackagePurchases +( + UserId, PackageId, PurchaseMethod, PurchasedAt, Amount, + OrderId, TransactionId, Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted +) +SELECT + pl.UserId, + pl.PackageId, + 3, + pl.PurchasedAt, + pl.Amount, + NULL, + pl.TransactionId, + @Now, + NULL, + @Now, + NULL, + 0 +FROM #UppPlan pl +WHERE pl.PackageId IS NOT NULL AND pl.Amount > 0; + +PRINT CONCAT('UPP inserted: ', @@ROWCOUNT); +DROP TABLE #UppPlan; + +------------------------------------------------------------ +-- 5) Verify +------------------------------------------------------------ +SELECT + p.UserId, + u.Mobile, + p.TransactionId, + h.Id AS WalletHistoryId, + h.RefrenceId AS WhRefrenceId, + upp.Id AS UppId, + upp.PurchaseMethod, + CASE + WHEN h.Id IS NULL AND p.WalletHistoryId IS NOT NULL THEN N'MISSING_WH' + WHEN h.RefrenceId <> p.TransactionId AND p.WalletHistoryId IS NOT NULL THEN N'WH_REF_WRONG' + WHEN NOT EXISTS ( + SELECT 1 FROM CMS.UserWalletHistories hx + INNER JOIN CMS.UserWallets wx ON wx.Id = hx.WalletId AND wx.UserId = p.UserId + WHERE hx.IsDeleted = 0 AND hx.RefrenceId = p.TransactionId + ) THEN N'NO_WH_FOR_TX' + WHEN upp.Id IS NULL THEN N'MISSING_UPP' + ELSE N'OK' + END AS FinalStatus +FROM @Phase2 p +INNER JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0 +LEFT JOIN CMS.UserWalletHistories h ON h.Id = p.WalletHistoryId AND h.IsDeleted = 0 +LEFT JOIN CMS.UserPackagePurchases upp + ON upp.UserId = p.UserId + AND upp.IsDeleted = 0 + AND upp.TransactionId = p.TransactionId +ORDER BY p.TransactionId; + +SELECT N'Incomplete after run' AS CheckName, COUNT(*) AS Cnt +FROM @Phase2 p +WHERE NOT EXISTS ( + SELECT 1 FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = p.UserId AND upp.IsDeleted = 0 AND upp.TransactionId = p.TransactionId +) +OR NOT EXISTS ( + SELECT 1 + FROM CMS.UserWalletHistories h + INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.UserId = p.UserId + WHERE h.IsDeleted = 0 AND h.RefrenceId = p.TransactionId +); + +ROLLBACK; +-- COMMIT; + +PRINT 'Done (rolled back by default). Uncomment COMMIT when preview looks correct.'; diff --git a/src/dbbkup/6c-Phase3_Create_UPP_Remaining_16_Users.sql b/src/dbbkup/6c-Phase3_Create_UPP_Remaining_16_Users.sql new file mode 100644 index 0000000..f8ed1d0 --- /dev/null +++ b/src/dbbkup/6c-Phase3_Create_UPP_Remaining_16_Users.sql @@ -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.'; diff --git a/src/dbbkup/7-Fix_WrongDirectPurchase_ToManual_FromManualPayment.sql b/src/dbbkup/7-Fix_WrongDirectPurchase_ToManual_FromManualPayment.sql new file mode 100644 index 0000000..fa9647a --- /dev/null +++ b/src/dbbkup/7-Fix_WrongDirectPurchase_ToManual_FromManualPayment.sql @@ -0,0 +1,740 @@ +/* + Fix: Manual payment wrongly stored as DirectPurchase (2) → Manual (3) + + create missing Tx/UPP/UserWalletHistory (same ledger as CreateManualPayment service) + + Background: + Before commit 427d2cc, CreateManualPayment set Users.PackagePurchaseMethod = DirectPurchase + and older rows may lack UserPackagePurchases / wallet history entirely. + + Scope — ALL users present in CMS.ManualPayments (IsDeleted = 0): + 1) Users / UPP / Club / Cycle: PurchaseMethod 2 → 3 + 2) Users with NO UPP (~18): create Success Tx + UPP Manual(3) + 3) After that, for EVERY user missing UserWalletHistory on their Tx (~6 existing + ~18 new): + - INSERT history only (Created=PaymentDate, ChangeValue=Amount) + - DO NOT re-charge wallet + - Prefer existing MP/UPP TransactionId (the ~6 already have Tx) + + PackagePurchaseMethod: None=0, DayaLoan=1, DirectPurchase=2, Manual=3 + ManualPaymentStatus: Pending=0, Approved=1, Rejected=2 + + Defaults to ROLLBACK. Uncomment COMMIT after verifying PRINT / preview. +*/ + +SET NOCOUNT ON; +SET XACT_ABORT ON; + +BEGIN TRAN; + +DECLARE @Now DATETIME2 = SYSUTCDATETIME(); + +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; + +------------------------------------------------------------ +-- Target: every user that appears in ManualPayments +------------------------------------------------------------ +DECLARE @FixUsers TABLE (UserId BIGINT PRIMARY KEY); + +INSERT INTO @FixUsers (UserId) +SELECT DISTINCT mp.UserId +FROM CMS.ManualPayments mp +WHERE mp.IsDeleted = 0; + +DECLARE @TargetUserCount INT = (SELECT COUNT(*) FROM @FixUsers); +PRINT CONCAT('Target users (all ManualPayments): ', @TargetUserCount); +PRINT CONCAT('BasePackageId=', @BasePackageId, ' Price=', @BasePackagePrice); + +------------------------------------------------------------ +-- Preview before +-- NOTE: UPP row-count ≠ distinct users (one user can have 2+ UPP rows) +------------------------------------------------------------ +SELECT 'Users DirectPurchase (in scope)' AS CheckName, COUNT(*) AS Cnt +FROM CMS.Users u +INNER JOIN @FixUsers f ON f.UserId = u.Id +WHERE u.IsDeleted = 0 AND u.PackagePurchaseMethod = 2 +UNION ALL +SELECT 'UPP DirectPurchase ROWS (in scope)', COUNT(*) +FROM CMS.UserPackagePurchases upp +INNER JOIN @FixUsers f ON f.UserId = upp.UserId +WHERE upp.IsDeleted = 0 AND upp.PurchaseMethod = 2 +UNION ALL +SELECT 'Users with UPP DirectPurchase (distinct)', COUNT(DISTINCT upp.UserId) +FROM CMS.UserPackagePurchases upp +INNER JOIN @FixUsers f ON f.UserId = upp.UserId +WHERE upp.IsDeleted = 0 AND upp.PurchaseMethod = 2 +UNION ALL +SELECT 'ClubMembership DirectPurchase (in scope)', COUNT(*) +FROM CMS.ClubMemberships m +INNER JOIN @FixUsers f ON f.UserId = m.UserId +WHERE m.IsDeleted = 0 AND m.PurchaseMethod = 2 +UNION ALL +SELECT 'Cycle DirectPurchase (in scope)', COUNT(*) +FROM CMS.ClubMembershipCycles c +INNER JOIN @FixUsers f ON f.UserId = c.UserId +WHERE c.IsDeleted = 0 AND c.PurchaseMethod = 2 +UNION ALL +SELECT 'Users with any UPP (distinct)', COUNT(*) +FROM @FixUsers f +WHERE EXISTS ( + SELECT 1 FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = f.UserId AND upp.IsDeleted = 0 +) +UNION ALL +SELECT 'Missing any UPP (will create Tx+UPP, then WH)', COUNT(*) +FROM @FixUsers f +WHERE NOT EXISTS ( + SELECT 1 FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = f.UserId AND upp.IsDeleted = 0 +) +UNION ALL +SELECT 'Missing WH — have Tx already (create history only)', COUNT(*) +FROM @FixUsers f +OUTER APPLY ( + SELECT TOP (1) + mp.Id AS ManualPaymentId, + mp.TransactionId AS MpTxId, + mp.ReferenceNumber + FROM CMS.ManualPayments mp + WHERE mp.UserId = f.UserId AND mp.IsDeleted = 0 + ORDER BY + CASE WHEN mp.Status = 1 THEN 0 ELSE 1 END, + CASE WHEN mp.TransactionId IS NOT NULL THEN 0 ELSE 1 END, + COALESCE(mp.ApprovedAt, mp.Created) DESC, + mp.Id DESC +) mp +OUTER APPLY ( + SELECT TOP (1) upp.TransactionId AS UppTxId + FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = f.UserId AND upp.IsDeleted = 0 AND upp.TransactionId IS NOT NULL + ORDER BY upp.Id DESC +) upp +CROSS APPLY ( + SELECT COALESCE( + CASE + WHEN mp.MpTxId IS NOT NULL + AND EXISTS ( + SELECT 1 FROM CMS.Transactions t + WHERE t.Id = mp.MpTxId AND t.IsDeleted = 0 AND t.PaymentStatus = 0 + ) + THEN mp.MpTxId + END, + upp.UppTxId, + ( + SELECT TOP (1) t.Id + FROM CMS.Transactions t + WHERE t.IsDeleted = 0 AND t.PaymentStatus = 0 + AND mp.ReferenceNumber IS NOT NULL + AND t.RefId = mp.ReferenceNumber + ORDER BY t.Id DESC + ) + ) AS TxId +) tx +WHERE tx.TxId IS NOT NULL + AND NOT EXISTS ( + SELECT 1 + FROM CMS.UserWalletHistories h + INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 + WHERE w.UserId = f.UserId + AND h.IsDeleted = 0 + AND h.RefrenceId = tx.TxId + ); + +-- Diagnostic: users who already have UPP (expect ~6) — Tx link vs history +SELECT + f.UserId, + mp.ManualPaymentId, + mp.MpTxId, + upp.UppTxId, + tx.TxId AS ResolvedTxId, + CASE + WHEN tx.TxId IS NULL THEN N'NO_TX_RESOLVED' + WHEN h.Id IS NULL THEN N'MISSING_HISTORY' + ELSE N'HAS_HISTORY' + END AS HistoryStatus, + h.Id AS WalletHistoryId +FROM @FixUsers f +OUTER APPLY ( + SELECT TOP (1) + mp0.Id AS ManualPaymentId, + mp0.TransactionId AS MpTxId, + mp0.ReferenceNumber + FROM CMS.ManualPayments mp0 + WHERE mp0.UserId = f.UserId AND mp0.IsDeleted = 0 + ORDER BY + CASE WHEN mp0.Status = 1 THEN 0 ELSE 1 END, + CASE WHEN mp0.TransactionId IS NOT NULL THEN 0 ELSE 1 END, + COALESCE(mp0.ApprovedAt, mp0.Created) DESC, + mp0.Id DESC +) mp +OUTER APPLY ( + SELECT TOP (1) upp0.TransactionId AS UppTxId + FROM CMS.UserPackagePurchases upp0 + WHERE upp0.UserId = f.UserId AND upp0.IsDeleted = 0 AND upp0.TransactionId IS NOT NULL + ORDER BY upp0.Id DESC +) upp +CROSS APPLY ( + SELECT COALESCE( + CASE + WHEN mp.MpTxId IS NOT NULL + AND EXISTS ( + SELECT 1 FROM CMS.Transactions t + WHERE t.Id = mp.MpTxId AND t.IsDeleted = 0 AND t.PaymentStatus = 0 + ) + THEN mp.MpTxId + END, + upp.UppTxId, + ( + SELECT TOP (1) t.Id + FROM CMS.Transactions t + WHERE t.IsDeleted = 0 AND t.PaymentStatus = 0 + AND mp.ReferenceNumber IS NOT NULL + AND t.RefId = mp.ReferenceNumber + ORDER BY t.Id DESC + ) + ) AS TxId +) tx +OUTER APPLY ( + SELECT TOP (1) h0.Id + FROM CMS.UserWalletHistories h0 + INNER JOIN CMS.UserWallets w0 ON w0.Id = h0.WalletId AND w0.IsDeleted = 0 + WHERE w0.UserId = f.UserId AND h0.IsDeleted = 0 AND h0.RefrenceId = tx.TxId +) h +WHERE EXISTS ( + SELECT 1 FROM CMS.UserPackagePurchases uany + WHERE uany.UserId = f.UserId AND uany.IsDeleted = 0 +) +ORDER BY f.UserId; + +-- Who has more than one UPP row? (explains ROWS vs users) +SELECT + upp.UserId, + COUNT(*) AS UppRowCnt, + SUM(CASE WHEN upp.PurchaseMethod = 2 THEN 1 ELSE 0 END) AS UppDirectPurchaseCnt, + SUM(CASE WHEN upp.PurchaseMethod = 3 THEN 1 ELSE 0 END) AS UppManualCnt +FROM CMS.UserPackagePurchases upp +INNER JOIN @FixUsers f ON f.UserId = upp.UserId +WHERE upp.IsDeleted = 0 +GROUP BY upp.UserId +HAVING COUNT(*) > 1 +ORDER BY UppRowCnt DESC, upp.UserId; + +------------------------------------------------------------ +-- 1) Users 2 → 3 +------------------------------------------------------------ +UPDATE u +SET + u.PackagePurchaseMethod = 3, + u.LastModified = @Now +FROM CMS.Users u +INNER JOIN @FixUsers f ON f.UserId = u.Id +WHERE u.IsDeleted = 0 + AND u.PackagePurchaseMethod = 2; + +PRINT CONCAT('Users updated 2→3: ', @@ROWCOUNT); + +------------------------------------------------------------ +-- 2) Existing UPP 2 → 3 +------------------------------------------------------------ +UPDATE upp +SET + upp.PurchaseMethod = 3, + upp.LastModified = @Now +FROM CMS.UserPackagePurchases upp +INNER JOIN @FixUsers f ON f.UserId = upp.UserId +WHERE upp.IsDeleted = 0 + AND upp.PurchaseMethod = 2; + +PRINT CONCAT('UserPackagePurchases updated 2→3: ', @@ROWCOUNT); + +------------------------------------------------------------ +-- 3) ClubMemberships 2 → 3 +------------------------------------------------------------ +UPDATE m +SET + m.PurchaseMethod = 3, + m.LastModified = @Now +FROM CMS.ClubMemberships m +INNER JOIN @FixUsers f ON f.UserId = m.UserId +WHERE m.IsDeleted = 0 + AND m.PurchaseMethod = 2; + +PRINT CONCAT('ClubMemberships updated 2→3: ', @@ROWCOUNT); + +------------------------------------------------------------ +-- 4) ClubMembershipCycles 2 → 3 +------------------------------------------------------------ +UPDATE c +SET + c.PurchaseMethod = 3, + c.LastModified = @Now +FROM CMS.ClubMembershipCycles c +INNER JOIN @FixUsers f ON f.UserId = c.UserId +WHERE c.IsDeleted = 0 + AND c.PurchaseMethod = 2; + +PRINT CONCAT('ClubMembershipCycles updated 2→3: ', @@ROWCOUNT); + +------------------------------------------------------------ +-- 5) Create missing Tx + UPP (like CreateManualPayment ledger) +------------------------------------------------------------ +;WITH MissingUppUsers AS ( + -- Any non-deleted UPP counts as present (avoid duplicate for method=2 / broken Tx) + SELECT f.UserId + FROM @FixUsers f + WHERE NOT EXISTS ( + SELECT 1 + FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = f.UserId + AND upp.IsDeleted = 0 + ) +), +BestManual AS ( + SELECT + mp.UserId, + mp.Id AS ManualPaymentId, + mp.Amount, + mp.TransactionId, + mp.ReferenceNumber, + mp.Description, + COALESCE(mp.ApprovedAt, mp.Created) AS PurchasedAt, + ROW_NUMBER() OVER ( + PARTITION BY mp.UserId + ORDER BY + CASE WHEN mp.Status = 1 THEN 0 ELSE 1 END, -- Approved first + CASE WHEN mp.TransactionId IS NOT NULL THEN 0 ELSE 1 END, + COALESCE(mp.ApprovedAt, mp.Created) DESC, + mp.Id DESC + ) AS rn + FROM CMS.ManualPayments mp + INNER JOIN MissingUppUsers m ON m.UserId = mp.UserId + WHERE mp.IsDeleted = 0 +), +Candidates AS ( + SELECT + bm.UserId, + bm.ManualPaymentId, + bm.TransactionId AS ExistingTxId, + bm.ReferenceNumber, + bm.Description, + bm.PurchasedAt, + COALESCE(NULLIF(cm.LastPackageId, 0), NULLIF(cm.FirstPackageId, 0), @BasePackageId) AS PackageId, + CASE + WHEN bm.Amount IS NOT NULL AND bm.Amount > 0 THEN bm.Amount + ELSE COALESCE(p.Price, @BasePackagePrice) + END AS Amount + FROM BestManual bm + LEFT JOIN CMS.ClubMemberships cm + ON cm.UserId = bm.UserId AND cm.IsDeleted = 0 + LEFT JOIN CMS.Packages p + ON p.Id = COALESCE(NULLIF(cm.LastPackageId, 0), NULLIF(cm.FirstPackageId, 0), @BasePackageId) + AND p.IsDeleted = 0 + WHERE bm.rn = 1 +) +SELECT * +INTO #UppToCreate +FROM Candidates +WHERE PackageId IS NOT NULL AND Amount > 0; + +DECLARE @MissingUppCount INT = (SELECT COUNT(*) FROM #UppToCreate); +PRINT CONCAT('Missing UPP candidates to create: ', @MissingUppCount); + +SELECT + UserId, + ManualPaymentId, + ExistingTxId, + PackageId, + Amount, + PurchasedAt, + CASE WHEN ExistingTxId IS NOT NULL THEN N'REUSE_MP_TX' ELSE N'CREATE_NEW_TX' END AS TxPlan +FROM #UppToCreate +ORDER BY UserId; + +DECLARE @UserId BIGINT; +DECLARE @ManualPaymentId BIGINT; +DECLARE @ExistingTxId BIGINT; +DECLARE @PackageId BIGINT; +DECLARE @Amount BIGINT; +DECLARE @PurchasedAt DATETIME2; +DECLARE @ReferenceNumber NVARCHAR(200); +DECLARE @Description NVARCHAR(500); +DECLARE @TxId BIGINT; +DECLARE @CreatedUpp INT = 0; +DECLARE @CreatedTx INT = 0; +DECLARE @ReusedTx INT = 0; + +DECLARE cur CURSOR LOCAL FAST_FORWARD FOR + SELECT UserId, ManualPaymentId, ExistingTxId, PackageId, Amount, PurchasedAt, ReferenceNumber, Description + FROM #UppToCreate; + +OPEN cur; +FETCH NEXT FROM cur INTO + @UserId, @ManualPaymentId, @ExistingTxId, @PackageId, @Amount, @PurchasedAt, @ReferenceNumber, @Description; + +WHILE @@FETCH_STATUS = 0 +BEGIN + SET @TxId = NULL; + + -- Reuse Success Tx from ManualPayment when possible + IF @ExistingTxId IS NOT NULL + AND EXISTS ( + SELECT 1 FROM CMS.Transactions t + WHERE t.Id = @ExistingTxId AND t.IsDeleted = 0 AND t.PaymentStatus = 0 + ) + BEGIN + SET @TxId = @ExistingTxId; + SET @ReusedTx = @ReusedTx + 1; + END + ELSE + BEGIN + INSERT INTO CMS.Transactions + ( + Amount, Description, PaymentStatus, PaymentDate, RefId, Type, + Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted + ) + VALUES + ( + @Amount, + CONCAT( + N'عضویت دستی باشگاه مشتریان - ', + ISNULL(@Description, N'backfill UPP'), + N' - مرجع: ', + ISNULL(@ReferenceNumber, CONCAT(N'MP-', @ManualPaymentId)) + ), + 0, -- Success + @PurchasedAt, + ISNULL(@ReferenceNumber, CONCAT(N'UPP-MP-FIX-', @ManualPaymentId)), + 2, -- DepositExternal1 + @PurchasedAt, NULL, @PurchasedAt, NULL, 0 + ); + SET @TxId = SCOPE_IDENTITY(); + SET @CreatedTx = @CreatedTx + 1; + + UPDATE CMS.ManualPayments + SET + TransactionId = @TxId, + LastModified = @Now + WHERE Id = @ManualPaymentId + AND (TransactionId IS NULL OR TransactionId <> @TxId); + END + + INSERT INTO CMS.UserPackagePurchases + ( + UserId, PackageId, PurchaseMethod, PurchasedAt, Amount, + OrderId, TransactionId, Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted + ) + VALUES + ( + @UserId, @PackageId, 3, -- Manual + @PurchasedAt, @Amount, + NULL, @TxId, @PurchasedAt, NULL, @PurchasedAt, NULL, 0 + ); + + -- Align user flag (only None/DirectPurchase → Manual; leave real Daya=1 alone) + UPDATE CMS.Users + SET + PackagePurchaseMethod = 3, + LastModified = @Now + WHERE Id = @UserId + AND IsDeleted = 0 + AND PackagePurchaseMethod IN (0, 2); + + SET @CreatedUpp = @CreatedUpp + 1; + + FETCH NEXT FROM cur INTO + @UserId, @ManualPaymentId, @ExistingTxId, @PackageId, @Amount, @PurchasedAt, @ReferenceNumber, @Description; +END + +CLOSE cur; +DEALLOCATE cur; + +DROP TABLE #UppToCreate; + +PRINT CONCAT('UPP created: ', @CreatedUpp, + ' | Tx reused: ', @ReusedTx, + ' | Tx created: ', @CreatedTx); + +------------------------------------------------------------ +-- 6) UserWalletHistory for every FixUser that has a Tx but no history +-- Runs AFTER step 5 so the ~18 new Txs are included. +-- The ~6 with existing UPP/Tx only get history (no new Tx if resolved). +-- NO wallet Balance/Discount charge. +------------------------------------------------------------ +;WITH BestManualAll AS ( + SELECT + mp.UserId, + mp.Id AS ManualPaymentId, + mp.Amount, + mp.TransactionId, + mp.ReferenceNumber, + mp.Description, + COALESCE(mp.ApprovedAt, mp.Created) AS PurchasedAt, + ROW_NUMBER() OVER ( + PARTITION BY mp.UserId + ORDER BY + CASE WHEN mp.Status = 1 THEN 0 ELSE 1 END, + CASE WHEN mp.TransactionId IS NOT NULL THEN 0 ELSE 1 END, + COALESCE(mp.ApprovedAt, mp.Created) DESC, + mp.Id DESC + ) AS rn + FROM CMS.ManualPayments mp + INNER JOIN @FixUsers f ON f.UserId = mp.UserId + WHERE mp.IsDeleted = 0 +), +Resolved AS ( + SELECT + bm.UserId, + bm.ManualPaymentId, + bm.ReferenceNumber, + bm.Description, + bm.PurchasedAt, + COALESCE(NULLIF(cm.LastPackageId, 0), NULLIF(cm.FirstPackageId, 0), @BasePackageId) AS PackageId, + CASE + WHEN bm.Amount IS NOT NULL AND bm.Amount > 0 THEN bm.Amount + ELSE COALESCE(p.Price, @BasePackagePrice) + END AS Amount, + COALESCE( + CASE + WHEN bm.TransactionId IS NOT NULL + AND EXISTS ( + SELECT 1 FROM CMS.Transactions t + WHERE t.Id = bm.TransactionId AND t.IsDeleted = 0 AND t.PaymentStatus = 0 + ) + THEN bm.TransactionId + END, + ( + SELECT TOP (1) upp.TransactionId + FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = bm.UserId AND upp.IsDeleted = 0 AND upp.TransactionId IS NOT NULL + ORDER BY upp.Id DESC + ), + ( + SELECT TOP (1) t.Id + FROM CMS.Transactions t + WHERE t.IsDeleted = 0 AND t.PaymentStatus = 0 + AND bm.ReferenceNumber IS NOT NULL + AND t.RefId = bm.ReferenceNumber + ORDER BY t.Id DESC + ) + ) AS TxId + FROM BestManualAll bm + LEFT JOIN CMS.ClubMemberships cm + ON cm.UserId = bm.UserId AND cm.IsDeleted = 0 + LEFT JOIN CMS.Packages p + ON p.Id = COALESCE(NULLIF(cm.LastPackageId, 0), NULLIF(cm.FirstPackageId, 0), @BasePackageId) + AND p.IsDeleted = 0 + WHERE bm.rn = 1 +) +SELECT + r.UserId, + r.ManualPaymentId, + r.TxId, + r.PackageId, + r.Amount, + COALESCE(t.PaymentDate, r.PurchasedAt) AS HistoryAt, + CAST(ROUND(r.Amount * COALESCE(p.DiscountMultiplier, 2.0), 0) AS BIGINT) AS DiscountAmount, + w.Id AS WalletId, + COALESCE(w.NetworkBalance, 0) AS NetworkBalance +INTO #WalletHistoryToCreate +FROM Resolved r +LEFT JOIN CMS.Transactions t ON t.Id = r.TxId AND t.IsDeleted = 0 +LEFT JOIN CMS.Packages p ON p.Id = r.PackageId AND p.IsDeleted = 0 +LEFT JOIN CMS.UserWallets w ON w.UserId = r.UserId AND w.IsDeleted = 0 +WHERE r.TxId IS NOT NULL + AND r.Amount > 0 + AND r.PackageId IS NOT NULL + AND NOT EXISTS ( + SELECT 1 + FROM CMS.UserWalletHistories h + INNER JOIN CMS.UserWallets wh ON wh.Id = h.WalletId AND wh.IsDeleted = 0 + WHERE wh.UserId = r.UserId + AND h.IsDeleted = 0 + AND h.RefrenceId = r.TxId + ); + +DECLARE @MissingWhCount INT = (SELECT COUNT(*) FROM #WalletHistoryToCreate); +PRINT CONCAT('Missing WalletHistory (after UPP/Tx step — expect ~6 old + ~18 new): ', @MissingWhCount); + +SELECT + UserId, ManualPaymentId, TxId, PackageId, Amount, DiscountAmount, HistoryAt, WalletId, + N'CREATE_HISTORY_ONLY' AS PlanAction +FROM #WalletHistoryToCreate +ORDER BY UserId; + +DECLARE @WalletId BIGINT; +DECLARE @DiscountAmount BIGINT; +DECLARE @HistoryAt DATETIME2; +DECLARE @NetworkBalance BIGINT; +DECLARE @CreatedWh INT = 0; + +DECLARE curWh CURSOR LOCAL FAST_FORWARD FOR + SELECT UserId, ManualPaymentId, TxId, PackageId, Amount, DiscountAmount, HistoryAt, WalletId, NetworkBalance + FROM #WalletHistoryToCreate; + +OPEN curWh; +FETCH NEXT FROM curWh INTO + @UserId, @ManualPaymentId, @TxId, @PackageId, @Amount, @DiscountAmount, @HistoryAt, @WalletId, @NetworkBalance; + +WHILE @@FETCH_STATUS = 0 +BEGIN + -- Keep MP linked to resolved Tx when it was found via UPP / RefId + UPDATE CMS.ManualPayments + SET TransactionId = @TxId, LastModified = @Now + WHERE Id = @ManualPaymentId + AND (TransactionId IS NULL OR TransactionId <> @TxId); + + IF @WalletId IS NULL + BEGIN + INSERT INTO CMS.UserWallets + (UserId, Balance, NetworkBalance, DiscountBalance, WalletMode, Created, LastModified, IsDeleted) + VALUES + (@UserId, 0, 0, 0, 0, @HistoryAt, @HistoryAt, 0); + SET @WalletId = SCOPE_IDENTITY(); + SET @NetworkBalance = 0; + END + + INSERT INTO CMS.UserWalletHistories + ( + WalletId, CurrentBalance, ChangeValue, CurrentNetworkBalance, ChangeNerworkValue, + CurrentDiscountBalance, ChangeDiscountValue, IsIncrease, RefrenceId, PackageId, + Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted + ) + VALUES + ( + @WalletId, + 0, + @Amount, + @NetworkBalance, + 0, + 0, + @DiscountAmount, + 1, + @TxId, + @PackageId, + @HistoryAt, + NULL, + @HistoryAt, + NULL, + 0 + ); + + SET @CreatedWh = @CreatedWh + 1; + + FETCH NEXT FROM curWh INTO + @UserId, @ManualPaymentId, @TxId, @PackageId, @Amount, @DiscountAmount, @HistoryAt, @WalletId, @NetworkBalance; +END + +CLOSE curWh; +DEALLOCATE curWh; + +DROP TABLE #WalletHistoryToCreate; + +PRINT CONCAT('WalletHistory created (no charge): ', @CreatedWh); + +------------------------------------------------------------ +-- Verify after +------------------------------------------------------------ +SELECT 'Users still DirectPurchase (in scope)' AS CheckName, COUNT(*) AS Cnt +FROM CMS.Users u +INNER JOIN @FixUsers f ON f.UserId = u.Id +WHERE u.IsDeleted = 0 AND u.PackagePurchaseMethod = 2 +UNION ALL +SELECT 'UPP still DirectPurchase (in scope)', COUNT(*) +FROM CMS.UserPackagePurchases upp +INNER JOIN @FixUsers f ON f.UserId = upp.UserId +WHERE upp.IsDeleted = 0 AND upp.PurchaseMethod = 2 +UNION ALL +SELECT 'Club still DirectPurchase (in scope)', COUNT(*) +FROM CMS.ClubMemberships m +INNER JOIN @FixUsers f ON f.UserId = m.UserId +WHERE m.IsDeleted = 0 AND m.PurchaseMethod = 2 +UNION ALL +SELECT 'Cycle still DirectPurchase (in scope)', COUNT(*) +FROM CMS.ClubMembershipCycles c +INNER JOIN @FixUsers f ON f.UserId = c.UserId +WHERE c.IsDeleted = 0 AND c.PurchaseMethod = 2 +UNION ALL +SELECT 'Still missing any UPP (in scope)', COUNT(*) +FROM @FixUsers f +WHERE NOT EXISTS ( + SELECT 1 FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = f.UserId AND upp.IsDeleted = 0 +) +UNION ALL +SELECT 'Still missing WalletHistory for resolved Tx', COUNT(*) +FROM @FixUsers f +OUTER APPLY ( + SELECT TOP (1) + mp.TransactionId AS MpTxId, + mp.ReferenceNumber + FROM CMS.ManualPayments mp + WHERE mp.UserId = f.UserId AND mp.IsDeleted = 0 + ORDER BY + CASE WHEN mp.Status = 1 THEN 0 ELSE 1 END, + CASE WHEN mp.TransactionId IS NOT NULL THEN 0 ELSE 1 END, + COALESCE(mp.ApprovedAt, mp.Created) DESC, + mp.Id DESC +) mp +OUTER APPLY ( + SELECT TOP (1) upp.TransactionId AS UppTxId + FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = f.UserId AND upp.IsDeleted = 0 AND upp.TransactionId IS NOT NULL + ORDER BY upp.Id DESC +) upp +CROSS APPLY ( + SELECT COALESCE( + CASE + WHEN mp.MpTxId IS NOT NULL + AND EXISTS ( + SELECT 1 FROM CMS.Transactions t + WHERE t.Id = mp.MpTxId AND t.IsDeleted = 0 AND t.PaymentStatus = 0 + ) + THEN mp.MpTxId + END, + upp.UppTxId, + ( + SELECT TOP (1) t.Id + FROM CMS.Transactions t + WHERE t.IsDeleted = 0 AND t.PaymentStatus = 0 + AND mp.ReferenceNumber IS NOT NULL + AND t.RefId = mp.ReferenceNumber + ORDER BY t.Id DESC + ) + ) AS TxId +) tx +WHERE tx.TxId IS NOT NULL + AND NOT EXISTS ( + SELECT 1 + FROM CMS.UserWalletHistories h + INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 + WHERE w.UserId = f.UserId + AND h.IsDeleted = 0 + AND h.RefrenceId = tx.TxId + ); + +SELECT TOP (50) + u.Id AS UserId, + u.Mobile, + u.PackagePurchaseMethod AS UserMethod, + m.PurchaseMethod AS ClubMethod, + (SELECT COUNT(*) FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = u.Id AND upp.IsDeleted = 0 AND upp.PurchaseMethod = 3) AS UppManualCnt +FROM CMS.Users u +INNER JOIN @FixUsers f ON f.UserId = u.Id +LEFT JOIN CMS.ClubMemberships m ON m.UserId = u.Id AND m.IsDeleted = 0 +WHERE u.IsDeleted = 0 +ORDER BY u.Id; + +-- Uncomment to apply: +-- COMMIT; +ROLLBACK; +PRINT 'Rolled back (safety). Uncomment COMMIT and remove ROLLBACK to apply.'; diff --git a/src/dbbkup/8-Backfill_UserWalletHistory_ForManualPayment_Txs.sql b/src/dbbkup/8-Backfill_UserWalletHistory_ForManualPayment_Txs.sql new file mode 100644 index 0000000..b882a2b --- /dev/null +++ b/src/dbbkup/8-Backfill_UserWalletHistory_ForManualPayment_Txs.sql @@ -0,0 +1,215 @@ +/* + Backfill UserWalletHistory for 6 ManualPayment users (history only — NO wallet charge) + + Transaction IDs: + 172, 40182, 40184, 40201, 40264, 110556 + + Wallet was already charged when ManualPayment ran; this script only inserts + the missing UserWalletHistory row (same shape as CreateManualPayment). + + Defaults to ROLLBACK. Uncomment COMMIT after verifying preview. +*/ + +SET NOCOUNT ON; +SET XACT_ABORT ON; + +BEGIN TRAN; + +DECLARE @Now DATETIME2 = SYSUTCDATETIME(); + +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 @TargetTx TABLE (TransactionId BIGINT PRIMARY KEY); + +INSERT INTO @TargetTx (TransactionId) +VALUES + (172), + (40182), + (40184), + (40201), + (40264), + (110556); + +------------------------------------------------------------ +-- Preview +------------------------------------------------------------ +SELECT + tx.TransactionId, + t.Amount AS TxAmount, + t.PaymentDate, + t.PaymentStatus, + t.IsDeleted AS TxDeleted, + COALESCE(mp.UserId, upp.UserId) AS UserId, + mp.Id AS ManualPaymentId, + upp.Id AS UserPackagePurchaseId, + COALESCE( + upp.PackageId, + NULLIF(cm.LastPackageId, 0), + NULLIF(cm.FirstPackageId, 0), + @BasePackageId + ) AS PackageId, + w.Id AS WalletId, + h.Id AS ExistingWalletHistoryId, + CASE + WHEN t.Id IS NULL THEN N'TX_NOT_FOUND' + WHEN t.IsDeleted = 1 THEN N'TX_DELETED' + WHEN t.PaymentStatus <> 0 THEN N'TX_NOT_SUCCESS' + WHEN COALESCE(mp.UserId, upp.UserId) IS NULL THEN N'USER_NOT_RESOLVED' + WHEN w.Id IS NULL THEN N'WALLET_MISSING' + WHEN h.Id IS NOT NULL THEN N'ALREADY_HAS_HISTORY' + ELSE N'WILL_CREATE_HISTORY' + END AS PlanAction +FROM @TargetTx tx +LEFT JOIN CMS.Transactions t ON t.Id = tx.TransactionId +LEFT JOIN CMS.ManualPayments mp + ON mp.TransactionId = tx.TransactionId AND mp.IsDeleted = 0 +LEFT JOIN CMS.UserPackagePurchases upp + ON upp.TransactionId = tx.TransactionId AND upp.IsDeleted = 0 +LEFT JOIN CMS.ClubMemberships cm + ON cm.UserId = COALESCE(mp.UserId, upp.UserId) AND cm.IsDeleted = 0 +LEFT JOIN CMS.UserWallets w + ON w.UserId = COALESCE(mp.UserId, upp.UserId) AND w.IsDeleted = 0 +OUTER APPLY ( + SELECT TOP (1) h0.Id + FROM CMS.UserWalletHistories h0 + WHERE h0.IsDeleted = 0 + AND h0.RefrenceId = tx.TransactionId + AND ( + w.Id IS NULL + OR h0.WalletId = w.Id + ) +) h +ORDER BY tx.TransactionId; + +SELECT 'Will create WalletHistory' AS CheckName, COUNT(*) AS Cnt +FROM @TargetTx tx +INNER JOIN CMS.Transactions t ON t.Id = tx.TransactionId AND t.IsDeleted = 0 AND t.PaymentStatus = 0 +OUTER APPLY ( + SELECT TOP (1) mp.UserId + FROM CMS.ManualPayments mp + WHERE mp.TransactionId = tx.TransactionId AND mp.IsDeleted = 0 +) mp +OUTER APPLY ( + SELECT TOP (1) upp.UserId, upp.PackageId + FROM CMS.UserPackagePurchases upp + WHERE upp.TransactionId = tx.TransactionId AND upp.IsDeleted = 0 + ORDER BY upp.Id DESC +) upp +CROSS APPLY ( + SELECT COALESCE(mp.UserId, upp.UserId) AS UserId +) u +INNER JOIN CMS.UserWallets w ON w.UserId = u.UserId AND w.IsDeleted = 0 +WHERE NOT EXISTS ( + SELECT 1 + FROM CMS.UserWalletHistories h + WHERE h.WalletId = w.Id + AND h.IsDeleted = 0 + AND h.RefrenceId = tx.TransactionId +); + +------------------------------------------------------------ +-- Insert missing history +------------------------------------------------------------ +;WITH Resolved AS ( + SELECT + tx.TransactionId AS TxId, + t.Amount, + COALESCE(t.PaymentDate, t.Created) AS HistoryAt, + COALESCE(mp.UserId, upp.UserId) AS UserId, + COALESCE( + upp.PackageId, + NULLIF(cm.LastPackageId, 0), + NULLIF(cm.FirstPackageId, 0), + @BasePackageId + ) AS PackageId, + w.Id AS WalletId, + COALESCE(w.NetworkBalance, 0) AS NetworkBalance + FROM @TargetTx tx + INNER JOIN CMS.Transactions t + ON t.Id = tx.TransactionId AND t.IsDeleted = 0 AND t.PaymentStatus = 0 + OUTER APPLY ( + SELECT TOP (1) mp0.UserId, mp0.Id AS ManualPaymentId + FROM CMS.ManualPayments mp0 + WHERE mp0.TransactionId = tx.TransactionId AND mp0.IsDeleted = 0 + ) mp + OUTER APPLY ( + SELECT TOP (1) upp0.UserId, upp0.PackageId + FROM CMS.UserPackagePurchases upp0 + WHERE upp0.TransactionId = tx.TransactionId AND upp0.IsDeleted = 0 + ORDER BY upp0.Id DESC + ) upp + LEFT JOIN CMS.ClubMemberships cm + ON cm.UserId = COALESCE(mp.UserId, upp.UserId) AND cm.IsDeleted = 0 + INNER JOIN CMS.UserWallets w + ON w.UserId = COALESCE(mp.UserId, upp.UserId) AND w.IsDeleted = 0 + WHERE COALESCE(mp.UserId, upp.UserId) IS NOT NULL + AND NOT EXISTS ( + SELECT 1 + FROM CMS.UserWalletHistories h + WHERE h.WalletId = w.Id + AND h.IsDeleted = 0 + AND h.RefrenceId = tx.TransactionId + ) +) +INSERT INTO CMS.UserWalletHistories +( + WalletId, CurrentBalance, ChangeValue, CurrentNetworkBalance, ChangeNerworkValue, + CurrentDiscountBalance, ChangeDiscountValue, IsIncrease, RefrenceId, PackageId, + Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted +) +SELECT + r.WalletId, + 0, + r.Amount, + r.NetworkBalance, + 0, + 0, + CAST(ROUND(r.Amount * COALESCE(p.DiscountMultiplier, 2.0), 0) AS BIGINT), + 1, + r.TxId, + r.PackageId, + r.HistoryAt, + NULL, + r.HistoryAt, + NULL, + 0 +FROM Resolved r +LEFT JOIN CMS.Packages p ON p.Id = r.PackageId AND p.IsDeleted = 0 +WHERE r.PackageId IS NOT NULL + AND r.Amount > 0; + +PRINT CONCAT('UserWalletHistory inserted: ', @@ROWCOUNT); + +------------------------------------------------------------ +-- Verify +------------------------------------------------------------ +SELECT + tx.TransactionId, + h.Id AS WalletHistoryId, + h.ChangeValue, + h.ChangeDiscountValue, + h.RefrenceId, + h.Created AS HistoryCreated, + w.UserId +FROM @TargetTx tx +LEFT JOIN CMS.UserWalletHistories h + ON h.RefrenceId = tx.TransactionId AND h.IsDeleted = 0 +LEFT JOIN CMS.UserWallets w + ON w.Id = h.WalletId AND w.IsDeleted = 0 +ORDER BY tx.TransactionId; + +-- Uncomment to apply: +-- COMMIT; +ROLLBACK; +PRINT 'Rolled back (safety). Uncomment COMMIT and remove ROLLBACK to apply.'; diff --git a/src/dbbkup/9-Diagnose_WrongDaya_Ledger_FromWalletHistory.sql b/src/dbbkup/9-Diagnose_WrongDaya_Ledger_FromWalletHistory.sql new file mode 100644 index 0000000..5ffcc7d --- /dev/null +++ b/src/dbbkup/9-Diagnose_WrongDaya_Ledger_FromWalletHistory.sql @@ -0,0 +1,431 @@ +/* + DIAGNOSTIC ONLY — no data changes (read-only) + + Trace WrongDaya→Manual FixUsers ledger via UserWalletHistory: + WalletHistory → CreatedBy/LastModifiedBy (mobile) → User → Wallet + → Transaction (RefrenceId / CreatedBy-as-TxId / Tx.CreatedBy mobile) + → UPP / ManualPayment / PurchaseMethod + + Known IDs from manual CSV exports (UserWalletHistories*.csv, Transactions.csv): + WH: 102-108,122,138-142,292-295,118-121,124,201 + Tx: 23-31,42-46,56-59,68,107-110 + + RefrenceId=0 rule (ChargeUserWallets.sql): + RefId = 'manualy' + original ChangeLogId. After id remap, WH.RefrenceId may be 0. + For Ref=0 rows, assume Tx exists ONLY if CreatedBy is numeric AND that Tx has RefId manualy%. + Do NOT infer Tx from mobile alone or from manualy{N} suffix alone. + + See also: 10-Diagnose_Manualy_Transaction_Map.sql + + Run on staging, review Verdict + RecommendedAction per user before any fix script. +*/ + +SET NOCOUNT ON; + +DECLARE @FixUsers TABLE (UserId BIGINT PRIMARY KEY); +INSERT INTO @FixUsers (UserId) VALUES +(2),(7),(8),(9),(10),(11),(12),(13),(40),(41),(43),(45),(47), +(52),(58),(69),(71),(72),(74),(75),(87),(88),(89),(90),(91),(93), +(96),(99),(103),(105),(106),(111),(113),(115),(116),(119),(121), +(125),(130),(142),(162),(169),(170),(171),(172),(175),(176); + +-- Known WalletHistory / Transaction ids from CSV exports (for cross-check) +DECLARE @KnownWh TABLE (WalletHistoryId BIGINT PRIMARY KEY); +INSERT INTO @KnownWh (WalletHistoryId) VALUES +(102),(103),(104),(105),(106),(107),(108),(122), +(138),(139),(140),(141),(142), +(292),(293),(294),(295), +(118),(119),(120),(121),(124),(201); + +DECLARE @KnownTx TABLE (TransactionId BIGINT PRIMARY KEY); +INSERT INTO @KnownTx (TransactionId) VALUES +(23),(24),(25),(26),(28),(29),(30),(31), +(42),(43),(44),(45),(46), +(56),(57),(58),(59),(68), +(107),(108),(109),(110); + +DECLARE @TargetUserCount INT = (SELECT COUNT(*) FROM @FixUsers); +PRINT CONCAT('FixUsers scope: ', @TargetUserCount); + +------------------------------------------------------------ +-- 1) WalletHistories found BY mobile in CreatedBy / LastModifiedBy +-- (starts from WH — user request) +------------------------------------------------------------ +PRINT '=== 1) WalletHistory → User via CreatedBy/LastModifiedBy mobile ==='; + +SELECT + h.Id AS WalletHistoryId, + h.WalletId, + h.RefrenceId AS WhRefrenceId, + h.ChangeValue, + h.ChangeDiscountValue, + h.Created AS WhCreated, + h.CreatedBy AS WhCreatedBy, + h.LastModifiedBy AS WhLastModifiedBy, + u.Id AS UserId, + u.Mobile, + u.FirstName, + u.LastName, + u.PackagePurchaseMethod AS UserMethod, + CASE WHEN kwh.WalletHistoryId IS NOT NULL THEN 1 ELSE 0 END AS InKnownWhCsv, + CASE + WHEN u.Id IS NULL THEN N'NO_USER_FOR_MOBILE' + WHEN f.UserId IS NULL THEN N'USER_NOT_IN_FIX_SCOPE' + ELSE N'IN_FIX_SCOPE' + END AS ScopeStatus +FROM CMS.UserWalletHistories h +LEFT JOIN CMS.Users u ON u.IsDeleted = 0 + AND u.Mobile IN ( + NULLIF(LTRIM(RTRIM(h.CreatedBy)), N''), + NULLIF(LTRIM(RTRIM(h.LastModifiedBy)), N'') + ) +LEFT JOIN @FixUsers f ON f.UserId = u.Id +LEFT JOIN @KnownWh kwh ON kwh.WalletHistoryId = h.Id +WHERE h.IsDeleted = 0 + AND ( + (h.CreatedBy LIKE N'09%' AND LEN(h.CreatedBy) >= 10) + OR (h.LastModifiedBy LIKE N'09%' AND LEN(h.LastModifiedBy) >= 10) + ) +ORDER BY h.Id; + +------------------------------------------------------------ +-- 2) All WalletHistories for FixUsers (via Wallet → User) +------------------------------------------------------------ +PRINT '=== 2) All WalletHistory rows for FixUsers ==='; + +SELECT + f.UserId, + u.Mobile, + u.FirstName, + u.LastName, + u.PackagePurchaseMethod AS UserMethod, + w.Id AS WalletId, + h.Id AS WalletHistoryId, + h.RefrenceId AS WhRefrenceId, + h.ChangeValue, + h.ChangeDiscountValue, + h.Created AS WhCreated, + h.CreatedBy AS WhCreatedBy, + h.LastModifiedBy AS WhLastModifiedBy, + CASE WHEN kwh.WalletHistoryId IS NOT NULL THEN 1 ELSE 0 END AS InKnownWhCsv, + CASE WHEN h.RefrenceId IS NULL OR h.RefrenceId = 0 THEN N'WH_NO_REF' ELSE N'WH_HAS_REF' END AS WhRefStatus +FROM @FixUsers f +INNER JOIN CMS.Users u ON u.Id = f.UserId AND u.IsDeleted = 0 +INNER JOIN CMS.UserWallets w ON w.UserId = f.UserId AND w.IsDeleted = 0 +INNER JOIN CMS.UserWalletHistories h ON h.WalletId = w.Id AND h.IsDeleted = 0 +LEFT JOIN @KnownWh kwh ON kwh.WalletHistoryId = h.Id +ORDER BY f.UserId, h.Id; + +------------------------------------------------------------ +-- 3) Per-user ledger verdict (WH + Tx + UPP) +------------------------------------------------------------ +PRINT '=== 3) Per-user ledger verdict ==='; + +;WITH UserWh AS ( + SELECT + f.UserId, + COUNT(*) AS WalletHistoryCount, + SUM(CASE WHEN h.RefrenceId IS NULL OR h.RefrenceId = 0 THEN 1 ELSE 0 END) AS WhMissingRefCount, + SUM(CASE WHEN kwh.WalletHistoryId IS NOT NULL THEN 1 ELSE 0 END) AS KnownCsvWhCount, + MAX(h.Id) AS LatestWhId, + MAX(h.RefrenceId) AS LatestWhRefId + FROM @FixUsers f + INNER JOIN CMS.UserWallets w ON w.UserId = f.UserId AND w.IsDeleted = 0 + LEFT JOIN CMS.UserWalletHistories h ON h.WalletId = w.Id AND h.IsDeleted = 0 + LEFT JOIN @KnownWh kwh ON kwh.WalletHistoryId = h.Id + GROUP BY f.UserId +), +UserTxViaWh AS ( + SELECT + uw.UserId, + COUNT(DISTINCT t.Id) AS TxViaWhRefCount, + MAX(t.Id) AS SampleTxViaWhRef + FROM UserWh uw + INNER JOIN CMS.UserWallets w ON w.UserId = uw.UserId AND w.IsDeleted = 0 + 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 + GROUP BY uw.UserId +), +UserTxViaMobile AS ( + SELECT + f.UserId, + COUNT(DISTINCT t.Id) AS TxViaMobileCount, + MAX(t.Id) AS SampleTxViaMobile + FROM @FixUsers f + INNER JOIN CMS.Users u ON u.Id = f.UserId AND u.IsDeleted = 0 + INNER JOIN CMS.Transactions t ON t.IsDeleted = 0 + AND (t.CreatedBy = u.Mobile OR t.LastModifiedBy = u.Mobile) + GROUP BY f.UserId +), +UserTxViaCreatedByHint AS ( + -- WH.CreatedBy stores Tx Id when RefrenceId=0 failed to update (UserWalletHistories2.csv). + -- Only count when hinted Tx exists AND is manualy% (may still be wrong user — verify mobile). + SELECT + f.UserId, + COUNT(DISTINCT t.Id) AS TxViaWhCreatedByHintCount, + MAX(t.Id) AS SampleTxViaHint + FROM @FixUsers f + INNER JOIN CMS.UserWallets w ON w.UserId = f.UserId AND w.IsDeleted = 0 + INNER JOIN CMS.UserWalletHistories h ON h.WalletId = w.Id AND h.IsDeleted = 0 + INNER JOIN CMS.Transactions t ON t.Id = TRY_CAST(h.CreatedBy AS BIGINT) + AND t.IsDeleted = 0 AND t.RefId LIKE N'manualy%' + WHERE (h.RefrenceId IS NULL OR h.RefrenceId = 0) + AND TRY_CAST(h.CreatedBy AS BIGINT) > 0 + GROUP BY f.UserId +), +UserTxViaManualyMobile AS ( + -- Informational only — NOT used alone for Ref=0 WH linking + SELECT + f.UserId, + COUNT(DISTINCT t.Id) AS TxViaManualyMobileCount, + MAX(t.Id) AS SampleManualyTxViaMobile + FROM @FixUsers f + INNER JOIN CMS.Users u ON u.Id = f.UserId AND u.IsDeleted = 0 + INNER JOIN CMS.Transactions t ON t.IsDeleted = 0 + AND t.RefId LIKE N'manualy%' + AND u.Mobile IN ( + NULLIF(LTRIM(RTRIM(t.CreatedBy)), N''), + NULLIF(LTRIM(RTRIM(t.LastModifiedBy)), N'') + ) + GROUP BY f.UserId +), +UserUpp AS ( + SELECT + f.UserId, + COUNT(*) AS UppCount, + SUM(CASE WHEN upp.PurchaseMethod = 1 THEN 1 ELSE 0 END) AS UppDayaCount, + SUM(CASE WHEN upp.PurchaseMethod = 3 THEN 1 ELSE 0 END) AS UppManualCount, + MAX(upp.TransactionId) AS LatestUppTxId + FROM @FixUsers f + LEFT JOIN CMS.UserPackagePurchases upp + ON upp.UserId = f.UserId AND upp.IsDeleted = 0 + GROUP BY f.UserId +), +UserMp AS ( + SELECT + f.UserId, + COUNT(*) AS ManualPaymentCount, + MAX(mp.TransactionId) AS LatestMpTxId + FROM @FixUsers f + LEFT JOIN CMS.ManualPayments mp + ON mp.UserId = f.UserId AND mp.IsDeleted = 0 + GROUP BY f.UserId +) +SELECT * +FROM ( + SELECT + f.UserId, + u.Mobile, + u.FirstName, + u.LastName, + u.PackagePurchaseMethod AS UserMethod, + ISNULL(uwh.WalletHistoryCount, 0) AS WalletHistoryCount, + ISNULL(uwh.WhMissingRefCount, 0) AS WhMissingRefCount, + ISNULL(uwh.KnownCsvWhCount, 0) AS KnownCsvWhCount, + uwh.LatestWhId, + uwh.LatestWhRefId, + ISNULL(utw.TxViaWhRefCount, 0) AS TxViaWhRefCount, + utw.SampleTxViaWhRef, + ISNULL(utm.TxViaMobileCount, 0) AS TxViaMobileCount, + utm.SampleTxViaMobile, + ISNULL(uth.TxViaWhCreatedByHintCount, 0) AS TxViaWhCreatedByHintCount, + uth.SampleTxViaHint, + ISNULL(utmm.TxViaManualyMobileCount, 0) AS TxViaManualyMobileCount, + utmm.SampleManualyTxViaMobile, + ISNULL(uu.UppCount, 0) AS UppCount, + ISNULL(uu.UppDayaCount, 0) AS UppDayaCount, + uu.LatestUppTxId, + ISNULL(ump.ManualPaymentCount, 0) AS ManualPaymentCount, + ump.LatestMpTxId, + CASE + WHEN ISNULL(uwh.WalletHistoryCount, 0) = 0 THEN N'NO_WALLET_HISTORY' + WHEN ISNULL(uwh.WhMissingRefCount, 0) > 0 + AND ISNULL(uth.TxViaWhCreatedByHintCount, 0) > 0 THEN N'WH_REF_BROKEN_FIX_VIA_CREATEDBY_HINT' + WHEN ISNULL(uwh.WhMissingRefCount, 0) > 0 + AND ISNULL(utmm.TxViaManualyMobileCount, 0) > 0 THEN N'WH_REF_BROKEN_MANUALY_TX_BY_MOBILE_REVIEW' + WHEN ISNULL(uwh.WhMissingRefCount, 0) > 0 THEN N'WH_REF_BROKEN_NO_TX_HINT' + WHEN ISNULL(utw.TxViaWhRefCount, 0) > 0 + AND ISNULL(uu.UppCount, 0) = 0 THEN N'HAS_WH+TX_NEED_UPP' + WHEN ISNULL(utw.TxViaWhRefCount, 0) > 0 + AND ISNULL(uu.UppDayaCount, 0) > 0 THEN N'HAS_WH+TX_UPP_DAYA_FIX_METHOD' + WHEN ISNULL(utw.TxViaWhRefCount, 0) > 0 THEN N'OK_WH+TX' + WHEN ISNULL(utm.TxViaMobileCount, 0) > 0 THEN N'TX_BY_MOBILE_WH_LINK_UNCLEAR' + ELSE N'NEEDS_MANUAL_REVIEW' + END AS Verdict, + CASE + WHEN ISNULL(uwh.WalletHistoryCount, 0) = 0 THEN N'Create WH+Tx+UPP (or find hidden WH by mobile)' + WHEN ISNULL(uwh.WhMissingRefCount, 0) > 0 + AND ISNULL(uth.TxViaWhCreatedByHintCount, 0) > 0 THEN N'Link WH.RefrenceId to manualy Tx from CreatedBy hint only' + WHEN ISNULL(uwh.WhMissingRefCount, 0) > 0 + AND ISNULL(utmm.TxViaManualyMobileCount, 0) > 0 THEN N'manualy Tx exists by mobile but WH hint missing — manual review' + WHEN ISNULL(uwh.WhMissingRefCount, 0) > 0 THEN N'No Tx hint — do NOT assume Tx exists; review charge log' + WHEN ISNULL(utw.TxViaWhRefCount, 0) > 0 AND ISNULL(uu.UppCount, 0) = 0 THEN N'Create UPP Manual(3) reusing Tx' + WHEN ISNULL(uu.UppDayaCount, 0) > 0 OR u.PackagePurchaseMethod = 1 THEN N'Fix PurchaseMethod 1→3 only' + ELSE N'Likely OK — verify PurchaseMethod' + END AS RecommendedAction + FROM @FixUsers f + INNER JOIN CMS.Users u ON u.Id = f.UserId AND u.IsDeleted = 0 + LEFT JOIN UserWh uwh ON uwh.UserId = f.UserId + LEFT JOIN UserTxViaWh utw ON utw.UserId = f.UserId + LEFT JOIN UserTxViaMobile utm ON utm.UserId = f.UserId + LEFT JOIN UserTxViaCreatedByHint uth ON uth.UserId = f.UserId + LEFT JOIN UserTxViaManualyMobile utmm ON utmm.UserId = f.UserId + LEFT JOIN UserUpp uu ON uu.UserId = f.UserId + LEFT JOIN UserMp ump ON ump.UserId = f.UserId +) q +ORDER BY + CASE q.Verdict + WHEN N'OK_WH+TX' THEN 9 + WHEN N'HAS_WH+TX_UPP_DAYA_FIX_METHOD' THEN 8 + ELSE 1 + END, + q.UserId; + +------------------------------------------------------------ +-- 4) Summary counts by Verdict +------------------------------------------------------------ +PRINT '=== 4) Summary by Verdict ==='; + +;WITH PerUser AS ( + SELECT + f.UserId, + u.PackagePurchaseMethod AS UserMethod, + ISNULL(uwh.Cnt, 0) AS WhCnt, + ISNULL(uwh.BadRefCnt, 0) AS WhBadRefCnt, + ISNULL(utw.Cnt, 0) AS TxViaWhCnt, + ISNULL(utm.Cnt, 0) AS TxViaMobileCnt, + ISNULL(uth.Cnt, 0) AS TxViaHintCnt, + ISNULL(uu.Cnt, 0) AS UppCnt + FROM @FixUsers f + INNER JOIN CMS.Users u ON u.Id = f.UserId AND u.IsDeleted = 0 + OUTER APPLY ( + SELECT COUNT(*) AS Cnt, + SUM(CASE WHEN h.RefrenceId IS NULL OR h.RefrenceId = 0 THEN 1 ELSE 0 END) AS BadRefCnt + FROM CMS.UserWallets w + INNER JOIN CMS.UserWalletHistories h ON h.WalletId = w.Id AND h.IsDeleted = 0 + WHERE w.UserId = f.UserId AND w.IsDeleted = 0 + ) uwh + OUTER APPLY ( + SELECT COUNT(DISTINCT t.Id) AS Cnt + 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 + WHERE w.UserId = f.UserId AND w.IsDeleted = 0 + ) utw + OUTER APPLY ( + SELECT COUNT(DISTINCT t.Id) AS Cnt + FROM CMS.Transactions t + WHERE t.IsDeleted = 0 + AND (t.CreatedBy = u.Mobile OR t.LastModifiedBy = u.Mobile) + ) utm + OUTER APPLY ( + SELECT COUNT(DISTINCT t.Id) AS Cnt + 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 = TRY_CAST(h.CreatedBy AS BIGINT) + AND t.IsDeleted = 0 AND t.RefId LIKE N'manualy%' + WHERE w.UserId = f.UserId AND w.IsDeleted = 0 + AND (h.RefrenceId IS NULL OR h.RefrenceId = 0) + AND TRY_CAST(h.CreatedBy AS BIGINT) > 0 + ) uth + OUTER APPLY ( + SELECT COUNT(*) AS Cnt + FROM CMS.UserPackagePurchases upp + WHERE upp.UserId = f.UserId AND upp.IsDeleted = 0 + ) uu +), +Verdicts AS ( + SELECT + UserId, + CASE + WHEN WhCnt = 0 THEN N'NO_WALLET_HISTORY' + WHEN WhBadRefCnt > 0 AND TxViaHintCnt > 0 THEN N'WH_REF_BROKEN_FIX_VIA_CREATEDBY_HINT' + WHEN WhBadRefCnt > 0 THEN N'WH_REF_BROKEN_NO_TX_HINT' + WHEN TxViaWhCnt > 0 AND UppCnt = 0 THEN N'HAS_WH+TX_NEED_UPP' + WHEN TxViaWhCnt > 0 THEN N'OK_WH+TX' + WHEN TxViaMobileCnt > 0 THEN N'TX_BY_MOBILE_WH_LINK_UNCLEAR' + ELSE N'NEEDS_MANUAL_REVIEW' + END AS Verdict + FROM PerUser +) +SELECT Verdict, COUNT(*) AS UserCount +FROM Verdicts +GROUP BY Verdict +ORDER BY UserCount DESC; + +------------------------------------------------------------ +-- 5) Known CSV Tx ids — exist in DB? linked to WH/UPP? +------------------------------------------------------------ +PRINT '=== 5) Known Transaction IDs from CSV ==='; + +SELECT + kt.TransactionId, + CASE WHEN t.Id IS NULL THEN N'MISSING_IN_DB' ELSE N'EXISTS' END AS TxStatus, + t.Amount, + t.Description, + t.RefId, + t.CreatedBy AS TxCreatedBy, + t.LastModifiedBy AS TxLastModifiedBy, + u.Id AS UserByMobile, + u.Mobile, + h.Id AS LinkedWalletHistoryId, + h.WalletId, + h.RefrenceId AS WhRefrenceId, + upp.UserId AS UppUserId, + upp.PurchaseMethod AS UppMethod +FROM @KnownTx kt +LEFT JOIN CMS.Transactions t ON t.Id = kt.TransactionId +LEFT JOIN CMS.Users u ON u.IsDeleted = 0 + AND u.Mobile IN (NULLIF(t.CreatedBy, N''), NULLIF(t.LastModifiedBy, N'')) +LEFT JOIN CMS.UserWalletHistories h ON h.IsDeleted = 0 AND h.RefrenceId = kt.TransactionId +LEFT JOIN CMS.UserPackagePurchases upp ON upp.IsDeleted = 0 AND upp.TransactionId = kt.TransactionId +ORDER BY kt.TransactionId; + +------------------------------------------------------------ +-- 6) Known CSV WH ids — RefrenceId vs CreatedBy hint vs mobile +------------------------------------------------------------ +PRINT '=== 6) Known WalletHistory IDs from CSV ==='; + +SELECT + kw.WalletHistoryId, + h.WalletId, + h.RefrenceId AS WhRefrenceId, + h.ChangeValue, + h.CreatedBy AS WhCreatedBy, + h.LastModifiedBy AS WhLastModifiedBy, + w.UserId AS WalletUserId, + u.Mobile AS WalletUserMobile, + u_by_mobile.Id AS UserByWhMobile, + u_by_mobile.Mobile AS MatchedMobile, + t_ref.Id AS TxByRefrenceId, + t_ref.Description AS TxByRefDescription, + t_hint.Id AS TxByCreatedByHint, + t_hint.RefId AS TxByHintRefId, + t_hint.Description AS TxByHintDescription, + TRY_CAST( + SUBSTRING(t_hint.RefId, LEN(N'manualy') + 1, 20) + AS BIGINT + ) AS ManualyOriginalChangeLogId, + CASE + WHEN h.Id IS NULL THEN N'WH_MISSING_IN_DB' + WHEN t_ref.Id IS NOT NULL AND t_ref.RefId LIKE N'manualy%' THEN N'WH_LINKED_TO_MANUALY_TX' + WHEN t_ref.Id IS NOT NULL THEN N'WH_LINKED_TO_OTHER_TX' + WHEN t_hint.Id IS NOT NULL AND t_hint.RefId LIKE N'manualy%' THEN N'WH_REF_BROKEN_USE_CREATEDBY_HINT' + WHEN TRY_CAST(h.CreatedBy AS BIGINT) > 0 AND t_hint.Id IS NULL THEN N'WH_HINT_TX_MISSING' + WHEN u_by_mobile.Id IS NOT NULL THEN N'WH_MOBILE_ONLY_NO_AUTO_LINK' + ELSE N'WH_ORPHAN_REVIEW' + END AS WhLinkStatus +FROM @KnownWh kw +LEFT JOIN CMS.UserWalletHistories h ON h.Id = kw.WalletHistoryId AND h.IsDeleted = 0 +LEFT JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0 +LEFT JOIN CMS.Users u ON u.Id = w.UserId AND u.IsDeleted = 0 +LEFT JOIN CMS.Users u_by_mobile ON u_by_mobile.IsDeleted = 0 + AND u_by_mobile.Mobile IN ( + NULLIF(LTRIM(RTRIM(h.CreatedBy)), N''), + NULLIF(LTRIM(RTRIM(h.LastModifiedBy)), N'') + ) +LEFT JOIN CMS.Transactions t_ref ON t_ref.Id = h.RefrenceId AND t_ref.IsDeleted = 0 +LEFT JOIN CMS.Transactions t_hint ON t_hint.Id = TRY_CAST(h.CreatedBy AS BIGINT) AND t_hint.IsDeleted = 0 +ORDER BY kw.WalletHistoryId; + +PRINT 'Done (diagnostic only — no changes).'; diff --git a/src/dbbkup/9-result.csv b/src/dbbkup/9-result.csv new file mode 100644 index 0000000..0201e47 --- /dev/null +++ b/src/dbbkup/9-result.csv @@ -0,0 +1,415 @@ +"WalletHistoryId","WalletId","WhRefrenceId","ChangeValue","ChangeDiscountValue","WhCreated","WhCreatedBy","WhLastModifiedBy","UserId","Mobile","FirstName","LastName","UserMethod","InKnownWhCsv","ScopeStatus" +"118","34","0","1","0","3/12/2025 09:49:45.92","56","09015793338","71","09015793338","حمیدرضا","مرجانی","3","1","IN_FIX_SCOPE" +"119","32","0","1","0","19/11/2025 01:24:24","58","09217672935","69","09217672935","مهدی ","گیوی ","3","1","IN_FIX_SCOPE" +"120","37","0","1","0","19/11/2025 01:24:24","59","09101692049","74","09101692049","سجاد ","اداوی","3","1","IN_FIX_SCOPE" +"121","12","0","1","0","19/12/2025 22:00:40.276666","0","09387342688","2","09387342688","رباب","مرجانی","3","1","IN_FIX_SCOPE" +"124","35","0","1","0","19/11/2025 01:24:24","57","09961354257",,,,,,"1","NO_USER_FOR_MOBILE" +"125","42","53","56000000","112000000","3/12/2025 09:49:45.92","09172606097","09172606097","88","09172606097","کریم","رعیت پیشه","1","0","IN_FIX_SCOPE" +"126","71","54","56000000","112000000","3/12/2025 09:49:45.92","09199105580","09199105580","123","09199105580","ناصر ","کریمی پیروز ","1","0","USER_NOT_IN_FIX_SCOPE" +"127","43","55","56000000","112000000","3/12/2025 09:49:45.92","09174337813","09174337813","90","09174337813","علیرضا ","پولادی","1","0","IN_FIX_SCOPE" +"131","62","35","56000000","112000000","3/12/2025 09:49:45.92","09397939699","09397939699","114","09397939699","اکرم","دهقانی","1","0","USER_NOT_IN_FIX_SCOPE" +"132","50","36","56000000","112000000","3/12/2025 09:49:45.92","09367537393","09367537393","101","09367537393","مبینا","مالمیر","1","0","USER_NOT_IN_FIX_SCOPE" +"133","66","37","56000000","112000000","3/12/2025 09:49:45.92","09926262237","09926262237","118","09926262237","مهدی ","محیط آبادی","1","0","USER_NOT_IN_FIX_SCOPE" +"134","73","38","56000000","112000000","3/12/2025 09:49:45.92","09126302293","09126302293","125","09126302293","محمود","دادگرکریمی","1","0","IN_FIX_SCOPE" +"135","70","39","56000000","112000000","3/12/2025 09:49:45.92","09107033016","09107033016","122","09107033016","ابوالقا‌‌سم","عابدی","1","0","USER_NOT_IN_FIX_SCOPE" +"136","44","40","56000000","112000000","3/12/2025 09:49:45.92","09390081668","09390081668","91","09390081668","رحیم ","رعیت پیشه","1","0","IN_FIX_SCOPE" +"137","69","41","56000000","112000000","3/12/2025 09:49:45.92","09332726075","09332726075","121","09332726075","محمد","جعفری","1","0","IN_FIX_SCOPE" +"138","64","42","56000000","0","3/12/2025 09:49:45.92","09014638673","09014638673","116","09014638673","سالار","رضائی","3","1","IN_FIX_SCOPE" +"139","63","43","56000000","0","3/12/2025 09:49:45.92","09056365323","09056365323","115","09056365323","حامد","دهقانی","3","1","IN_FIX_SCOPE" +"140","67","44","56000000","0","3/12/2025 09:49:45.92","09126092994","09126092994","119","09126092994","علیرضا ","کریمی پیروز ","3","1","IN_FIX_SCOPE" +"141","61","45","56000000","0","3/12/2025 09:49:45.92","09177325630","09177325630","113","09177325630","کاوس","بیگ اینالو","3","1","IN_FIX_SCOPE" +"142","51","46","56000000","0","3/12/2025 09:49:45.92","09384366040","09384366040","103","09384366040","علی ","دلال زاده","3","1","IN_FIX_SCOPE" +"144","72","61","56000000","112000000","8/12/2025 12:30:53.536666","09120389056","09120389056","124","09120389056","محمدرضا ","باغجری","1","0","USER_NOT_IN_FIX_SCOPE" +"145","74","62","56000000","112000000","8/12/2025 12:30:53.536666","09191024013","09191024013","126","09191024013"," امیرعباس","میرزایی","1","0","USER_NOT_IN_FIX_SCOPE" +"146","86","63","56000000","112000000","8/12/2025 12:30:53.536666","09125032770","09125032770","138","09125032770","سیما","اکبرزاده","1","0","USER_NOT_IN_FIX_SCOPE" +"147","87","64","56000000","112000000","8/12/2025 12:30:53.536666","09102618416","09102618416","139","09102618416","مسعود","توسلیان","1","0","USER_NOT_IN_FIX_SCOPE" +"148","88","65","56000000","112000000","8/12/2025 12:30:53.536666","09121444951","09121444951","140","09121444951","سید سعید ","بزرگ نیا حسینی","1","0","USER_NOT_IN_FIX_SCOPE" +"149","89","66","56000000","112000000","8/12/2025 12:30:53.536666","09123233123","09123233123","141","09123233123","بهزاد","بابااصفهانی","1","0","USER_NOT_IN_FIX_SCOPE" +"174","91","87","56000000","0","19/12/2025 18:11:34.32","09358325024","09358325024","143","09358325024","مهدیه","زیبائی","1","0","USER_NOT_IN_FIX_SCOPE" +"352","130","146","56000000","112000000","22/2/2026 16:02:19.2219367","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"363","133","170","5600000","11200000","9/3/2026 10:34:00.2814919","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"365","136","173","5600000","11200000","15/3/2026 10:54:59.2500419","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"40387","39","40193","5600000","11200000","4/5/2026 21:55:45.9173742","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"40394","150","40202","5600000","11200000","7/5/2026 15:57:11.887558","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"40469","163","40269","56000000","112000000","25/5/2026 21:01:00.302016","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"40516","170","40293","5600000","11200000","1/6/2026 19:30:29.811968","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"40517","168","40294","5600000","11200000","1/6/2026 19:30:50.6897351","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"40524","172","40301","5600000","11200000","4/6/2026 15:21:57.0889467","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"40525","176","40302","5600000","11200000","5/6/2026 15:12:14.4460401","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"40526","174","40303","5600000","11200000","5/6/2026 15:12:31.6951342","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"40527","175","40304","5600000","11200000","5/6/2026 15:12:43.4902779","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"40552","183","40326","5600000","11200000","9/6/2026 20:31:28.0962845","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"40553","188","40327","5600000","11200000","9/6/2026 20:32:03.6166647","09199877503","09199877503","162","09199877503","مسعود","آفرین مقدم","3","0","IN_FIX_SCOPE" +"2","09387342688","رباب","مرجانی","3","12","121","0","1","0","19/12/2025 22:00:40.276666","0","09387342688","1","WH_NO_REF" +"2","09387342688","رباب","مرجانی","3","12","327","92","0","0","31/1/2026 10:20:55.9566667","SP","SP","0","WH_HAS_REF" +"2","09387342688","رباب","مرجانی","3","12","40654","154","0","0","27/6/2026 11:52:47.0866667","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","185","106","0","0","19/12/2025 21:05:21.956666","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","198","113","0","0","19/12/2025 22:00:40.276666","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","202","9","0","0","20/12/2025 09:56:37.616666","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","206","13","0","0","20/12/2025 10:30:49.186666","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","212","19","0","0","20/12/2025 10:31:12.52","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","223","30","0","0","20/12/2025 10:31:24.903333","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","230","37","0","0","20/12/2025 10:31:48.963333","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","233","40","0","0","20/12/2025 10:38:43.333333","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","239","46","0","0","20/12/2025 10:39:58.833333","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","250","57","0","0","20/12/2025 10:41:04.043333","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","257","64","0","0","20/12/2025 10:42:03.116666","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","286","78","0","0","28/12/2025 18:05:47.7766667","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","297","84","0","0","3/1/2026 09:05:11.38","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","313","88","0","0","15/1/2026 15:51:15.5433333","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","328","93","0","0","31/1/2026 10:20:55.9566667","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","40380","99","0","0","4/5/2026 21:49:21.8933333","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","40384","103","0","0","4/5/2026 21:51:42.8666667","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","40454","115","0","0","23/5/2026 21:18:37.59","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","40484","127","0","0","29/5/2026 18:46:36.1866667","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","40530","132","0","0","6/6/2026 13:35:49.2833333","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","40557","138","0","0","13/6/2026 13:03:08.3066667","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","40592","147","0","0","20/6/2026 06:08:53.4","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","40655","155","0","0","27/6/2026 11:52:47.0866667","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","90716","20177","0","0","25/7/2026 06:58:12.6766667","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","110825","30185","0","0","7/8/2026 22:33:52.54","SP","SP","0","WH_HAS_REF" +"7","09128676640","مهدی","صیفی","3","13","120888","30203","0","0","15/8/2026 05:48:36.46","SP","SP","0","WH_HAS_REF" +"8","09126612405","مهدی","صیفی","3","14","40385","104","0","0","4/5/2026 21:51:42.8666667","SP","SP","0","WH_HAS_REF" +"8","09126612405","مهدی","صیفی","3","14","40656","156","0","0","27/6/2026 11:52:47.0866667","SP","SP","0","WH_HAS_REF" +"8","09126612405","مهدی","صیفی","3","14","90717","20178","0","0","25/7/2026 06:58:12.6766667","SP","SP","0","WH_HAS_REF" +"9","09387095611","مهدی","مرجانی","3","15","186","107","0","0","19/12/2025 21:05:21.956666","SP","SP","0","WH_HAS_REF" +"9","09387095611","مهدی","مرجانی","3","15","213","20","0","0","20/12/2025 10:31:12.52","SP","SP","0","WH_HAS_REF" +"9","09387095611","مهدی","مرجانی","3","15","224","31","0","0","20/12/2025 10:31:24.903333","SP","SP","0","WH_HAS_REF" +"9","09387095611","مهدی","مرجانی","3","15","240","47","0","0","20/12/2025 10:39:58.833333","SP","SP","0","WH_HAS_REF" +"9","09387095611","مهدی","مرجانی","3","15","251","58","0","0","20/12/2025 10:41:04.043333","SP","SP","0","WH_HAS_REF" +"9","09387095611","مهدی","مرجانی","3","15","287","79","0","0","28/12/2025 18:05:47.7766667","SP","SP","0","WH_HAS_REF" +"9","09387095611","مهدی","مرجانی","3","15","329","94","0","0","31/1/2026 10:20:55.9566667","SP","SP","0","WH_HAS_REF" +"9","09387095611","مهدی","مرجانی","3","15","40386","105","0","0","4/5/2026 21:51:42.8666667","SP","SP","0","WH_HAS_REF" +"9","09387095611","مهدی","مرجانی","3","15","40398","106","0","0","10/5/2026 20:32:00.55","SP","SP","0","WH_HAS_REF" +"9","09387095611","مهدی","مرجانی","3","15","40455","116","0","0","23/5/2026 21:18:37.59","SP","SP","0","WH_HAS_REF" +"9","09387095611","مهدی","مرجانی","3","15","40485","128","0","0","29/5/2026 18:46:36.1866667","SP","SP","0","WH_HAS_REF" +"40","09124287588","مهدی","مرجانی","3","20","288","80","0","0","28/12/2025 18:05:47.7766667","SP","SP","0","WH_HAS_REF" +"40","09124287588","مهدی","مرجانی","3","20","330","95","0","0","31/1/2026 10:20:55.9566667","SP","SP","0","WH_HAS_REF" +"40","09124287588","مهدی","مرجانی","3","20","40482","125","0","0","29/5/2026 18:46:36.0866667","SP","SP","0","WH_HAS_REF" +"40","09124287588","مهدی","مرجانی","3","20","40531","133","0","0","6/6/2026 13:35:49.2833333","SP","SP","0","WH_HAS_REF" +"40","09124287588","مهدی","مرجانی","3","20","40558","139","0","0","13/6/2026 13:03:08.3066667","SP","SP","0","WH_HAS_REF" +"40","09124287588","مهدی","مرجانی","3","20","40657","157","0","0","27/6/2026 11:52:47.0866667","SP","SP","0","WH_HAS_REF" +"40","09124287588","مهدی","مرجانی","3","20","50671","164","0","0","5/7/2026 09:38:54.27","SP","SP","0","WH_HAS_REF" +"40","09124287588","مهدی","مرجانی","3","20","70686","20164","0","0","18/7/2026 06:15:56.3666667","SP","SP","0","WH_HAS_REF" +"40","09124287588","مهدی","مرجانی","3","20","100771","30177","0","0","3/8/2026 11:26:51.4","SP","SP","0","WH_HAS_REF" +"40","09124287588","مهدی","مرجانی","3","20","110826","30186","0","0","7/8/2026 22:33:52.54","SP","SP","0","WH_HAS_REF" +"40","09124287588","مهدی","مرجانی","3","20","120889","30204","0","0","15/8/2026 05:48:36.46","SP","SP","0","WH_HAS_REF" +"40","09124287588","مهدی","مرجانی","3","20","140905","40203","0","0","22/8/2026 09:15:24.6","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","107","29","56000000","0","19/11/2025 01:24:24",,,"1","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","176","97","0","0","19/12/2025 20:47:49.22","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","187","108","0","0","19/12/2025 21:05:21.956666","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","203","10","0","0","20/12/2025 09:56:37.616666","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","207","14","0","0","20/12/2025 10:30:49.186666","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","214","21","0","0","20/12/2025 10:31:12.52","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","225","32","0","0","20/12/2025 10:31:24.903333","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","234","41","0","0","20/12/2025 10:38:43.333333","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","241","48","0","0","20/12/2025 10:39:58.833333","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","252","59","0","0","20/12/2025 10:41:04.043333","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","289","81","0","0","28/12/2025 18:05:47.7766667","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","298","85","0","0","3/1/2026 09:05:11.38","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","314","89","0","0","15/1/2026 15:51:15.5433333","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","40421","40226","-8030000","0","14/5/2026 05:29:06.5412764","43","43","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","40422","40227","-7810000","0","14/5/2026 05:32:17.6846523","43","43","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","40423","40229","-3121800","0","14/5/2026 05:39:57.0293431","43","43","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","40424","40230","-3497440","0","14/5/2026 06:43:14.495774","43","43","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","60673","10164","0","0","11/7/2026 06:48:37.5","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","70687","20165","0","0","18/7/2026 06:15:56.3666667","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","100772","30178","0","0","3/8/2026 11:26:51.4","SP","SP","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","110810","110572","-2084900","0","6/8/2026 09:52:06.8511076","43","43","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","110811","110573","0","-98100","6/8/2026 09:55:13.7439233","43","43","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","110812","110573","0","-98100","6/8/2026 10:14:12.789987","43","43","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","110817","110573","0","-98100","6/8/2026 13:34:54.8426154","50282","50282","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","110846","110605","-913000","0","8/8/2026 15:21:48.1642179","43","43","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","110847","110606","-2702670","0","8/8/2026 15:29:25.4361709","43","43","0","WH_HAS_REF" +"43","09039033341","کریم","خادمی ","3","22","140906","40204","0","0","22/8/2026 09:15:24.6","SP","SP","0","WH_HAS_REF" +"45","09121150062","علی","دلال زاده","3","23","108","30","56000000","0","19/11/2025 01:24:24",,,"1","WH_HAS_REF" +"45","09121150062","علی","دلال زاده","3","23","153","51","-24690000","0","13/12/2025 01:20:08.176666","45","45","0","WH_HAS_REF" +"45","09121150062","علی","دلال زاده","3","23","177","98","0","0","19/12/2025 20:47:49.22","SP","SP","0","WH_HAS_REF" +"45","09121150062","علی","دلال زاده","3","23","188","109","0","0","19/12/2025 21:05:21.956666","SP","SP","0","WH_HAS_REF" +"45","09121150062","علی","دلال زاده","3","23","215","22","0","0","20/12/2025 10:31:12.52","SP","SP","0","WH_HAS_REF" +"45","09121150062","علی","دلال زاده","3","23","226","33","0","0","20/12/2025 10:31:24.903333","SP","SP","0","WH_HAS_REF" +"45","09121150062","علی","دلال زاده","3","23","242","49","0","0","20/12/2025 10:39:58.833333","SP","SP","0","WH_HAS_REF" +"45","09121150062","علی","دلال زاده","3","23","253","60","0","0","20/12/2025 10:41:04.043333","SP","SP","0","WH_HAS_REF" +"45","09121150062","علی","دلال زاده","3","23","264","97","-13449150","0","23/12/2025 17:41:19.995818","45","45","0","WH_HAS_REF" +"45","09121150062","علی","دلال زاده","3","23","40370","40179","-5222999","0","22/4/2026 09:39:04.6856636","45","45","0","WH_HAS_REF" +"45","09121150062","علی","دلال زاده","3","23","40411","40214","-2021987","0","11/5/2026 22:15:08.7121357","45","45","0","WH_HAS_REF" +"45","09121150062","علی","دلال زاده","3","23","100755","100519","-2247800","0","30/7/2026 11:32:50.7987614","45","45","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","106","28","56000000","0","19/11/2025 01:24:24",,,"1","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","171","84","-5353400","0","19/12/2025 10:08:54.173333","47","47","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","172","85","-1757500","0","19/12/2025 10:11:34.32","47","47","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","178","99","0","0","19/12/2025 20:47:49.22","SP","SP","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","189","110","0","0","19/12/2025 21:05:21.956666","SP","SP","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","204","11","0","0","20/12/2025 09:56:37.616666","SP","SP","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","208","15","0","0","20/12/2025 10:30:49.186666","SP","SP","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","216","23","0","0","20/12/2025 10:31:12.52","SP","SP","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","227","34","0","0","20/12/2025 10:31:24.903333","SP","SP","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","235","42","0","0","20/12/2025 10:38:43.333333","SP","SP","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","243","50","0","0","20/12/2025 10:39:58.833333","SP","SP","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","254","61","0","0","20/12/2025 10:41:04.043333","SP","SP","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","271","104","-2857800","0","26/12/2025 06:35:54.4469592","47","47","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","272","105","-924000","0","26/12/2025 06:38:49.1560479","47","47","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","307","116","-774400","0","5/1/2026 09:41:18.2212775","47","47","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","358","163","-8030000","0","24/2/2026 12:31:23.560765","47","47","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","40397","40205","-3380600","0","10/5/2026 13:59:49.4056935","47","47","0","WH_HAS_REF" +"47","09123122544","صدیقه","منعمیان","3","24","40500","40275","-165000","0","31/5/2026 08:38:01.8954219","47","47","0","WH_HAS_REF" +"52","09178327020","حمیدرضا ","اسمعیلی ","3","26","122","31","56000000","0","27/11/2025 01:24:24",,,"1","WH_HAS_REF" +"58","09362102420","وحید","حق گو","1","8","115","7","56000000","112000000","19/11/2025 01:24:24",,,"0","WH_HAS_REF" +"69","09217672935","مهدی ","گیوی ","3","32","119","0","1","0","19/11/2025 01:24:24","58","09217672935","1","WH_NO_REF" +"69","09217672935","مهدی ","گیوی ","3","32","209","0","0","0","20/12/2025 10:30:49.186666","16","SP","0","WH_NO_REF" +"69","09217672935","مهدی ","گیوی ","3","32","236","0","0","0","20/12/2025 10:38:43.333333","43","SP","0","WH_NO_REF" +"69","09217672935","مهدی ","گیوی ","3","32","40430","111","0","0","16/5/2026 18:45:37.26","SP","SP","0","WH_HAS_REF" +"71","09015793338","حمیدرضا","مرجانی","3","34","118","0","1","0","3/12/2025 09:49:45.92","56","09015793338","1","WH_NO_REF" +"71","09015793338","حمیدرضا","مرجانی","3","34","218","0","0","0","20/12/2025 10:31:12.52","25","SP","0","WH_NO_REF" +"71","09015793338","حمیدرضا","مرجانی","3","34","245","0","0","0","20/12/2025 10:39:58.833333","52","SP","0","WH_NO_REF" +"71","09015793338","حمیدرضا","مرجانی","3","34","40399","107","0","0","10/5/2026 20:32:00.55","SP","SP","0","WH_HAS_REF" +"71","09015793338","حمیدرضا","مرجانی","3","34","40555","40329","-165000","0","12/6/2026 09:48:16.6573626","71","71","0","WH_HAS_REF" +"71","09015793338","حمیدرضا","مرجانی","3","34","110827","30187","0","0","7/8/2026 22:33:52.54","SP","SP","0","WH_HAS_REF" +"72","09124678697","مژگان","گیوی","3","35","124","0","1","0","19/11/2025 01:24:24","57","09961354257","1","WH_NO_REF" +"74","09101692049","سجاد ","اداوی","3","37","120","0","1","0","19/11/2025 01:24:24","59","09101692049","1","WH_NO_REF" +"74","09101692049","سجاد ","اداوی","3","37","219","0","0","0","20/12/2025 10:31:12.52","26","SP","0","WH_NO_REF" +"74","09101692049","سجاد ","اداوی","3","37","246","0","0","0","20/12/2025 10:39:58.833333","53","SP","0","WH_NO_REF" +"74","09101692049","سجاد ","اداوی","3","37","40381","100","0","0","4/5/2026 21:49:21.8933333","SP","SP","0","WH_HAS_REF" +"74","09101692049","سجاد ","اداوی","3","37","40382","101","0","0","4/5/2026 21:51:01.7466667","SP","SP","0","WH_HAS_REF" +"74","09101692049","سجاد ","اداوی","3","37","40383","102","0","0","4/5/2026 21:51:20.3866667","SP","SP","0","WH_HAS_REF" +"74","09101692049","سجاد ","اداوی","3","37","40431","112","0","0","16/5/2026 18:45:37.26","SP","SP","0","WH_HAS_REF" +"74","09101692049","سجاد ","اداوی","3","37","40532","134","0","0","6/6/2026 13:35:49.2833333","SP","SP","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","102","23","56000000","0","19/11/2025 01:24:24",,,"1","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","199","114","0","0","19/12/2025 22:00:40.276666","SP","SP","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","205","12","0","0","20/12/2025 09:56:37.616666","SP","SP","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","210","17","0","0","20/12/2025 10:30:49.186666","SP","SP","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","231","38","0","0","20/12/2025 10:31:48.963333","SP","SP","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","237","44","0","0","20/12/2025 10:38:43.333333","SP","SP","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","258","65","0","0","20/12/2025 10:42:03.116666","SP","SP","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","299","86","0","0","3/1/2026 09:05:11.38","SP","SP","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","340","134","-7810000","0","12/2/2026 18:59:26.4359166","75","75","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","341","135","-13585000","0","13/2/2026 11:43:52.8147951","75","75","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","342","136","-7810000","0","13/2/2026 18:03:25.0356764","75","75","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","344","138","-8030000","0","15/2/2026 14:16:41.8568639","75","75","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","346","140","-4600200","0","16/2/2026 09:15:32.9394144","75","75","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","40369","40178","-7810000","0","21/4/2026 15:25:58.0230953","75","75","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","40400","108","0","0","10/5/2026 20:32:00.55","SP","SP","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","40406","40209","-825200","0","11/5/2026 13:43:42.9497941","75","75","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","40407","40210","-1865974","0","11/5/2026 13:48:07.5718054","75","75","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","40518","40295","-3630000","0","2/6/2026 11:47:15.7293433","75","75","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","40559","140","0","0","13/6/2026 13:03:08.3066667","SP","SP","0","WH_HAS_REF" +"75","09353851578","پویا","عبدی ","3","38","120890","30205","0","0","15/8/2026 05:48:36.46","SP","SP","0","WH_HAS_REF" +"87","09020569440","امیررضا","محمدی","1","9","116","8","56000000","112000000","19/11/2025 01:24:24",,,"0","WH_HAS_REF" +"87","09020569440","امیررضا","محمدی","1","9","182","103","0","0","19/12/2025 20:47:49.22","SP","SP","0","WH_HAS_REF" +"87","09020569440","امیررضا","محمدی","1","9","220","27","0","0","20/12/2025 10:31:12.52","SP","SP","0","WH_HAS_REF" +"87","09020569440","امیررضا","محمدی","1","9","247","54","0","0","20/12/2025 10:39:58.833333","SP","SP","0","WH_HAS_REF" +"88","09172606097","کریم","رعیت پیشه","1","42","125","53","56000000","112000000","3/12/2025 09:49:45.92","09172606097","09172606097","0","WH_HAS_REF" +"88","09172606097","کریم","رعیت پیشه","1","42","183","104","0","0","19/12/2025 20:47:49.22","SP","SP","0","WH_HAS_REF" +"88","09172606097","کریم","رعیت پیشه","1","42","221","28","0","0","20/12/2025 10:31:12.52","SP","SP","0","WH_HAS_REF" +"88","09172606097","کریم","رعیت پیشه","1","42","248","55","0","0","20/12/2025 10:39:58.833333","SP","SP","0","WH_HAS_REF" +"89","09171237952","نورالله","هاشمی ","1","10","117","9","56000000","112000000","19/11/2025 01:24:24",,,"0","WH_HAS_REF" +"89","09171237952","نورالله","هاشمی ","1","10","336","130","-44675600","0","10/2/2026 14:35:23.1658124","89","89","0","WH_HAS_REF" +"89","09171237952","نورالله","هاشمی ","1","10","339","133","-875000","0","10/2/2026 22:07:11.6883998","89","89","0","WH_HAS_REF" +"90","09174337813","علیرضا ","پولادی","1","43","127","55","56000000","112000000","3/12/2025 09:49:45.92","09174337813","09174337813","0","WH_HAS_REF" +"90","09174337813","علیرضا ","پولادی","1","43","10367","10176","-21760076","0","31/3/2026 19:42:52.3320407","90","90","0","WH_HAS_REF" +"90","09174337813","علیرضا ","پولادی","1","43","60688","60442","-33815504","0","13/7/2026 20:26:12.8880784","90","90","0","WH_HAS_REF" +"91","09390081668","رحیم ","رعیت پیشه","1","44","136","40","56000000","112000000","3/12/2025 09:49:45.92","09390081668","09390081668","0","WH_HAS_REF" +"93","09122156286","ریحانه سادات ","هاشمی نصر ","3","46","103","24","56000000","0","19/11/2025 01:24:24",,,"1","WH_HAS_REF" +"93","09122156286","ریحانه سادات ","هاشمی نصر ","3","46","40579","40339","-47047000","0","15/6/2026 09:29:00.5576873","93","93","0","WH_HAS_REF" +"93","09122156286","ریحانه سادات ","هاشمی نصر ","3","46","40580","40340","-7084000","0","15/6/2026 16:07:15.3974267","93","93","0","WH_HAS_REF" +"93","09122156286","ریحانه سادات ","هاشمی نصر ","3","46","40628","40389","-1532749","0","21/6/2026 12:13:01.1948474","93","93","0","WH_HAS_REF" +"93","09122156286","ریحانه سادات ","هاشمی نصر ","3","46","40629","40390","-336050","0","21/6/2026 12:15:06.3540102","93","93","0","WH_HAS_REF" +"96","09125020729","غلامرضا ","عبدی ","3","47","104","25","56000000","0","19/11/2025 01:24:24",,,"1","WH_HAS_REF" +"96","09125020729","غلامرضا ","عبدی ","3","47","165","78","-13585000","0","18/12/2025 15:28:38.216666","96","96","0","WH_HAS_REF" +"96","09125020729","غلامرضا ","عبدی ","3","47","167","80","-13585000","0","18/12/2025 15:31:34.153333","96","96","0","WH_HAS_REF" +"96","09125020729","غلامرضا ","عبدی ","3","47","169","82","-13585000","0","18/12/2025 15:35:01.376666","96","96","0","WH_HAS_REF" +"96","09125020729","غلامرضا ","عبدی ","3","47","170","83","-13585000","0","18/12/2025 15:36:41.913333","96","96","0","WH_HAS_REF" +"96","09125020729","غلامرضا ","عبدی ","3","47","306","115","-1403000","0","5/1/2026 09:33:31.2176626","96","96","0","WH_HAS_REF" +"96","09125020729","غلامرضا ","عبدی ","3","47","40409","40212","-165000","0","11/5/2026 16:21:57.7690801","96","96","0","WH_HAS_REF" +"99","09106519822","هستی","خادمی","3","49","105","26","56000000","0","19/11/2025 01:24:24",,,"1","WH_HAS_REF" +"103","09384366040","علی ","دلال زاده","3","51","142","46","56000000","0","3/12/2025 09:49:45.92","09384366040","09384366040","1","WH_HAS_REF" +"103","09384366040","علی ","دلال زاده","3","51","20368","20177","-56000000","0","3/4/2026 14:14:43.1146196","103","103","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","40483","126","0","0","29/5/2026 18:46:36.0866667","SP","SP","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","40486","129","0","0","29/5/2026 18:46:36.1866667","SP","SP","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","40511","40288","-22399999","0","1/6/2026 10:34:09.2649307","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","40513","40290","-5270100","0","1/6/2026 10:39:29.0610185","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","40658","158","0","0","27/6/2026 11:52:47.0866667","SP","SP","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","50672","165","0","0","5/7/2026 09:38:54.27","SP","SP","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","70688","20166","0","0","18/7/2026 06:15:56.3666667","SP","SP","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","70704","70452","2500000","0","19/7/2026 15:06:29.9828496","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","110829","30189","0","0","7/8/2026 22:33:52.54","SP","SP","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","110884","110650","-5307351","0","11/8/2026 11:26:39.2456538","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","110885","110651","100000000","0","11/8/2026 13:22:21.9329329","162","162","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","120891","30206","0","0","15/8/2026 05:48:36.46","SP","SP","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","130884","130651","-1596001","0","17/8/2026 07:35:38.158927","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","130885","110279","1596001","0","17/8/2026 07:37:37.1659725","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","130886","130652","-1596001","0","17/8/2026 07:38:51.0009125","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","130908","130676","-1562000","0","19/8/2026 06:44:00.2389859","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","130912","130682","-4389361","0","20/8/2026 04:58:46.4329118","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","130913","130683","-4398796","0","20/8/2026 05:01:45.1576458","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","130914","110293","4389361","0","20/8/2026 05:02:55.1041528","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","130915","130684","-4468561","0","20/8/2026 05:19:39.1097062","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","140904","140673","-1610400","0","22/8/2026 06:56:21.7082457","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","140939","140698","-959200","0","24/8/2026 13:27:48.539407","106","106","0","WH_HAS_REF" +"106","09122302660","مهرداد","شجاعی","3","54","140945","140706","-9458500","0","24/8/2026 20:30:02.7379001","106","106","0","WH_HAS_REF" +"111","09352828086","انسیه","توسلیان","1","59","129","33","56000000","112000000","3/12/2025 09:49:45.92",,,"0","WH_HAS_REF" +"111","09352828086","انسیه","توسلیان","1","59","191","112","0","0","19/12/2025 21:05:21.956666","SP","SP","0","WH_HAS_REF" +"111","09352828086","انسیه","توسلیان","1","59","229","36","0","0","20/12/2025 10:31:24.903333","SP","SP","0","WH_HAS_REF" +"111","09352828086","انسیه","توسلیان","1","59","256","63","0","0","20/12/2025 10:41:04.043333","SP","SP","0","WH_HAS_REF" +"111","09352828086","انسیه","توسلیان","1","59","361","166","-28250200","0","27/2/2026 07:07:04.5068205","111","111","0","WH_HAS_REF" +"111","09352828086","انسیه","توسلیان","1","59","40401","109","0","0","10/5/2026 20:32:00.55","SP","SP","0","WH_HAS_REF" +"111","09352828086","انسیه","توسلیان","1","59","40487","130","0","0","29/5/2026 18:46:36.1866667","SP","SP","0","WH_HAS_REF" +"113","09177325630","کاوس","بیگ اینالو","3","61","141","45","56000000","0","3/12/2025 09:49:45.92","09177325630","09177325630","1","WH_HAS_REF" +"113","09177325630","کاوس","بیگ اینالو","3","61","200","115","0","0","19/12/2025 22:00:40.276666","SP","SP","0","WH_HAS_REF" +"113","09177325630","کاوس","بیگ اینالو","3","61","232","39","0","0","20/12/2025 10:31:48.963333","SP","SP","0","WH_HAS_REF" +"113","09177325630","کاوس","بیگ اینالو","3","61","259","66","0","0","20/12/2025 10:42:03.116666","SP","SP","0","WH_HAS_REF" +"115","09056365323","حامد","دهقانی","3","63","139","43","56000000","0","3/12/2025 09:49:45.92","09056365323","09056365323","1","WH_HAS_REF" +"115","09056365323","حامد","دهقانی","3","63","168","81","-13585000","0","18/12/2025 15:32:59.06","115","115","0","WH_HAS_REF" +"115","09056365323","حامد","دهقانی","3","63","40410","40213","-42295000","0","11/5/2026 16:54:10.9533071","115","115","0","WH_HAS_REF" +"115","09056365323","حامد","دهقانی","3","63","40522","40299","0","45000","3/6/2026 09:59:49.8074331",,,"0","WH_HAS_REF" +"115","09056365323","حامد","دهقانی","3","63","120892","30207","0","0","15/8/2026 05:48:36.46","SP","SP","0","WH_HAS_REF" +"116","09014638673","سالار","رضائی","3","64","138","42","56000000","0","3/12/2025 09:49:45.92","09014638673","09014638673","1","WH_HAS_REF" +"116","09014638673","سالار","رضائی","3","64","296","111","-13585000","0","1/1/2026 22:05:44.3947747","116","116","0","WH_HAS_REF" +"116","09014638673","سالار","رضائی","3","64","351","145","-21418500","0","20/2/2026 09:00:54.7167888","116","116","0","WH_HAS_REF" +"116","09014638673","سالار","رضائی","3","64","356","155","-4600200","0","23/2/2026 09:56:49.6353806","116","116","0","WH_HAS_REF" +"116","09014638673","سالار","رضائی","3","64","40376","40189","-8250000","0","28/4/2026 10:36:23.4852403","116","116","0","WH_HAS_REF" +"119","09126092994","علیرضا ","کریمی پیروز ","3","67","140","44","56000000","0","3/12/2025 09:49:45.92","09126092994","09126092994","1","WH_HAS_REF" +"119","09126092994","علیرضا ","کریمی پیروز ","3","67","100751","100515","-13068000","0","30/7/2026 11:01:44.0341615","119","119","0","WH_HAS_REF" +"119","09126092994","علیرضا ","کریمی پیروز ","3","67","100752","100516","-21725401","0","30/7/2026 11:15:29.2485564","119","119","0","WH_HAS_REF" +"119","09126092994","علیرضا ","کریمی پیروز ","3","67","100754","100518","-12947000","0","30/7/2026 11:30:36.0769629","119","119","0","WH_HAS_REF" +"119","09126092994","علیرضا ","کریمی پیروز ","3","67","100757","100521","-7805504","0","30/7/2026 11:42:40.6883097","119","119","0","WH_HAS_REF" +"119","09126092994","علیرضا ","کریمی پیروز ","3","67","100758","100522","143705","0","30/7/2026 11:47:05.028365","119","119","0","WH_HAS_REF" +"119","09126092994","علیرضا ","کریمی پیروز ","3","67","100759","100523","-597800","0","30/7/2026 11:47:13.2421718","119","119","0","WH_HAS_REF" +"121","09332726075","محمد","جعفری","1","69","137","41","56000000","112000000","3/12/2025 09:49:45.92","09332726075","09332726075","0","WH_HAS_REF" +"121","09332726075","محمد","جعفری","1","69","360","165","-55899863","0","25/2/2026 15:47:25.4690474","121","121","0","WH_HAS_REF" +"125","09126302293","محمود","دادگرکریمی","1","73","134","38","56000000","112000000","3/12/2025 09:49:45.92","09126302293","09126302293","0","WH_HAS_REF" +"125","09126302293","محمود","دادگرکریمی","1","73","348","142","-7739000","0","18/2/2026 17:02:54.3278655","125","125","0","WH_HAS_REF" +"125","09126302293","محمود","دادگرکریمی","1","73","40519","40296","-47080000","0","2/6/2026 12:04:37.0376162","125","125","0","WH_HAS_REF" +"125","09126302293","محمود","دادگرکریمی","1","73","40520","40297","-1155000","0","2/6/2026 12:11:18.8475273","125","125","0","WH_HAS_REF" +"130","09368743289","مهرداد","شجاعی","3","78","40659","159","0","0","27/6/2026 11:52:47.0866667","SP","SP","0","WH_HAS_REF" +"130","09368743289","مهرداد","شجاعی","3","78","70689","20167","0","0","18/7/2026 06:15:56.3666667","SP","SP","0","WH_HAS_REF" +"162","09199877503","مسعود","آفرین مقدم","3","110","201","0","1","112000000","20/12/2025 02:24:42.771904","92","162","1","WH_NO_REF" +"162","09199877503","مسعود","آفرین مقدم","3","110","362","167","-96800","0","28/2/2026 02:16:53.1467394","162","162","0","WH_HAS_REF" +"162","09199877503","مسعود","آفرین مقدم","3","110","40651","40415","10000","0","26/6/2026 18:12:30.3695252","162","162","0","WH_HAS_REF" +"169","09122583411","مهرداد","شجاعی","3","117","40458","119","0","0","23/5/2026 21:18:37.59","SP","SP","0","WH_HAS_REF" +"169","09122583411","مهرداد","شجاعی","3","117","40561","142","0","0","13/6/2026 13:03:08.3066667","SP","SP","0","WH_HAS_REF" +"169","09122583411","مهرداد","شجاعی","3","117","140907","40205","0","0","22/8/2026 09:15:24.6","SP","SP","0","WH_HAS_REF" +"170","09120991323","لیلا","خدارحمی دره میانه","3","118","292","107","56000000","112000000","30/12/2025 01:24:24","SP","SP","1","WH_HAS_REF" +"171","09375724408","مژده","بنی هاشمی","3","119","293","108","56000000","112000000","31/12/2025 01:24:24","SP","SP","1","WH_HAS_REF" +"171","09375724408","مژده","بنی هاشمی","3","119","300","87","0","0","3/1/2026 09:05:11.38","SP","SP","0","WH_HAS_REF" +"171","09375724408","مژده","بنی هاشمی","3","119","308","117","-13585000","0","8/1/2026 08:46:14.5070996","171","171","0","WH_HAS_REF" +"171","09375724408","مژده","بنی هاشمی","3","119","40403","40206","-28121199","0","11/5/2026 11:24:40.3004634","171","171","0","WH_HAS_REF" +"171","09375724408","مژده","بنی هاشمی","3","119","40404","40207","-660000","0","11/5/2026 12:08:37.0557993","171","171","0","WH_HAS_REF" +"172","09121355832","مهرافشان","زاهدنیا","3","120","294","109","56000000","112000000","31/12/2025 01:24:24","SP","SP","1","WH_HAS_REF" +"172","09121355832","مهرافشان","زاهدنیا","3","120","40434","40235","-56000000","0","17/5/2026 06:24:52.3451604","172","172","0","WH_HAS_REF" +"175","09122332219","ناهید ","حسن زاده مژدهی","3","123","295","110","56000000","112000000","1/1/2026 17:07:53.2301978","SP","SP","1","WH_HAS_REF" +"175","09122332219","ناهید ","حسن زاده مژدهی","3","123","40405","40208","-56000000","0","11/5/2026 13:21:51.1259865","175","175","0","WH_HAS_REF" +"2","09387342688","رباب","مرجانی","3","3","1","1","40654","154","1","154","0",,"0",,"1","0",,"1",,"WH_REF_BROKEN_NEED_CREATE_TX","Create missing Transaction; link WH+UPP" +"10","09109394124","مهدی","صیفی","3","1","1","0",,,"0",,"0",,"0",,"1","0",,"1",,"WH_REF_BROKEN_NEED_CREATE_TX","Create missing Transaction; link WH+UPP" +"11","09303303391","مهدی","مرجانی","3","1","1","0",,,"0",,"0",,"0",,"1","0",,"1",,"WH_REF_BROKEN_NEED_CREATE_TX","Create missing Transaction; link WH+UPP" +"12","09333773152","مهدی","مرجانی","3","1","1","0",,,"0",,"0",,"0",,"1","0",,"1",,"WH_REF_BROKEN_NEED_CREATE_TX","Create missing Transaction; link WH+UPP" +"13","09382734852","مهدی","مرجانی","3","1","1","0",,,"0",,"0",,"0",,"1","0",,"1",,"WH_REF_BROKEN_NEED_CREATE_TX","Create missing Transaction; link WH+UPP" +"41","09124287589","مهدی","مرجانی","3","1","1","0",,,"0",,"0",,"0",,"1","0",,"1",,"WH_REF_BROKEN_NEED_CREATE_TX","Create missing Transaction; link WH+UPP" +"69","09217672935","مهدی ","گیوی ","3","4","3","1","40430","111","1","111","1","58","3","58","1","0",,"1",,"WH_REF_BROKEN_TX_EXISTS_FIX_LINK","Link WH.RefrenceId to Tx from CreatedBy hint; ensure UPP" +"71","09015793338","حمیدرضا","مرجانی","3","6","3","1","110827","40329","2","40329","1","56","3","56","1","0",,"1",,"WH_REF_BROKEN_TX_EXISTS_FIX_LINK","Link WH.RefrenceId to Tx from CreatedBy hint; ensure UPP" +"72","09124678697","مژگان","گیوی","3","1","1","1","124","0","0",,"0",,"1","57","1","0",,"1",,"WH_REF_BROKEN_TX_EXISTS_FIX_LINK","Link WH.RefrenceId to Tx from CreatedBy hint; ensure UPP" +"74","09101692049","سجاد ","اداوی","3","8","3","1","40532","134","5","134","1","59","3","59","1","0",,"1",,"WH_REF_BROKEN_TX_EXISTS_FIX_LINK","Link WH.RefrenceId to Tx from CreatedBy hint; ensure UPP" +"105","09382302660","مهرداد","شجاعی","3","1","1","0",,,"0",,"0",,"0",,"1","0",,"1",,"WH_REF_BROKEN_NEED_CREATE_TX","Create missing Transaction; link WH+UPP" +"142","09399172812","صغری","شبانکاره ","3","1","1","0",,,"0",,"1","68","0",,"1","0",,"1",,"WH_REF_BROKEN_TX_BY_MOBILE_FIX_LINK","Link WH.RefrenceId to Tx found by mobile; ensure UPP" +"162","09199877503","مسعود","آفرین مقدم","3","3","1","1","40651","40415","2","40415","14","40327","0",,"1","0",,"1",,"WH_REF_BROKEN_TX_BY_MOBILE_FIX_LINK","Link WH.RefrenceId to Tx found by mobile; ensure UPP" +"176","09214456946","مهریدخت ","میکانیکی","3","1","1","0",,,"0",,"0",,"0",,"1","0",,"1",,"WH_REF_BROKEN_NEED_CREATE_TX","Create missing Transaction; link WH+UPP" +"7","09128676640","مهدی","صیفی","3","26","0","0","120888","30203","23","20177","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"8","09126612405","مهدی","صیفی","3","3","0","0","90717","20178","2","156","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"9","09387095611","مهدی","مرجانی","3","11","0","0","40485","128","10","128","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"40","09124287588","مهدی","مرجانی","3","12","0","0","140905","40203","9","40203","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"43","09039033341","کریم","خادمی ","3","27","0","1","140906","110606","21","110606","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"45","09121150062","علی","دلال زاده","3","12","0","1","100755","100519","12","100519","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"47","09123122544","صدیقه","منعمیان","3","18","0","1","40500","40275","17","40275","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"52","09178327020","حمیدرضا ","اسمعیلی ","3","1","0","1","122","31","1","31","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"58","09362102420","وحید","حق گو","1","1","0","0","115","7","1","7","0",,"0",,"1","0",,"1",,"OK_WH+TX","Fix PurchaseMethod 1→3 only" +"75","09353851578","پویا","عبدی ","3","20","0","1","120890","40295","17","40295","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"87","09020569440","امیررضا","محمدی","1","4","0","0","247","103","4","103","0",,"0",,"1","0",,"1",,"OK_WH+TX","Fix PurchaseMethod 1→3 only" +"88","09172606097","کریم","رعیت پیشه","1","4","0","0","248","104","4","104","1","53","0",,"1","0",,"1",,"OK_WH+TX","Fix PurchaseMethod 1→3 only" +"89","09171237952","نورالله","هاشمی ","1","3","0","0","339","133","3","133","0",,"0",,"1","0",,"1",,"OK_WH+TX","Fix PurchaseMethod 1→3 only" +"90","09174337813","علیرضا ","پولادی","1","3","0","0","60688","60442","3","60442","1","55","0",,"1","0",,"1",,"OK_WH+TX","Fix PurchaseMethod 1→3 only" +"91","09390081668","رحیم ","رعیت پیشه","1","1","0","0","136","40","1","40","1","40","0",,"1","0",,"1",,"OK_WH+TX","Fix PurchaseMethod 1→3 only" +"93","09122156286","ریحانه سادات ","هاشمی نصر ","3","5","0","1","40629","40390","5","40390","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"96","09125020729","غلامرضا ","عبدی ","3","7","0","1","40409","40212","7","40212","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"99","09106519822","هستی","خادمی","3","1","0","1","105","26","1","26","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"103","09384366040","علی ","دلال زاده","3","2","0","1","20368","20177","2","20177","1","46","0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"106","09122302660","مهرداد","شجاعی","3","23","0","0","140945","140706","18","140706","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"111","09352828086","انسیه","توسلیان","1","7","0","0","40487","166","7","166","0",,"0",,"1","0",,"1",,"OK_WH+TX","Fix PurchaseMethod 1→3 only" +"113","09177325630","کاوس","بیگ اینالو","3","4","0","1","259","115","4","115","1","45","0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"115","09056365323","حامد","دهقانی","3","5","0","1","120892","40299","4","40299","1","43","0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"116","09014638673","سالار","رضائی","3","5","0","1","40376","40189","5","40189","1","42","0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"119","09126092994","علیرضا ","کریمی پیروز ","3","7","0","1","100759","100523","7","100523","1","44","0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"121","09332726075","محمد","جعفری","1","2","0","0","360","165","2","165","1","41","0",,"1","0",,"1",,"OK_WH+TX","Fix PurchaseMethod 1→3 only" +"125","09126302293","محمود","دادگرکریمی","1","4","0","0","40520","40297","4","40297","1","38","0",,"1","0",,"1",,"OK_WH+TX","Fix PurchaseMethod 1→3 only" +"130","09368743289","مهرداد","شجاعی","3","2","0","0","70689","20167","1","159","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"169","09122583411","مهرداد","شجاعی","3","3","0","0","140907","40205","3","40205","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"170","09120991323","لیلا","خدارحمی دره میانه","3","1","0","1","292","107","1","107","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"171","09375724408","مژده","بنی هاشمی","3","5","0","1","40404","40207","4","40207","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"172","09121355832","مهرافشان","زاهدنیا","3","2","0","1","40434","40235","2","40235","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"175","09122332219","ناهید ","حسن زاده مژدهی","3","2","0","1","40405","40208","2","40208","0",,"0",,"1","0",,"1",,"OK_WH+TX","Likely OK — verify PurchaseMethod" +"HAS_WH+TX_NEED_UPP","33" +"NO_WALLET_HISTORY","8" +"WH_REF_BROKEN_TX_EXISTS_FIX_LINK","4" +"WH_REF_BROKEN_NEED_CREATE_TX","1" +"WH_REF_BROKEN_TX_BY_MOBILE_FIX_LINK","1" +"23","EXISTS","56000000","اعتبار دایا","manualy24",,,,,"102","38","23",, +"23","EXISTS","56000000","اعتبار دایا","manualy24",,,,,"216","24","23",, +"24","EXISTS","56000000","اعتبار دایا","manualy25",,,,,"103","46","24",, +"24","EXISTS","56000000","اعتبار دایا","manualy25",,,,,"217","6","24",, +"25","EXISTS","56000000","اعتبار دایا","manualy26",,,,,"104","47","25",, +"26","EXISTS","56000000","اعتبار دایا","manualy27",,,,,"105","49","26",, +"28","EXISTS","56000000","اعتبار دایا","manualy29",,,,,"106","24","28",, +"28","EXISTS","56000000","اعتبار دایا","manualy29",,,,,"221","42","28",, +"29","EXISTS","56000000","اعتبار دایا","manualy30",,,,,"107","22","29",, +"29","EXISTS","56000000","اعتبار دایا","manualy30",,,,,"222","62","29",, +"30","EXISTS","56000000","اعتبار دایا","manualy31",,,,,"108","23","30",, +"30","EXISTS","56000000","اعتبار دایا","manualy31",,,,,"223","13","30",, +"31","EXISTS","56000000","اعتبار دایا","manualy32",,,,,"122","26","31",, +"31","EXISTS","56000000","اعتبار دایا","manualy32",,,,,"224","15","31",, +"42","EXISTS","56000000","اعتبار دایا","manualy43","09014638673","09014638673","116","09014638673","138","64","42",, +"42","EXISTS","56000000","اعتبار دایا","manualy43","09014638673","09014638673","116","09014638673","235","24","42",, +"43","EXISTS","56000000","اعتبار دایا","manualy44","09056365323","09056365323","115","09056365323","139","63","43",, +"44","EXISTS","56000000","اعتبار دایا","manualy45","09126092994","09126092994","119","09126092994","140","67","44",, +"44","EXISTS","56000000","اعتبار دایا","manualy45","09126092994","09126092994","119","09126092994","237","38","44",, +"45","EXISTS","56000000","اعتبار دایا","manualy46","09177325630","09177325630","113","09177325630","141","61","45",, +"45","EXISTS","56000000","اعتبار دایا","manualy46","09177325630","09177325630","113","09177325630","238","6","45",, +"46","EXISTS","56000000","اعتبار دایا","manualy47","09384366040","09384366040","103","09384366040","142","51","46",, +"46","EXISTS","56000000","اعتبار دایا","manualy47","09384366040","09384366040","103","09384366040","239","13","46",, +"56","EXISTS","56000000","اعتبار دایا","manualy57","09015793338","09015793338","71","09015793338","249","62","56",, +"57","EXISTS","56000000","اعتبار دایا","manualy58","09961354257","09961354257",,,"250","13","57",, +"58","EXISTS","56000000","اعتبار دایا","manualy59","09217672935","09217672935","69","09217672935","251","15","58",, +"59","EXISTS","56000000","اعتبار دایا","manualy60","09101692049","09101692049","74","09101692049","252","22","59",, +"68","EXISTS","56000000","اعتبار دایا","manualy69","09399172812","09399172812","142","09399172812",,,,, +"107","EXISTS","56000000","اعتبار پرداخت مستقیم","manualy292",,,,,"186","15","107",, +"107","EXISTS","56000000","اعتبار پرداخت مستقیم","manualy292",,,,,"292","118","107",, +"107","EXISTS","56000000","اعتبار پرداخت مستقیم","manualy292",,,,,"40399","34","107",, +"108","EXISTS","56000000","اعتبار پرداخت مستقیم","manualy293",,,,,"187","22","108",, +"108","EXISTS","56000000","اعتبار پرداخت مستقیم","manualy293",,,,,"293","119","108",, +"108","EXISTS","56000000","اعتبار پرداخت مستقیم","manualy293",,,,,"40400","38","108",, +"109","EXISTS","56000000","اعتبار پرداخت مستقیم","manualy294",,,,,"188","23","109",, +"109","EXISTS","56000000","اعتبار پرداخت مستقیم","manualy294",,,,,"294","120","109",, +"109","EXISTS","56000000","اعتبار پرداخت مستقیم","manualy294",,,,,"40401","59","109",, +"110","EXISTS","56000000","اعتبار پرداخت مستقیم","manualy295",,,,,"189","24","110",, +"110","EXISTS","56000000","اعتبار پرداخت مستقیم","manualy295",,,,,"295","123","110",, +"110","EXISTS","56000000","اعتبار پرداخت مستقیم","manualy295",,,,,"40402","134","110",, +"102","38","23","56000000",,,"75","09353851578",,,"23","اعتبار دایا",,,"WH_LINKED_TO_TX" +"103","46","24","56000000",,,"93","09122156286",,,"24","اعتبار دایا",,,"WH_LINKED_TO_TX" +"104","47","25","56000000",,,"96","09125020729",,,"25","اعتبار دایا",,,"WH_LINKED_TO_TX" +"105","49","26","56000000",,,"99","09106519822",,,"26","اعتبار دایا",,,"WH_LINKED_TO_TX" +"106","24","28","56000000",,,"47","09123122544",,,"28","اعتبار دایا",,,"WH_LINKED_TO_TX" +"107","22","29","56000000",,,"43","09039033341",,,"29","اعتبار دایا",,,"WH_LINKED_TO_TX" +"108","23","30","56000000",,,"45","09121150062",,,"30","اعتبار دایا",,,"WH_LINKED_TO_TX" +"118","34","0","1","56","09015793338","71","09015793338","71","09015793338",,,"56","اعتبار دایا","WH_REF_BROKEN_USE_CREATEDBY_HINT" +"119","32","0","1","58","09217672935","69","09217672935","69","09217672935",,,"58","اعتبار دایا","WH_REF_BROKEN_USE_CREATEDBY_HINT" +"120","37","0","1","59","09101692049","74","09101692049","74","09101692049",,,"59","اعتبار دایا","WH_REF_BROKEN_USE_CREATEDBY_HINT" +"121","12","0","1","0","09387342688","2","09387342688","2","09387342688",,,,,"WH_FOUND_USER_BY_MOBILE_NO_TX_LINK" +"122","26","31","56000000",,,"52","09178327020",,,"31","اعتبار دایا",,,"WH_LINKED_TO_TX" +"124","35","0","1","57","09961354257","72","09124678697",,,,,"57","اعتبار دایا","WH_REF_BROKEN_USE_CREATEDBY_HINT" +"138","64","42","56000000","09014638673","09014638673","116","09014638673","116","09014638673","42","اعتبار دایا",,,"WH_LINKED_TO_TX" +"139","63","43","56000000","09056365323","09056365323","115","09056365323","115","09056365323","43","اعتبار دایا",,,"WH_LINKED_TO_TX" +"140","67","44","56000000","09126092994","09126092994","119","09126092994","119","09126092994","44","اعتبار دایا",,,"WH_LINKED_TO_TX" +"141","61","45","56000000","09177325630","09177325630","113","09177325630","113","09177325630","45","اعتبار دایا",,,"WH_LINKED_TO_TX" +"142","51","46","56000000","09384366040","09384366040","103","09384366040","103","09384366040","46","اعتبار دایا",,,"WH_LINKED_TO_TX" +"201","110","0","1","92","162","162","09199877503",,,,,,,"WH_ORPHAN_REVIEW" +"292","118","107","56000000","SP","SP","170","09120991323",,,"107","اعتبار پرداخت مستقیم",,,"WH_LINKED_TO_TX" +"293","119","108","56000000","SP","SP","171","09375724408",,,"108","اعتبار پرداخت مستقیم",,,"WH_LINKED_TO_TX" +"294","120","109","56000000","SP","SP","172","09121355832",,,"109","اعتبار پرداخت مستقیم",,,"WH_LINKED_TO_TX" +"295","123","110","56000000","SP","SP","175","09122332219",,,"110","اعتبار پرداخت مستقیم",,,"WH_LINKED_TO_TX" diff --git a/src/dbbkup/Fix_WrongDaya_ToManual_PurchaseMethod.sql b/src/dbbkup/Fix_WrongDaya_ToManual_PurchaseMethod.sql deleted file mode 100644 index 5827691..0000000 --- a/src/dbbkup/Fix_WrongDaya_ToManual_PurchaseMethod.sql +++ /dev/null @@ -1,157 +0,0 @@ -/* - Correct users wrongly marked as DayaLoan — should be Manual. - - Affects: - - CMS.Users.PackagePurchaseMethod (1 → 3) - - CMS.ClubMemberships.PurchaseMethod (1 or 0 → 3) - - CMS.ClubMembershipCycles.PurchaseMethod (1 or 0 → 3) - - CMS.UserPackagePurchases.PurchaseMethod (1 → 3) - - CMS.Users.HasReceivedDayaCredit / DayaCreditReceivedAt clear - - CMS.DayaLoanContracts soft-delete stub rows - (IsProcessed=0, no TransactionId, no ProcessedDate) - for these UserIds only - - PackagePurchaseMethod: None=0, DayaLoan=1, DirectPurchase=2, Manual=3 - - NOTE: UserId=43 shares NationalCode 5289780335 with UserId=42 (real Excel Daya). - This script only touches UserId=43's own rows — not UserId=42's contract. - - Defaults to ROLLBACK. Uncomment COMMIT after verifying PRINT counts. -*/ - -SET NOCOUNT ON; -SET XACT_ABORT ON; - -BEGIN TRAN; - -DECLARE @FixUsers TABLE (UserId BIGINT PRIMARY KEY); -INSERT INTO @FixUsers (UserId) VALUES -(2),(7),(8),(9),(10),(11),(12),(13),(40),(41),(43),(45),(47), -(52),(58),(69),(71),(72),(74),(75),(87),(88),(89),(90),(91),(93), -(96),(99),(103),(105),(106),(111),(113),(115),(116),(119),(121), -(125),(130),(142),(162),(169),(170),(171),(172),(175),(176); - ------------------------------------------------------------- --- 1) Users ------------------------------------------------------------- -UPDATE u -SET - u.PackagePurchaseMethod = 3, -- Manual - u.HasReceivedDayaCredit = 0, - u.DayaCreditReceivedAt = NULL, - u.LastModified = SYSUTCDATETIME() -FROM CMS.Users u -INNER JOIN @FixUsers f ON f.UserId = u.Id -WHERE u.IsDeleted = 0 - AND ( - u.PackagePurchaseMethod = 1 -- DayaLoan - OR u.HasReceivedDayaCredit = 1 - OR u.DayaCreditReceivedAt IS NOT NULL - ); - -PRINT CONCAT('Users updated: ', @@ROWCOUNT); - ------------------------------------------------------------- --- 2) ClubMemberships ------------------------------------------------------------- -UPDATE m -SET - m.PurchaseMethod = 3, -- Manual - m.LastModified = SYSUTCDATETIME() -FROM CMS.ClubMemberships m -INNER JOIN @FixUsers f ON f.UserId = m.UserId -WHERE m.IsDeleted = 0 - AND m.PurchaseMethod IN (0, 1); -- None or DayaLoan - -PRINT CONCAT('ClubMemberships updated: ', @@ROWCOUNT); - ------------------------------------------------------------- --- 3) ClubMembershipCycles ------------------------------------------------------------- -UPDATE c -SET - c.PurchaseMethod = 3, -- Manual - c.LastModified = SYSUTCDATETIME() -FROM CMS.ClubMembershipCycles c -INNER JOIN @FixUsers f ON f.UserId = c.UserId -WHERE c.IsDeleted = 0 - AND c.PurchaseMethod IN (0, 1); - -PRINT CONCAT('ClubMembershipCycles updated: ', @@ROWCOUNT); - ------------------------------------------------------------- --- 4) UserPackagePurchases (incl. backfill rows) ------------------------------------------------------------- -UPDATE upp -SET - upp.PurchaseMethod = 3, -- Manual - upp.LastModified = SYSUTCDATETIME() -FROM CMS.UserPackagePurchases upp -INNER JOIN @FixUsers f ON f.UserId = upp.UserId -WHERE upp.IsDeleted = 0 - AND upp.PurchaseMethod = 1; -- only Daya → Manual (keep Direct=2 if any) - -PRINT CONCAT('UserPackagePurchases updated: ', @@ROWCOUNT); - ------------------------------------------------------------- --- 5) Soft-delete stub DayaLoanContracts (never processed) ------------------------------------------------------------- -UPDATE d -SET - d.IsDeleted = 1, - d.LastModified = SYSUTCDATETIME() -FROM CMS.DayaLoanContracts d -INNER JOIN @FixUsers f ON f.UserId = d.UserId -WHERE d.IsDeleted = 0 - AND d.IsProcessed = 0 - AND d.TransactionId IS NULL - AND d.ProcessedDate IS NULL; - -PRINT CONCAT('DayaLoanContracts soft-deleted (stubs): ', @@ROWCOUNT); - ------------------------------------------------------------- --- Verify ------------------------------------------------------------- -SELECT 'Users still Daya' AS CheckName, COUNT(*) AS Cnt -FROM CMS.Users u -INNER JOIN @FixUsers f ON f.UserId = u.Id -WHERE u.IsDeleted = 0 AND u.PackagePurchaseMethod = 1 -UNION ALL -SELECT 'Club still Daya/None', COUNT(*) -FROM CMS.ClubMemberships m -INNER JOIN @FixUsers f ON f.UserId = m.UserId -WHERE m.IsDeleted = 0 AND m.PurchaseMethod IN (0, 1) -UNION ALL -SELECT 'Cycle still Daya/None', COUNT(*) -FROM CMS.ClubMembershipCycles c -INNER JOIN @FixUsers f ON f.UserId = c.UserId -WHERE c.IsDeleted = 0 AND c.PurchaseMethod IN (0, 1) -UNION ALL -SELECT 'UPP still Daya', COUNT(*) -FROM CMS.UserPackagePurchases upp -INNER JOIN @FixUsers f ON f.UserId = upp.UserId -WHERE upp.IsDeleted = 0 AND upp.PurchaseMethod = 1 -UNION ALL -SELECT 'Active stub Daya contracts', COUNT(*) -FROM CMS.DayaLoanContracts d -INNER JOIN @FixUsers f ON f.UserId = d.UserId -WHERE d.IsDeleted = 0 - AND d.IsProcessed = 0 - AND d.TransactionId IS NULL - AND d.ProcessedDate IS NULL; - --- Sample after -SELECT u.Id AS UserId, - u.FirstName, u.LastName, u.Mobile, - u.PackagePurchaseMethod, - m.PurchaseMethod AS ClubPurchaseMethod -FROM CMS.Users u -INNER JOIN @FixUsers f ON f.UserId = u.Id -LEFT JOIN CMS.ClubMemberships m ON m.UserId = u.Id AND m.IsDeleted = 0 -WHERE u.IsDeleted = 0 -ORDER BY u.Id; - --- Uncomment to apply: --- COMMIT; -ROLLBACK; -PRINT 'Rolled back (safety). Uncomment COMMIT and remove ROLLBACK to apply.'; diff --git a/src/dbbkup/Transactions.csv b/src/dbbkup/Transactions.csv new file mode 100644 index 0000000..c247fb0 --- /dev/null +++ b/src/dbbkup/Transactions.csv @@ -0,0 +1,23 @@ +"Id","Amount","Description","PaymentStatus","PaymentDate","RefId","Type","Created","CreatedBy","LastModified","LastModifiedBy","IsDeleted" +"23","56000000","اعتبار دایا","0","19/11/2025 01:24:24","manualy24","2","19/11/2025 01:24:24",,"28/11/2025 05:27:38",,"0" +"24","56000000","اعتبار دایا","0","19/11/2025 01:24:24","manualy25","2","19/11/2025 01:24:24",,"28/11/2025 05:27:38",,"0" +"25","56000000","اعتبار دایا","0","19/11/2025 01:24:24","manualy26","2","19/11/2025 01:24:24",,"28/11/2025 05:27:38",,"0" +"26","56000000","اعتبار دایا","0","19/11/2025 01:24:24","manualy27","2","19/11/2025 01:24:24",,"28/11/2025 05:27:38",,"0" +"28","56000000","اعتبار دایا","0","19/11/2025 01:24:24","manualy29","2","19/11/2025 01:24:24",,"28/11/2025 05:27:38",,"0" +"29","56000000","اعتبار دایا","0","19/11/2025 01:24:24","manualy30","2","19/11/2025 01:24:24",,"28/11/2025 05:27:38",,"0" +"30","56000000","اعتبار دایا","0","19/11/2025 01:24:24","manualy31","2","19/11/2025 01:24:24",,"28/11/2025 05:27:38",,"0" +"31","56000000","اعتبار دایا","0","28/11/2025 05:27:38","manualy32","2","27/11/2025 01:24:24",,"28/11/2025 05:27:38",,"0" +"42","56000000","اعتبار دایا","0","3/12/2025 09:49:45.92","manualy43","2","3/12/2025 09:49:45.92","09014638673","5/12/2025 23:59:14.543333","09014638673","0" +"43","56000000","اعتبار دایا","0","3/12/2025 09:49:45.92","manualy44","2","3/12/2025 09:49:45.92","09056365323","5/12/2025 23:59:14.543333","09056365323","0" +"44","56000000","اعتبار دایا","0","3/12/2025 09:49:45.92","manualy45","2","3/12/2025 09:49:45.92","09126092994","5/12/2025 23:59:14.543333","09126092994","0" +"45","56000000","اعتبار دایا","0","3/12/2025 09:49:45.92","manualy46","2","3/12/2025 09:49:45.92","09177325630","5/12/2025 23:59:14.543333","09177325630","0" +"46","56000000","اعتبار دایا","0","3/12/2025 09:49:45.92","manualy47","2","3/12/2025 09:49:45.92","09384366040","5/12/2025 23:59:14.543333","09384366040","0" +"56","56000000","اعتبار دایا","0","3/12/2025 09:49:45.92","manualy57","2","3/12/2025 09:49:45.92","09015793338","14/12/2025 00:07:09.43","09015793338","0" +"57","56000000","اعتبار دایا","0","19/11/2025 01:24:24","manualy58","2","19/11/2025 01:24:24","09961354257","14/12/2025 00:07:48.61","09961354257","0" +"58","56000000","اعتبار دایا","0","19/11/2025 01:24:24","manualy59","2","19/11/2025 01:24:24","09217672935","14/12/2025 00:15:55.02","09217672935","0" +"59","56000000","اعتبار دایا","0","19/11/2025 01:24:24","manualy60","2","19/11/2025 01:24:24","09101692049","14/12/2025 00:16:57.08","09101692049","0" +"68","56000000","اعتبار دایا","0","8/12/2025 12:30:53.536666","manualy69","2","15/12/2025 21:55:40.946666","09399172812","15/12/2025 21:55:40.946666","09399172812","0" +"107","56000000","اعتبار پرداخت مستقیم","0","30/12/2025 01:24:24","manualy292","2","30/12/2025 01:24:24",,"30/12/2025 01:24:24",,"0" +"108","56000000","اعتبار پرداخت مستقیم","0","31/12/2025 01:24:24","manualy293","2","31/12/2025 01:24:24",,"31/12/2025 01:24:24",,"0" +"109","56000000","اعتبار پرداخت مستقیم","0","31/12/2025 01:24:24","manualy294","2","31/12/2025 01:24:24",,"31/12/2025 01:24:24",,"0" +"110","56000000","اعتبار پرداخت مستقیم","0","1/1/2026 17:07:53.2301978","manualy295","2","1/1/2026 17:07:53.2301978",,"1/1/2026 17:07:53.2301978",,"0" diff --git a/src/dbbkup/UserWalletHistories.csv b/src/dbbkup/UserWalletHistories.csv new file mode 100644 index 0000000..db3de48 --- /dev/null +++ b/src/dbbkup/UserWalletHistories.csv @@ -0,0 +1,18 @@ +"Id","WalletId","CurrentBalance","ChangeValue","IsIncrease","RefrenceId","Created","CreatedBy","LastModified","LastModifiedBy","IsDeleted","ChangeNerworkValue","CurrentNetworkBalance","ChangeDiscountValue","CurrentDiscountBalance","PackageId" +"102","38","56000000","56000000","1","23","19/11/2025 01:24:24",,"28/11/2025 01:27:12",,"0","0","0","0","0", +"103","46","56000000","56000000","1","24","19/11/2025 01:24:24",,"28/11/2025 05:22:08",,"0","0","0","0","0", +"104","47","56000000","56000000","1","25","19/11/2025 01:24:24",,"28/11/2025 05:22:08",,"0","0","0","0","0", +"105","49","56000000","56000000","1","26","19/11/2025 01:24:24",,"28/11/2025 05:22:08",,"0","0","0","0","0", +"106","24","56000000","56000000","1","28","19/11/2025 01:24:24",,"28/11/2025 05:22:08",,"0","0","0","0","0", +"107","22","56000000","56000000","1","29","19/11/2025 01:24:24",,"28/11/2025 05:22:08",,"0","0","0","0","0", +"108","23","56000000","56000000","1","30","19/11/2025 01:24:24",,"28/11/2025 05:22:08",,"0","0","0","0","0", +"122","26","56000000","56000000","1","31","27/11/2025 01:24:24",,"28/11/2025 05:22:08",,"0","0","0","0","0", +"138","64","56000000","56000000","1","42","3/12/2025 09:49:45.92","09014638673","5/12/2025 23:59:14.543333","09014638673","0","0","0","0","0", +"139","63","56000000","56000000","1","43","3/12/2025 09:49:45.92","09056365323","5/12/2025 23:59:14.543333","09056365323","0","0","0","0","0", +"140","67","56000000","56000000","1","44","3/12/2025 09:49:45.92","09126092994","5/12/2025 23:59:14.543333","09126092994","0","0","0","0","0", +"141","61","56000000","56000000","1","45","3/12/2025 09:49:45.92","09177325630","5/12/2025 23:59:14.543333","09177325630","0","0","0","0","0", +"142","51","56000000","56000000","1","46","3/12/2025 09:49:45.92","09384366040","5/12/2025 23:59:14.543333","09384366040","0","0","0","0","0", +"292","118","0","56000000","1","107","30/12/2025 01:24:24","SP","30/12/2025 01:24:24","SP","0","0","0","112000000","0", +"293","119","0","56000000","1","108","31/12/2025 01:24:24","SP","31/12/2025 01:24:24","SP","0","0","0","112000000","0", +"294","120","0","56000000","1","109","31/12/2025 01:24:24","SP","31/12/2025 01:24:24","SP","0","0","0","112000000","0", +"295","123","0","56000000","1","110","1/1/2026 17:07:53.2301978","SP","1/1/2026 17:07:53.2301978","SP","0","0","0","112000000","0", diff --git a/src/dbbkup/UserWalletHistories2.csv b/src/dbbkup/UserWalletHistories2.csv new file mode 100644 index 0000000..4fb5301 --- /dev/null +++ b/src/dbbkup/UserWalletHistories2.csv @@ -0,0 +1,7 @@ +"Id","WalletId","CurrentBalance","ChangeValue","IsIncrease","RefrenceId","Created","CreatedBy","LastModified","LastModifiedBy","IsDeleted","ChangeNerworkValue","CurrentNetworkBalance","ChangeDiscountValue","CurrentDiscountBalance","PackageId" +"118","34","0","1","1","0","3/12/2025 09:49:45.92","56","14/12/2025 00:07:09.43","09015793338","0","0","0","0","0", +"119","32","0","1","1","0","19/11/2025 01:24:24","58","14/12/2025 00:15:55.02","09217672935","0","0","0","0","0", +"120","37","0","1","1","0","19/11/2025 01:24:24","59","14/12/2025 00:16:57.08","09101692049","0","0","0","0","0", +"121","12","0","1","1","0","19/12/2025 22:00:40.276666","0","20/12/2025 02:10:19.542402","09387342688","0","0","0","0","0", +"124","35","0","1","1","0","19/11/2025 01:24:24","57","14/12/2025 00:07:48.61","09961354257","0","0","0","0","0", +"201","110","0","1","1","0","20/12/2025 02:24:42.771904","92","20/12/2025 02:24:42.771905","162","0","0","0","112000000","112000000",