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