fix(network): update network statistics and tree documentation
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 10m15s
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 10m15s
- Updated README to reflect the new documentation location. - Refactored GetNetworkStatisticsQueryHandler to improve method naming and logic for loading package holder counts. - Enhanced GetNetworkStatisticsResponseDto and NetworkTreeDto to clarify the purpose of leg total properties. - Updated Protobuf definitions to align with the new response structure for network statistics. - Removed obsolete SQL scripts related to user package purchases and DayaLoan contracts cleanup.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# CMS Microservice
|
||||
|
||||
Documentation moved to [totalDoc/INDEX.md](../totalDoc/INDEX.md).
|
||||
|
||||
|
||||
+64
-46
@@ -126,7 +126,7 @@ public class GetNetworkStatisticsQueryHandler : IRequestHandler<GetNetworkStatis
|
||||
}).ToList();
|
||||
|
||||
var (goldLeft, goldRight, silverLeft, silverRight) =
|
||||
await LoadLatestPackageLegScoresAsync(userId, cancellationToken);
|
||||
await LoadPackageHolderCountsByLegAsync(leftChild, rightChild, allUsers, cancellationToken);
|
||||
|
||||
return new GetNetworkStatisticsResponseDto
|
||||
{
|
||||
@@ -149,10 +149,62 @@ public class GetNetworkStatisticsQueryHandler : IRequestHandler<GetNetworkStatis
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// آخرین Left/RightLegTotal طلایی و نقرهای فقط برای خود کاربر (نوار آمار شجره).
|
||||
/// تعداد اعضای فعال باشگاه با پکیج جاری (IsCurrentCycle) در پای چپ/راست.
|
||||
/// </summary>
|
||||
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<User> allUsers,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var leftLegUserIds = leftChild != null ? GetSubtreeUserIds(leftChild.Id, allUsers) : new HashSet<long>();
|
||||
var rightLegUserIds = rightChild != null ? GetSubtreeUserIds(rightChild.Id, allUsers) : new HashSet<long>();
|
||||
|
||||
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<GetNetworkStatis
|
||||
!p.IsBasePackage && (p.Title.Contains("نقره") || p.MaxBalancesPerLeg <= 30))?.Id
|
||||
?? packages.FirstOrDefault(p => !p.IsBasePackage)?.Id;
|
||||
|
||||
var packageIds = new List<long>();
|
||||
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<long> GetSubtreeUserIds(long rootUserId, List<User> allUsers)
|
||||
{
|
||||
var ids = new HashSet<long> { rootUserId };
|
||||
foreach (var descendant in GetAllDescendants(rootUserId, allUsers))
|
||||
ids.Add(descendant.Id);
|
||||
return ids;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
+4
-1
@@ -14,10 +14,13 @@ public class GetNetworkStatisticsResponseDto
|
||||
public List<MonthlyGrowthModel> MonthlyGrowth { get; set; } = new();
|
||||
public List<TopNetworkUserModel> TopUsers { get; set; } = new();
|
||||
|
||||
/// <summary>آخرین LeftLegTotal پکیج طلایی برای همین کاربر</summary>
|
||||
/// <summary>تعداد اعضای فعال باشگاه با پکیج طلایی جاری در پای چپ</summary>
|
||||
public int GoldLeftLegTotal { get; set; }
|
||||
/// <summary>تعداد اعضای فعال باشگاه با پکیج طلایی جاری در پای راست</summary>
|
||||
public int GoldRightLegTotal { get; set; }
|
||||
/// <summary>تعداد اعضای فعال باشگاه با پکیج نقرهای جاری در پای چپ</summary>
|
||||
public int SilverLeftLegTotal { get; set; }
|
||||
/// <summary>تعداد اعضای فعال باشگاه با پکیج نقرهای جاری در پای راست</summary>
|
||||
public int SilverRightLegTotal { get; set; }
|
||||
|
||||
public string WeakerLeg => LeftLegCount <= RightLegCount ? "Left" : "Right";
|
||||
|
||||
+4
-4
@@ -60,16 +60,16 @@ public class NetworkTreeDto
|
||||
|
||||
public long? PackageId { get; set; }
|
||||
|
||||
/// <summary>آخرین LeftLegTotal پکیج طلایی (پایه)</summary>
|
||||
/// <summary>تعداد اعضای فعال با پکیج طلایی جاری در پای چپ (stats bar)</summary>
|
||||
public int GoldLeftLegTotal { get; set; }
|
||||
|
||||
/// <summary>آخرین RightLegTotal پکیج طلایی (پایه)</summary>
|
||||
/// <summary>تعداد اعضای فعال با پکیج طلایی جاری در پای راست (stats bar)</summary>
|
||||
public int GoldRightLegTotal { get; set; }
|
||||
|
||||
/// <summary>آخرین LeftLegTotal پکیج نقرهای</summary>
|
||||
/// <summary>تعداد اعضای فعال با پکیج نقرهای جاری در پای چپ (stats bar)</summary>
|
||||
public int SilverLeftLegTotal { get; set; }
|
||||
|
||||
/// <summary>آخرین RightLegTotal پکیج نقرهای</summary>
|
||||
/// <summary>تعداد اعضای فعال با پکیج نقرهای جاری در پای راست (stats bar)</summary>
|
||||
public int SilverRightLegTotal { get; set; }
|
||||
|
||||
public NetworkTreeDto? LeftChild { get; set; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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).';
|
||||
@@ -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"
|
||||
|
@@ -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;
|
||||
+120
-45
@@ -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;
|
||||
|
||||
@@ -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).';
|
||||
@@ -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.';
|
||||
@@ -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.';
|
||||
@@ -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.';
|
||||
@@ -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.';
|
||||
@@ -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.';
|
||||
@@ -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).';
|
||||
@@ -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"
|
||||
|
@@ -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.';
|
||||
@@ -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"
|
||||
|
@@ -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",
|
||||
|
@@ -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",
|
||||
|
Reference in New Issue
Block a user