crm-backend/utils/commons.py
2026-06-01 13:41:36 +03:30

112 lines
No EOL
6.5 KiB
Python

from main import settings
from utils.exceptions import UnprocessableEntity
from apps.payout.constans import TransferTypeChoices
import uuid
from utils.wallet_client import get_user_wallets
from django.utils.translation import gettext_lazy as _
from main import settings
def calculate_reward_wallet_commission(amount: int) -> int:
platform_commission = 0.01 * amount
platform_commission += platform_commission * 0.10
return int(platform_commission)
def calculate_platform_commission(amount: int) -> int:
platform_commission = 0.01 * amount
# platform_commission += platform_commission * 0.10 # disable Value Added Tax
return int(platform_commission)
def calculate_transfer_commission(amount: int, transfer_type: TransferTypeChoices) -> int:
commission = 0
if transfer_type == TransferTypeChoices.ACH:
if amount < 20000: # minimum settlement amount 20000
raise UnprocessableEntity(_('Minimum PAYA settlement amount is 2000 toman.'))
commission = settings.COMMISSION_ACH_RATE * amount
if commission < settings.COMMISSION_ACH_LOWER_BOUND:
commission = settings.COMMISSION_ACH_LOWER_BOUND
elif commission > settings.COMMISSION_ACH_UPPER_BOUND:
commission = settings.COMMISSION_ACH_UPPER_BOUND
elif transfer_type == TransferTypeChoices.RTGS:
if amount < 100000: # minimum settlement amount 100000
raise UnprocessableEntity(_('Minimum Real Time settlement amount is 10000 toman.'))
commission = settings.TOMAN_COMMISSION_RTGS_RATE * amount
if commission < settings.TOMAN_COMMISSION_RTGS_LOWER_BOUND:
commission = settings.TOMAN_COMMISSION_RTGS_LOWER_BOUND
elif commission > settings.TOMAN_COMMISSION_RTGS_UPPER_BOUND:
commission = settings.TOMAN_COMMISSION_RTGS_UPPER_BOUND
else:
raise UnprocessableEntity(_('Not a valid transfer type'))
return commission
def calculate_settlement_amounts(user_id: uuid, amount: int, transfer_type: TransferTypeChoices.choices) -> (int, int, int, int):
user_wallets = get_user_wallets(str(user_id), [settings.WALLET_RIAL, settings.WALLET_REWARD])
rial_wallet_balance = user_wallets[settings.WALLET_RIAL] if settings.WALLET_RIAL in user_wallets else 0
reward_wallet_balance = user_wallets[settings.WALLET_REWARD] if settings.WALLET_REWARD in user_wallets else 0
user_balance = rial_wallet_balance + reward_wallet_balance
if not user_balance:
raise UnprocessableEntity(_('settlement not possible for balance zero'))
commission = calculate_transfer_commission(amount, transfer_type)
if user_balance < amount: # required balance
raise UnprocessableEntity(_('settlement not possible for balance less than amount'))
amount -= commission
rial_commission = 0 if not rial_wallet_balance else commission if commission <= rial_wallet_balance else rial_wallet_balance
reward_commission = commission - rial_commission if rial_commission != commission else 0
rial_wallet_balance -= rial_commission
reward_wallet_balance -= reward_commission
rial_amount = 0 if not rial_wallet_balance else amount if amount <= rial_wallet_balance else rial_wallet_balance
reward_amount = amount - rial_amount if rial_amount != amount else 0
if reward_amount:
additional_reward_commission = calculate_reward_wallet_commission(reward_amount)
reward_commission += additional_reward_commission
reward_amount -= additional_reward_commission
return rial_amount, rial_commission, reward_amount, reward_commission
def calculate_settlement_amounts_by_transfer_commission_free(user_id: uuid, amount: int) -> (int, int, int, int):
user_wallets = get_user_wallets(str(user_id), [settings.WALLET_RIAL, settings.WALLET_REWARD])
rial_wallet_balance = user_wallets[settings.WALLET_RIAL] if settings.WALLET_RIAL in user_wallets else 0
reward_wallet_balance = user_wallets[settings.WALLET_REWARD] if settings.WALLET_REWARD in user_wallets else 0
user_balance = rial_wallet_balance + reward_wallet_balance
if not user_balance:
raise UnprocessableEntity(_('settlement not possible for balance zero'))
if user_balance < amount: # required balance
raise UnprocessableEntity(_('settlement not possible for balance less than amount'))
commission = calculate_platform_commission(amount) # transfer commission paid by platform
amount -= commission
rial_commission = 0 if not rial_wallet_balance else commission if commission <= rial_wallet_balance else rial_wallet_balance
reward_commission = commission - rial_commission if rial_commission != commission else 0
rial_wallet_balance -= rial_commission
reward_wallet_balance -= reward_commission
rial_amount = 0 if not rial_wallet_balance else amount if amount <= rial_wallet_balance else rial_wallet_balance
reward_amount = amount - rial_amount if rial_amount != amount else 0
return rial_amount, rial_commission, reward_amount, reward_commission
def calculate_settlement_amounts_by_transfer_commission_free_and_single_commission_transaction(user_id: uuid, amount: int) -> (int, int, int, int):
user_wallets = get_user_wallets(str(user_id), [settings.WALLET_RIAL, settings.WALLET_REWARD])
rial_wallet_balance = user_wallets[settings.WALLET_RIAL] if settings.WALLET_RIAL in user_wallets else 0
reward_wallet_balance = user_wallets[settings.WALLET_REWARD] if settings.WALLET_REWARD in user_wallets else 0
user_balance = rial_wallet_balance + reward_wallet_balance
if not user_balance:
raise UnprocessableEntity(_('settlement not possible for balance zero'))
if user_balance < amount: # required balance
raise UnprocessableEntity(_('settlement not possible for balance less than amount'))
commission = calculate_platform_commission(amount) # transfer commission paid by platform
amount -= commission
# requirement: commission transaction in single form instead of two transaction(if one has value!=0 other should be 0)
rial_commission = 0 if not rial_wallet_balance else commission if commission <= rial_wallet_balance else 0
reward_commission = 0 if not reward_wallet_balance else commission if not rial_commission and commission <= reward_wallet_balance else 0
rial_wallet_balance -= rial_commission
reward_wallet_balance -= reward_commission
rial_amount = 0 if not rial_wallet_balance else amount if amount <= rial_wallet_balance else rial_wallet_balance
reward_amount = amount - rial_amount if rial_amount != amount else 0
return rial_amount, rial_commission, reward_amount, reward_commission