8518c7b3ec
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 8m9s
- Updated AcceptClubMembershipContractCommandHandler to set PackagePurchasedAt to the contract-signing time, ensuring accurate pool charging. - Modified ActivateClubMembershipCommand to allow specifying a PackageId for forced activation, defaulting to the base package if not provided. - Improved ActivateClubMembershipCommandHandler to handle new and existing memberships differently regarding pool charging. - Added validation logic in GetWeeklyCommissionPoolQueryHandler to compare TotalPoolAmount against actual activations. - Introduced validation fields in WeeklyCommissionPoolDto for tracking discrepancies and expected amounts. - Updated stored procedures to ensure accurate calculations based on package purchases and to handle empty pools. - Enhanced protobuf definitions to include validation fields for commission pools and network tree nodes. - Added mapping for new fields in CommissionProfile and NetworkMembershipProfile. - Created DiscountProductProfile for mapping discount product requests and responses.
282 lines
10 KiB
Transact-SQL
282 lines
10 KiB
Transact-SQL
-- =============================================
|
|
-- Stored Procedure: sp_CalculateWeeklyCommissionPool
|
|
-- Description: محاسبه استخر کمیسیون هفتگی و توزیع بین کاربران
|
|
-- Author: System
|
|
-- Created: 2025-12-19
|
|
-- Updated: Q29 — اضافه کردن @PackageId، fix فیلتر pool، مدیریت pool خالی
|
|
-- =============================================
|
|
|
|
CREATE OR ALTER PROCEDURE [CMS].[sp_CalculateWeeklyCommissionPool]
|
|
@WeekDefinitionId BIGINT,
|
|
@PackageId BIGINT, -- هر بار به ازای یک پکیج اجرا میشود
|
|
@ForceRecalculate BIT = 0,
|
|
@PoolId BIGINT OUTPUT
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
SET XACT_ABORT ON;
|
|
|
|
DECLARE @ErrorMessage NVARCHAR(4000);
|
|
DECLARE @TotalPoolAmount BIGINT = 0;
|
|
DECLARE @TotalBalances INT;
|
|
DECLARE @ValuePerBalance BIGINT;
|
|
DECLARE @CalculatedAt DATETIME = GETDATE();
|
|
|
|
BEGIN TRY
|
|
BEGIN TRANSACTION;
|
|
|
|
-- =============================================
|
|
-- 1. پیدا کردن Pool هفته (فیلتر بر اساس PackageId)
|
|
-- =============================================
|
|
SELECT @PoolId = Id, @TotalPoolAmount = TotalPoolAmount
|
|
FROM CMS.WeeklyCommissionPools
|
|
WHERE WeekDefinitionId = @WeekDefinitionId AND PackageId = @PackageId;
|
|
|
|
-- اگر Pool وجود ندارد (هیچ فعالسازی در این هفته نبوده)، یک رکورد خالی ایجاد میکنیم
|
|
IF @PoolId IS NULL
|
|
BEGIN
|
|
INSERT INTO CMS.WeeklyCommissionPools (
|
|
WeekDefinitionId, PackageId, TotalPoolAmount, TotalBalances,
|
|
ValuePerBalance, IsCalculated, CalculatedAt,
|
|
IsDeleted, Created, CreatedBy, LastModified, LastModifiedBy
|
|
) VALUES (
|
|
@WeekDefinitionId, @PackageId, 0, 0, 0, 0, NULL,
|
|
0, @CalculatedAt, 'SP', @CalculatedAt, 'SP'
|
|
);
|
|
SET @PoolId = SCOPE_IDENTITY();
|
|
SET @TotalPoolAmount = 0;
|
|
END
|
|
|
|
-- =============================================
|
|
-- 2. بررسی محاسبات قبلی (بر اساس همین Pool نه کل هفته)
|
|
-- =============================================
|
|
IF EXISTS (SELECT 1 FROM CMS.UserCommissionPayouts WHERE WeeklyPoolId = @PoolId)
|
|
BEGIN
|
|
IF @ForceRecalculate = 0
|
|
BEGIN
|
|
SET @ErrorMessage = N'کمیسیون هفته ' + CAST(@WeekDefinitionId AS NVARCHAR(20))
|
|
+ N' (پکیج ' + CAST(@PackageId AS NVARCHAR(20)) + N') قبلاً محاسبه شده است. برای محاسبه مجدد از ForceRecalculate استفاده کنید';
|
|
RAISERROR(@ErrorMessage, 16, 1);
|
|
RETURN;
|
|
END
|
|
|
|
-- =============================================
|
|
-- 3. Revert کیف پولها (در صورت ForceRecalculate، فقط پرداختهای این Pool)
|
|
-- =============================================
|
|
|
|
-- کم کردن مقادیر قبلی از 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 WeeklyPoolId = @PoolId)
|
|
), 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 WeeklyPoolId = @PoolId)
|
|
);
|
|
|
|
-- حذف لاگهای تغییرات قبلی
|
|
DELETE FROM CMS.UserWalletChangeLogs
|
|
WHERE RefrenceId IN (SELECT Id FROM CMS.UserCommissionPayouts WHERE WeeklyPoolId = @PoolId);
|
|
|
|
-- حذف تاریخچه پرداخت
|
|
DELETE FROM CMS.CommissionPayoutHistories
|
|
WHERE UserCommissionPayoutId IN (SELECT Id FROM CMS.UserCommissionPayouts WHERE WeeklyPoolId = @PoolId);
|
|
|
|
-- حذف پرداختهای قبلی این Pool
|
|
DELETE FROM CMS.UserCommissionPayouts WHERE WeeklyPoolId = @PoolId;
|
|
|
|
-- 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
|
|
-- بالانسی محاسبه نشده — pool را به عنوان "محاسبه شده بدون پرداخت" علامت میزنیم
|
|
UPDATE CMS.WeeklyCommissionPools
|
|
SET IsCalculated = 1, CalculatedAt = @CalculatedAt
|
|
WHERE Id = @PoolId;
|
|
|
|
COMMIT TRANSACTION;
|
|
RETURN;
|
|
END
|
|
|
|
-- =============================================
|
|
-- 5. محاسبه مجموع تعادلها
|
|
-- =============================================
|
|
SELECT @TotalBalances = SUM(TotalBalances)
|
|
FROM CMS.NetworkWeeklyBalances
|
|
WHERE WeekDefinitionId = @WeekDefinitionId AND TotalBalances > 0;
|
|
|
|
IF @TotalBalances IS NULL OR @TotalBalances = 0
|
|
BEGIN
|
|
-- هیچ تعادلی برای توزیع وجود ندارد — pool محاسبه شده اما پرداختی ندارد
|
|
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,
|
|
cp.UserId,
|
|
@WeekDefinitionId,
|
|
0,
|
|
cp.TotalAmount,
|
|
0, -- OldStatus: Pending
|
|
0, -- NewStatus: Pending
|
|
0, -- Action: Created
|
|
'SP',
|
|
N'محاسبه اولیه توسط SP',
|
|
0,
|
|
@CalculatedAt,
|
|
'SP',
|
|
@CalculatedAt,
|
|
'SP'
|
|
FROM CMS.UserCommissionPayouts cp
|
|
WHERE cp.WeeklyPoolId = @PoolId;
|
|
|
|
-- =============================================
|
|
-- 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.WeeklyPoolId = @PoolId;
|
|
|
|
-- ثبت لاگ تغییرات کیف پول
|
|
INSERT INTO CMS.UserWalletChangeLogs (
|
|
WalletId,
|
|
CurrentBalance,
|
|
ChangeValue,
|
|
CurrentNetworkBalance,
|
|
ChangeNerworkValue,
|
|
CurrentDiscountBalance,
|
|
ChangeDiscountValue,
|
|
IsIncrease,
|
|
RefrenceId,
|
|
IsDeleted,
|
|
Created,
|
|
CreatedBy,
|
|
LastModified,
|
|
LastModifiedBy
|
|
)
|
|
SELECT
|
|
uw.Id,
|
|
uw.Balance,
|
|
0, -- ChangeValue (no change to main balance)
|
|
uw.NetworkBalance, -- CurrentNetworkBalance (after update)
|
|
cp.TotalAmount, -- ChangeNerworkValue
|
|
uw.DiscountBalance,
|
|
0, -- ChangeDiscountValue
|
|
1, -- IsIncrease: true
|
|
cp.Id, -- RefrenceId: PayoutId
|
|
0,
|
|
@CalculatedAt,
|
|
'SP',
|
|
@CalculatedAt,
|
|
'SP'
|
|
FROM CMS.UserCommissionPayouts cp
|
|
INNER JOIN CMS.UserWallets uw ON uw.UserId = cp.UserId
|
|
WHERE cp.WeeklyPoolId = @PoolId;
|
|
|
|
-- =============================================
|
|
-- 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
|