feat: implement commission calculation strategy with ORM and SP options
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 1m43s
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 1m43s
This commit is contained in:
+40
@@ -0,0 +1,40 @@
|
||||
-- =============================================
|
||||
-- Insert Configuration for Strategy Selection
|
||||
-- =============================================
|
||||
|
||||
-- Check if config exists, insert if not
|
||||
IF NOT EXISTS (SELECT 1 FROM CMS.SystemConfigurations WHERE [Key] = 'Commission.CalculationStrategy')
|
||||
BEGIN
|
||||
INSERT INTO CMS.SystemConfigurations ([Key], [Value], [Description], IsActive, Created, CreatedBy, LastModified, LastModifiedBy)
|
||||
VALUES (
|
||||
'Commission.CalculationStrategy',
|
||||
'ORM',
|
||||
N'روش محاسبه کمیسیون: ORM (Entity Framework) یا SP (Stored Procedure)',
|
||||
1,
|
||||
GETDATE(),
|
||||
'System',
|
||||
GETDATE(),
|
||||
'System'
|
||||
);
|
||||
PRINT 'Configuration Commission.CalculationStrategy created with default value: ORM'
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
PRINT 'Configuration Commission.CalculationStrategy already exists'
|
||||
END
|
||||
|
||||
-- Show current value
|
||||
SELECT [Key], [Value], [Description]
|
||||
FROM CMS.SystemConfigurations
|
||||
WHERE [Key] LIKE 'Commission.%'
|
||||
ORDER BY [Key];
|
||||
|
||||
/*
|
||||
تغییر روش محاسبه:
|
||||
|
||||
-- برای استفاده از ORM (Entity Framework):
|
||||
UPDATE CMS.SystemConfigurations SET Value = 'ORM' WHERE [Key] = 'Commission.CalculationStrategy'
|
||||
|
||||
-- برای استفاده از Stored Procedure:
|
||||
UPDATE CMS.SystemConfigurations SET Value = 'SP' WHERE [Key] = 'Commission.CalculationStrategy'
|
||||
*/
|
||||
@@ -0,0 +1,94 @@
|
||||
-- =============================================
|
||||
-- SP Deployment Script for Commission Calculation
|
||||
-- Version: 1.0
|
||||
-- Created: 2025-12-19
|
||||
-- =============================================
|
||||
|
||||
/*
|
||||
این اسکریپت برای نصب Stored Procedure های محاسبه کمیسیون استفاده میشود.
|
||||
|
||||
قبل از اجرا:
|
||||
1. مطمئن شوید که به دیتابیس CMS متصل هستید
|
||||
2. کاربر شما دسترسی CREATE PROCEDURE داشته باشد
|
||||
|
||||
ترتیب اجرا:
|
||||
1. sp_CalculateWeeklyBalances.sql
|
||||
2. sp_CalculateWeeklyCommissionPool.sql
|
||||
|
||||
یا این فایل را اجرا کنید که هر دو SP را نصب میکند.
|
||||
*/
|
||||
|
||||
PRINT '========================================='
|
||||
PRINT 'Commission Calculation SP Deployment'
|
||||
PRINT '========================================='
|
||||
PRINT ''
|
||||
|
||||
-- =============================================
|
||||
-- Check Schema
|
||||
-- =============================================
|
||||
IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = 'CMS')
|
||||
BEGIN
|
||||
PRINT 'ERROR: Schema CMS does not exist!'
|
||||
RETURN
|
||||
END
|
||||
|
||||
PRINT 'Schema CMS: OK'
|
||||
PRINT ''
|
||||
|
||||
-- =============================================
|
||||
-- Drop existing procedures if exist
|
||||
-- =============================================
|
||||
IF EXISTS (SELECT 1 FROM sys.procedures WHERE name = 'sp_CalculateWeeklyBalances' AND schema_id = SCHEMA_ID('CMS'))
|
||||
BEGIN
|
||||
DROP PROCEDURE CMS.sp_CalculateWeeklyBalances;
|
||||
PRINT 'Dropped existing sp_CalculateWeeklyBalances'
|
||||
END
|
||||
|
||||
IF EXISTS (SELECT 1 FROM sys.procedures WHERE name = 'sp_CalculateWeeklyCommissionPool' AND schema_id = SCHEMA_ID('CMS'))
|
||||
BEGIN
|
||||
DROP PROCEDURE CMS.sp_CalculateWeeklyCommissionPool;
|
||||
PRINT 'Dropped existing sp_CalculateWeeklyCommissionPool'
|
||||
END
|
||||
|
||||
PRINT ''
|
||||
PRINT 'Creating Stored Procedures...'
|
||||
PRINT ''
|
||||
|
||||
-- =============================================
|
||||
-- SP 1: sp_CalculateWeeklyBalances
|
||||
-- =============================================
|
||||
GO
|
||||
-- (content of sp_CalculateWeeklyBalances.sql here)
|
||||
-- Run sp_CalculateWeeklyBalances.sql separately
|
||||
|
||||
GO
|
||||
-- (content of sp_CalculateWeeklyCommissionPool.sql here)
|
||||
-- Run sp_CalculateWeeklyCommissionPool.sql separately
|
||||
|
||||
GO
|
||||
|
||||
PRINT ''
|
||||
PRINT '========================================='
|
||||
PRINT 'Deployment Complete!'
|
||||
PRINT '========================================='
|
||||
PRINT ''
|
||||
PRINT 'How to use:'
|
||||
PRINT ''
|
||||
PRINT '-- 1. Set calculation strategy in SystemConfigurations:'
|
||||
PRINT 'UPDATE CMS.SystemConfigurations '
|
||||
PRINT 'SET Value = ''SP'' '
|
||||
PRINT 'WHERE [Key] = ''Commission.CalculationStrategy'''
|
||||
PRINT ''
|
||||
PRINT '-- Or for ORM mode:'
|
||||
PRINT 'UPDATE CMS.SystemConfigurations '
|
||||
PRINT 'SET Value = ''ORM'' '
|
||||
PRINT 'WHERE [Key] = ''Commission.CalculationStrategy'''
|
||||
PRINT ''
|
||||
PRINT '-- 2. Manual execution (optional):'
|
||||
PRINT 'DECLARE @RowCount INT, @PoolId BIGINT'
|
||||
PRINT 'EXEC CMS.sp_CalculateWeeklyBalances @WeekDefinitionId = 1, @ForceRecalculate = 0, @RowCount = @RowCount OUTPUT'
|
||||
PRINT 'PRINT ''Rows affected: '' + CAST(@RowCount AS VARCHAR)'
|
||||
PRINT ''
|
||||
PRINT 'EXEC CMS.sp_CalculateWeeklyCommissionPool @WeekDefinitionId = 1, @ForceRecalculate = 0, @PoolId = @PoolId OUTPUT'
|
||||
PRINT 'PRINT ''Pool ID: '' + CAST(@PoolId AS VARCHAR)'
|
||||
GO
|
||||
+350
@@ -0,0 +1,350 @@
|
||||
-- =============================================
|
||||
-- Stored Procedure: sp_CalculateWeeklyBalances
|
||||
-- Description: محاسبه تعادلهای هفتگی شبکه باینری با استفاده از CTE
|
||||
-- Author: System
|
||||
-- Created: 2025-12-19
|
||||
-- =============================================
|
||||
|
||||
CREATE OR ALTER PROCEDURE [CMS].[sp_CalculateWeeklyBalances]
|
||||
@WeekDefinitionId BIGINT,
|
||||
@ForceRecalculate BIT = 0,
|
||||
@RowCount INT OUTPUT
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SET XACT_ABORT ON;
|
||||
|
||||
DECLARE @ErrorMessage NVARCHAR(4000);
|
||||
DECLARE @StartDate DATETIME;
|
||||
DECLARE @EndDate DATETIME;
|
||||
DECLARE @PreviousWeekDefinitionId BIGINT;
|
||||
DECLARE @MaxBalancesPerLeg INT = 300;
|
||||
DECLARE @MaxNetworkLevel INT = 15;
|
||||
DECLARE @CalculatedAt DATETIME = GETDATE();
|
||||
|
||||
BEGIN TRY
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
-- =============================================
|
||||
-- 1. اعتبارسنجی WeekDefinitionId
|
||||
-- =============================================
|
||||
IF NOT EXISTS (SELECT 1 FROM CMS.WeekDefinitions WHERE Id = @WeekDefinitionId)
|
||||
BEGIN
|
||||
SET @ErrorMessage = N'هفته ' + CAST(@WeekDefinitionId AS NVARCHAR(20)) + N' در سیستم تعریف نشده است';
|
||||
RAISERROR(@ErrorMessage, 16, 1);
|
||||
RETURN;
|
||||
END
|
||||
|
||||
-- دریافت بازه تاریخی هفته
|
||||
SELECT @StartDate = StartDate, @EndDate = EndDate
|
||||
FROM CMS.WeekDefinitions
|
||||
WHERE Id = @WeekDefinitionId;
|
||||
|
||||
-- =============================================
|
||||
-- 2. بررسی محاسبه قبلی
|
||||
-- =============================================
|
||||
IF EXISTS (SELECT 1 FROM CMS.NetworkWeeklyBalances WHERE WeekDefinitionId = @WeekDefinitionId)
|
||||
BEGIN
|
||||
IF @ForceRecalculate = 0
|
||||
BEGIN
|
||||
SET @ErrorMessage = N'تعادلهای هفته ' + CAST(@WeekDefinitionId AS NVARCHAR(20)) + N' قبلاً محاسبه شده است. برای محاسبه مجدد از ForceRecalculate استفاده کنید';
|
||||
RAISERROR(@ErrorMessage, 16, 1);
|
||||
RETURN;
|
||||
END
|
||||
|
||||
-- حذف محاسبات قبلی
|
||||
DELETE FROM CMS.NetworkWeeklyBalances WHERE WeekDefinitionId = @WeekDefinitionId;
|
||||
END
|
||||
|
||||
-- =============================================
|
||||
-- 3. پیدا کردن هفته قبل
|
||||
-- =============================================
|
||||
SELECT TOP 1 @PreviousWeekDefinitionId = Id
|
||||
FROM CMS.WeekDefinitions
|
||||
WHERE WeekOrder = (SELECT WeekOrder - 1 FROM CMS.WeekDefinitions WHERE Id = @WeekDefinitionId)
|
||||
AND IsActive = 1;
|
||||
|
||||
-- =============================================
|
||||
-- 4. خواندن Configuration ها
|
||||
-- =============================================
|
||||
SELECT @MaxBalancesPerLeg = CAST(Value AS INT)
|
||||
FROM CMS.SystemConfigurations
|
||||
WHERE [Key] = 'Commission.MaxWeeklyBalancesPerLeg' AND IsActive = 1;
|
||||
|
||||
SELECT @MaxNetworkLevel = CAST(Value AS INT)
|
||||
FROM CMS.SystemConfigurations
|
||||
WHERE [Key] = 'Commission.MaxNetworkLevel' AND IsActive = 1;
|
||||
|
||||
-- مقادیر پیشفرض
|
||||
SET @MaxBalancesPerLeg = ISNULL(@MaxBalancesPerLeg, 300);
|
||||
SET @MaxNetworkLevel = ISNULL(@MaxNetworkLevel, 15);
|
||||
|
||||
-- =============================================
|
||||
-- 5. ایجاد جدول موقت برای نتایج
|
||||
-- =============================================
|
||||
CREATE TABLE #Balances (
|
||||
UserId BIGINT PRIMARY KEY,
|
||||
LeftLegNewMembers INT DEFAULT 0,
|
||||
RightLegNewMembers INT DEFAULT 0,
|
||||
LeftLegCarryover INT DEFAULT 0,
|
||||
RightLegCarryover INT DEFAULT 0,
|
||||
LeftLegTotal INT DEFAULT 0,
|
||||
RightLegTotal INT DEFAULT 0,
|
||||
TotalBalances INT DEFAULT 0,
|
||||
LeftLegRemainder INT DEFAULT 0,
|
||||
RightLegRemainder INT DEFAULT 0,
|
||||
FlushedPerSide INT DEFAULT 0,
|
||||
TotalFlushed INT DEFAULT 0,
|
||||
SubordinateBalances INT DEFAULT 0
|
||||
);
|
||||
|
||||
-- =============================================
|
||||
-- 6. دریافت کاربران فعال باشگاه
|
||||
-- =============================================
|
||||
INSERT INTO #Balances (UserId)
|
||||
SELECT DISTINCT u.Id
|
||||
FROM CMS.Users u
|
||||
INNER JOIN CMS.ClubMemberships cm ON cm.UserId = u.Id AND cm.IsActive = 1;
|
||||
|
||||
-- =============================================
|
||||
-- 7. دریافت باقیمانده هفته قبل
|
||||
-- =============================================
|
||||
IF @PreviousWeekDefinitionId IS NOT NULL
|
||||
BEGIN
|
||||
UPDATE b
|
||||
SET b.LeftLegCarryover = ISNULL(nb.LeftLegRemainder, 0),
|
||||
b.RightLegCarryover = ISNULL(nb.RightLegRemainder, 0)
|
||||
FROM #Balances b
|
||||
LEFT JOIN CMS.NetworkWeeklyBalances nb ON nb.UserId = b.UserId AND nb.WeekDefinitionId = @PreviousWeekDefinitionId;
|
||||
END
|
||||
|
||||
-- =============================================
|
||||
-- 8. محاسبه اعضای جدید هر پا با CTE (بهینه!)
|
||||
-- =============================================
|
||||
|
||||
-- CTE برای شمارش اعضای جدید شاخه چپ
|
||||
;WITH LeftLegCTE AS (
|
||||
-- فرزند مستقیم چپ (لول 1)
|
||||
SELECT
|
||||
u.NetworkParentId AS ParentId,
|
||||
u.Id AS ChildId,
|
||||
1 AS Level
|
||||
FROM CMS.Users u
|
||||
WHERE u.LegPosition = 0 -- Left
|
||||
AND u.NetworkParentId IS NOT NULL
|
||||
|
||||
UNION ALL
|
||||
|
||||
-- زیرمجموعههای بازگشتی
|
||||
SELECT
|
||||
cte.ParentId,
|
||||
u.Id AS ChildId,
|
||||
cte.Level + 1 AS Level
|
||||
FROM CMS.Users u
|
||||
INNER JOIN LeftLegCTE cte ON u.NetworkParentId = cte.ChildId
|
||||
WHERE cte.Level < @MaxNetworkLevel
|
||||
),
|
||||
LeftNewMembers AS (
|
||||
SELECT
|
||||
cte.ParentId AS UserId,
|
||||
COUNT(*) AS NewMembersCount
|
||||
FROM LeftLegCTE cte
|
||||
INNER JOIN CMS.ClubMemberships cm ON cm.UserId = cte.ChildId AND cm.IsActive = 1
|
||||
WHERE cm.ActivatedAt >= @StartDate AND cm.ActivatedAt <= @EndDate
|
||||
GROUP BY cte.ParentId
|
||||
)
|
||||
UPDATE b
|
||||
SET b.LeftLegNewMembers = ISNULL(lnm.NewMembersCount, 0)
|
||||
FROM #Balances b
|
||||
LEFT JOIN LeftNewMembers lnm ON lnm.UserId = b.UserId
|
||||
OPTION (MAXRECURSION 100);
|
||||
|
||||
-- CTE برای شمارش اعضای جدید شاخه راست
|
||||
;WITH RightLegCTE AS (
|
||||
-- فرزند مستقیم راست (لول 1)
|
||||
SELECT
|
||||
u.NetworkParentId AS ParentId,
|
||||
u.Id AS ChildId,
|
||||
1 AS Level
|
||||
FROM CMS.Users u
|
||||
WHERE u.LegPosition = 1 -- Right
|
||||
AND u.NetworkParentId IS NOT NULL
|
||||
|
||||
UNION ALL
|
||||
|
||||
-- زیرمجموعههای بازگشتی
|
||||
SELECT
|
||||
cte.ParentId,
|
||||
u.Id AS ChildId,
|
||||
cte.Level + 1 AS Level
|
||||
FROM CMS.Users u
|
||||
INNER JOIN RightLegCTE cte ON u.NetworkParentId = cte.ChildId
|
||||
WHERE cte.Level < @MaxNetworkLevel
|
||||
),
|
||||
RightNewMembers AS (
|
||||
SELECT
|
||||
cte.ParentId AS UserId,
|
||||
COUNT(*) AS NewMembersCount
|
||||
FROM RightLegCTE cte
|
||||
INNER JOIN CMS.ClubMemberships cm ON cm.UserId = cte.ChildId AND cm.IsActive = 1
|
||||
WHERE cm.ActivatedAt >= @StartDate AND cm.ActivatedAt <= @EndDate
|
||||
GROUP BY cte.ParentId
|
||||
)
|
||||
UPDATE b
|
||||
SET b.RightLegNewMembers = ISNULL(rnm.NewMembersCount, 0)
|
||||
FROM #Balances b
|
||||
LEFT JOIN RightNewMembers rnm ON rnm.UserId = b.UserId
|
||||
OPTION (MAXRECURSION 100);
|
||||
|
||||
-- =============================================
|
||||
-- 9. محاسبه تعادلها
|
||||
-- =============================================
|
||||
UPDATE #Balances
|
||||
SET
|
||||
-- مجموع هر پا
|
||||
LeftLegTotal = LeftLegNewMembers + LeftLegCarryover,
|
||||
RightLegTotal = RightLegNewMembers + RightLegCarryover;
|
||||
|
||||
UPDATE #Balances
|
||||
SET
|
||||
-- تعادل = MIN(چپ، راست)
|
||||
TotalBalances = CASE
|
||||
WHEN LeftLegTotal <= RightLegTotal THEN LeftLegTotal
|
||||
ELSE RightLegTotal
|
||||
END;
|
||||
|
||||
UPDATE #Balances
|
||||
SET
|
||||
-- باقیمانده برای هفته بعد
|
||||
LeftLegRemainder = LeftLegTotal - TotalBalances,
|
||||
RightLegRemainder = RightLegTotal - TotalBalances,
|
||||
-- فلش (اگر تعادل > سقف)
|
||||
FlushedPerSide = CASE
|
||||
WHEN TotalBalances > @MaxBalancesPerLeg THEN TotalBalances - @MaxBalancesPerLeg
|
||||
ELSE 0
|
||||
END;
|
||||
|
||||
UPDATE #Balances
|
||||
SET
|
||||
-- اعمال سقف
|
||||
TotalBalances = CASE
|
||||
WHEN TotalBalances > @MaxBalancesPerLeg THEN @MaxBalancesPerLeg
|
||||
ELSE TotalBalances
|
||||
END,
|
||||
-- مجموع فلش از دو طرف
|
||||
TotalFlushed = FlushedPerSide * 2;
|
||||
|
||||
-- =============================================
|
||||
-- 10. محاسبه تعادل زیرمجموعه با CTE
|
||||
-- =============================================
|
||||
;WITH SubordinateCTE AS (
|
||||
-- فرزندان مستقیم (لول 1)
|
||||
SELECT
|
||||
u.NetworkParentId AS ParentId,
|
||||
u.Id AS ChildId,
|
||||
1 AS Level
|
||||
FROM CMS.Users u
|
||||
WHERE u.NetworkParentId IS NOT NULL
|
||||
|
||||
UNION ALL
|
||||
|
||||
-- زیرمجموعههای بازگشتی
|
||||
SELECT
|
||||
cte.ParentId,
|
||||
u.Id AS ChildId,
|
||||
cte.Level + 1 AS Level
|
||||
FROM CMS.Users u
|
||||
INNER JOIN SubordinateCTE cte ON u.NetworkParentId = cte.ChildId
|
||||
WHERE cte.Level < @MaxNetworkLevel
|
||||
),
|
||||
SubordinateBalances AS (
|
||||
SELECT
|
||||
cte.ParentId AS UserId,
|
||||
SUM(b.TotalBalances) AS TotalSubordinateBalances
|
||||
FROM SubordinateCTE cte
|
||||
INNER JOIN #Balances b ON b.UserId = cte.ChildId
|
||||
GROUP BY cte.ParentId
|
||||
)
|
||||
UPDATE b
|
||||
SET b.SubordinateBalances = ISNULL(sb.TotalSubordinateBalances, 0)
|
||||
FROM #Balances b
|
||||
LEFT JOIN SubordinateBalances sb ON sb.UserId = b.UserId
|
||||
OPTION (MAXRECURSION 100);
|
||||
|
||||
-- =============================================
|
||||
-- 11. Insert نتایج در جدول اصلی
|
||||
-- =============================================
|
||||
INSERT INTO CMS.NetworkWeeklyBalances (
|
||||
UserId,
|
||||
WeekDefinitionId,
|
||||
LeftLegNewMembers,
|
||||
RightLegNewMembers,
|
||||
LeftLegCarryover,
|
||||
RightLegCarryover,
|
||||
LeftLegTotal,
|
||||
RightLegTotal,
|
||||
TotalBalances,
|
||||
LeftLegRemainder,
|
||||
RightLegRemainder,
|
||||
FlushedPerSide,
|
||||
TotalFlushed,
|
||||
SubordinateBalances,
|
||||
LeftLegBalances,
|
||||
RightLegBalances,
|
||||
WeeklyPoolContribution,
|
||||
CalculatedAt,
|
||||
IsExpired,
|
||||
IsDeleted,
|
||||
Created,
|
||||
CreatedBy,
|
||||
LastModified,
|
||||
LastModifiedBy
|
||||
)
|
||||
SELECT
|
||||
UserId,
|
||||
@WeekDefinitionId,
|
||||
LeftLegNewMembers,
|
||||
RightLegNewMembers,
|
||||
LeftLegCarryover,
|
||||
RightLegCarryover,
|
||||
LeftLegTotal,
|
||||
RightLegTotal,
|
||||
TotalBalances,
|
||||
LeftLegRemainder,
|
||||
RightLegRemainder,
|
||||
FlushedPerSide,
|
||||
TotalFlushed,
|
||||
SubordinateBalances,
|
||||
LeftLegTotal, -- LeftLegBalances (deprecated)
|
||||
RightLegTotal, -- RightLegBalances (deprecated)
|
||||
0, -- WeeklyPoolContribution
|
||||
@CalculatedAt,
|
||||
0, -- IsExpired
|
||||
0, -- IsDeleted
|
||||
@CalculatedAt, -- Created
|
||||
'SP', -- CreatedBy
|
||||
@CalculatedAt, -- LastModified
|
||||
'SP' -- LastModifiedBy
|
||||
FROM #Balances;
|
||||
|
||||
SET @RowCount = @@ROWCOUNT;
|
||||
|
||||
-- پاکسازی
|
||||
DROP TABLE #Balances;
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
|
||||
END TRY
|
||||
BEGIN CATCH
|
||||
IF @@TRANCOUNT > 0
|
||||
ROLLBACK TRANSACTION;
|
||||
|
||||
-- پاکسازی در صورت خطا
|
||||
IF OBJECT_ID('tempdb..#Balances') IS NOT NULL
|
||||
DROP TABLE #Balances;
|
||||
|
||||
SET @ErrorMessage = ERROR_MESSAGE();
|
||||
RAISERROR(@ErrorMessage, 16, 1);
|
||||
END CATCH
|
||||
END
|
||||
GO
|
||||
+266
@@ -0,0 +1,266 @@
|
||||
-- =============================================
|
||||
-- Stored Procedure: sp_CalculateWeeklyCommissionPool
|
||||
-- Description: محاسبه استخر کمیسیون هفتگی و توزیع بین کاربران
|
||||
-- Author: System
|
||||
-- Created: 2025-12-19
|
||||
-- =============================================
|
||||
|
||||
CREATE OR ALTER PROCEDURE [CMS].[sp_CalculateWeeklyCommissionPool]
|
||||
@WeekDefinitionId BIGINT,
|
||||
@ForceRecalculate BIT = 0,
|
||||
@PoolId BIGINT OUTPUT
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SET XACT_ABORT ON;
|
||||
|
||||
DECLARE @ErrorMessage NVARCHAR(4000);
|
||||
DECLARE @TotalPoolAmount BIGINT;
|
||||
DECLARE @TotalBalances INT;
|
||||
DECLARE @ValuePerBalance BIGINT;
|
||||
DECLARE @CalculatedAt DATETIME = GETDATE();
|
||||
|
||||
BEGIN TRY
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
-- =============================================
|
||||
-- 1. پیدا کردن Pool هفته
|
||||
-- =============================================
|
||||
SELECT @PoolId = Id, @TotalPoolAmount = TotalPoolAmount
|
||||
FROM CMS.WeeklyCommissionPools
|
||||
WHERE WeekDefinitionId = @WeekDefinitionId;
|
||||
|
||||
IF @PoolId IS NULL
|
||||
BEGIN
|
||||
SET @ErrorMessage = N'استخر کمیسیون برای هفته ' + CAST(@WeekDefinitionId AS NVARCHAR(20)) + N' تعریف نشده است';
|
||||
RAISERROR(@ErrorMessage, 16, 1);
|
||||
RETURN;
|
||||
END
|
||||
|
||||
-- =============================================
|
||||
-- 2. بررسی محاسبات قبلی
|
||||
-- =============================================
|
||||
IF EXISTS (SELECT 1 FROM CMS.UserCommissionPayouts WHERE WeekDefinitionId = @WeekDefinitionId)
|
||||
BEGIN
|
||||
IF @ForceRecalculate = 0
|
||||
BEGIN
|
||||
SET @ErrorMessage = N'کمیسیون هفته ' + CAST(@WeekDefinitionId AS NVARCHAR(20)) + N' قبلاً محاسبه شده است. برای محاسبه مجدد از ForceRecalculate استفاده کنید';
|
||||
RAISERROR(@ErrorMessage, 16, 1);
|
||||
RETURN;
|
||||
END
|
||||
|
||||
-- =============================================
|
||||
-- 3. Revert کیف پولها (در صورت ForceRecalculate)
|
||||
-- =============================================
|
||||
|
||||
-- کم کردن مقادیر قبلی از NetworkBalance
|
||||
UPDATE uw
|
||||
SET uw.NetworkBalance = uw.NetworkBalance - ISNULL(
|
||||
(SELECT SUM(wl.ChangeNerworkValue)
|
||||
FROM CMS.UserWalletChangeLogs wl
|
||||
WHERE wl.WalletId = uw.Id
|
||||
AND wl.RefrenceId IN (SELECT Id FROM CMS.UserCommissionPayouts WHERE WeekDefinitionId = @WeekDefinitionId)
|
||||
), 0)
|
||||
FROM CMS.UserWallets uw
|
||||
WHERE uw.Id IN (
|
||||
SELECT DISTINCT wl.WalletId
|
||||
FROM CMS.UserWalletChangeLogs wl
|
||||
WHERE wl.RefrenceId IN (SELECT Id FROM CMS.UserCommissionPayouts WHERE WeekDefinitionId = @WeekDefinitionId)
|
||||
);
|
||||
|
||||
-- حذف لاگهای تغییرات قبلی
|
||||
DELETE FROM CMS.UserWalletChangeLogs
|
||||
WHERE RefrenceId IN (SELECT Id FROM CMS.UserCommissionPayouts WHERE WeekDefinitionId = @WeekDefinitionId);
|
||||
|
||||
-- حذف تاریخچه پرداخت
|
||||
DELETE FROM CMS.CommissionPayoutHistories
|
||||
WHERE UserCommissionPayoutId IN (SELECT Id FROM CMS.UserCommissionPayouts WHERE WeekDefinitionId = @WeekDefinitionId);
|
||||
|
||||
-- حذف پرداختهای قبلی
|
||||
DELETE FROM CMS.UserCommissionPayouts WHERE WeekDefinitionId = @WeekDefinitionId;
|
||||
|
||||
-- Reset وضعیت Pool
|
||||
UPDATE CMS.WeeklyCommissionPools
|
||||
SET IsCalculated = 0
|
||||
WHERE Id = @PoolId;
|
||||
END
|
||||
|
||||
-- =============================================
|
||||
-- 4. بررسی وجود تعادلهای هفتگی
|
||||
-- =============================================
|
||||
IF NOT EXISTS (SELECT 1 FROM CMS.NetworkWeeklyBalances WHERE WeekDefinitionId = @WeekDefinitionId)
|
||||
BEGIN
|
||||
SET @ErrorMessage = N'ابتدا باید تعادلهای هفتگی محاسبه شوند. sp_CalculateWeeklyBalances را اجرا کنید';
|
||||
RAISERROR(@ErrorMessage, 16, 1);
|
||||
RETURN;
|
||||
END
|
||||
|
||||
-- =============================================
|
||||
-- 5. محاسبه مجموع تعادلها
|
||||
-- =============================================
|
||||
SELECT @TotalBalances = SUM(TotalBalances)
|
||||
FROM CMS.NetworkWeeklyBalances
|
||||
WHERE WeekDefinitionId = @WeekDefinitionId AND TotalBalances > 0;
|
||||
|
||||
IF @TotalBalances IS NULL OR @TotalBalances = 0
|
||||
BEGIN
|
||||
-- هیچ تعادلی برای توزیع وجود ندارد
|
||||
UPDATE CMS.WeeklyCommissionPools
|
||||
SET IsCalculated = 1, CalculatedAt = @CalculatedAt
|
||||
WHERE Id = @PoolId;
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
RETURN;
|
||||
END
|
||||
|
||||
-- =============================================
|
||||
-- 6. محاسبه ارزش هر تعادل
|
||||
-- =============================================
|
||||
SET @ValuePerBalance = @TotalPoolAmount / @TotalBalances;
|
||||
|
||||
-- =============================================
|
||||
-- 7. ایجاد پرداخت برای هر کاربر
|
||||
-- =============================================
|
||||
INSERT INTO CMS.UserCommissionPayouts (
|
||||
UserId,
|
||||
WeekDefinitionId,
|
||||
WeeklyPoolId,
|
||||
BalancesEarned,
|
||||
ValuePerBalance,
|
||||
TotalAmount,
|
||||
Status,
|
||||
PaidAt,
|
||||
IsDeleted,
|
||||
Created,
|
||||
CreatedBy,
|
||||
LastModified,
|
||||
LastModifiedBy
|
||||
)
|
||||
SELECT
|
||||
nb.UserId,
|
||||
@WeekDefinitionId,
|
||||
@PoolId,
|
||||
nb.TotalBalances,
|
||||
@ValuePerBalance,
|
||||
nb.TotalBalances * @ValuePerBalance,
|
||||
0, -- Status: Pending
|
||||
NULL, -- PaidAt
|
||||
0, -- IsDeleted
|
||||
@CalculatedAt,
|
||||
'SP',
|
||||
@CalculatedAt,
|
||||
'SP'
|
||||
FROM CMS.NetworkWeeklyBalances nb
|
||||
WHERE nb.WeekDefinitionId = @WeekDefinitionId AND nb.TotalBalances > 0;
|
||||
|
||||
-- =============================================
|
||||
-- 8. ثبت تاریخچه پرداخت
|
||||
-- =============================================
|
||||
INSERT INTO CMS.CommissionPayoutHistories (
|
||||
UserCommissionPayoutId,
|
||||
UserId,
|
||||
WeekDefinitionId,
|
||||
AmountBefore,
|
||||
AmountAfter,
|
||||
OldStatus,
|
||||
NewStatus,
|
||||
Action,
|
||||
PerformedBy,
|
||||
Reason,
|
||||
IsDeleted,
|
||||
Created,
|
||||
CreatedBy,
|
||||
LastModified,
|
||||
LastModifiedBy
|
||||
)
|
||||
SELECT
|
||||
cp.Id, -- UserCommissionPayoutId
|
||||
cp.UserId, -- UserId
|
||||
@WeekDefinitionId,
|
||||
0, -- AmountBefore
|
||||
cp.TotalAmount, -- AmountAfter
|
||||
0, -- OldStatus: Pending
|
||||
0, -- NewStatus: Pending
|
||||
0, -- Action: Created (assuming enum value)
|
||||
'SP', -- PerformedBy
|
||||
N'محاسبه اولیه توسط SP', -- Reason
|
||||
0, -- IsDeleted
|
||||
@CalculatedAt,
|
||||
'SP',
|
||||
@CalculatedAt,
|
||||
'SP'
|
||||
FROM CMS.UserCommissionPayouts cp
|
||||
WHERE cp.WeekDefinitionId = @WeekDefinitionId;
|
||||
|
||||
-- =============================================
|
||||
-- 9. شارژ کیف پول کاربران
|
||||
-- =============================================
|
||||
|
||||
-- بروزرسانی NetworkBalance
|
||||
UPDATE uw
|
||||
SET uw.NetworkBalance = uw.NetworkBalance + cp.TotalAmount
|
||||
FROM CMS.UserWallets uw
|
||||
INNER JOIN CMS.UserCommissionPayouts cp ON cp.UserId = uw.UserId
|
||||
WHERE cp.WeekDefinitionId = @WeekDefinitionId;
|
||||
|
||||
-- ثبت لاگ تغییرات کیف پول
|
||||
INSERT INTO CMS.UserWalletChangeLogs (
|
||||
WalletId,
|
||||
CurrentBalance,
|
||||
ChangeValue,
|
||||
CurrentNetworkBalance,
|
||||
ChangeNerworkValue,
|
||||
CurrentDiscountBalance,
|
||||
ChangeDiscountValue,
|
||||
IsIncrease,
|
||||
RefrenceId,
|
||||
IsDeleted,
|
||||
Created,
|
||||
CreatedBy,
|
||||
LastModified,
|
||||
LastModifiedBy
|
||||
)
|
||||
SELECT
|
||||
uw.Id,
|
||||
uw.Balance, -- CurrentBalance
|
||||
0, -- ChangeValue (no change to main balance)
|
||||
uw.NetworkBalance, -- CurrentNetworkBalance (after update)
|
||||
cp.TotalAmount, -- ChangeNerworkValue
|
||||
uw.DiscountBalance, -- CurrentDiscountBalance
|
||||
0, -- ChangeDiscountValue
|
||||
1, -- IsIncrease: true
|
||||
cp.Id, -- RefrenceId: PayoutId
|
||||
0, -- IsDeleted
|
||||
@CalculatedAt,
|
||||
'SP',
|
||||
@CalculatedAt,
|
||||
'SP'
|
||||
FROM CMS.UserCommissionPayouts cp
|
||||
INNER JOIN CMS.UserWallets uw ON uw.UserId = cp.UserId
|
||||
WHERE cp.WeekDefinitionId = @WeekDefinitionId;
|
||||
|
||||
-- =============================================
|
||||
-- 10. بروزرسانی Pool
|
||||
-- =============================================
|
||||
UPDATE CMS.WeeklyCommissionPools
|
||||
SET
|
||||
IsCalculated = 1,
|
||||
CalculatedAt = @CalculatedAt,
|
||||
TotalBalances = @TotalBalances,
|
||||
ValuePerBalance = @ValuePerBalance,
|
||||
LastModified = @CalculatedAt,
|
||||
LastModifiedBy = 'SP'
|
||||
WHERE Id = @PoolId;
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
|
||||
END TRY
|
||||
BEGIN CATCH
|
||||
IF @@TRANCOUNT > 0
|
||||
ROLLBACK TRANSACTION;
|
||||
|
||||
SET @ErrorMessage = ERROR_MESSAGE();
|
||||
RAISERROR(@ErrorMessage, 16, 1);
|
||||
END CATCH
|
||||
END
|
||||
GO
|
||||
Reference in New Issue
Block a user