feat: 罚款分红费率按俱乐部可读可配,接入提现设置
个人利率优先,其次 club_fadan_fenhong_lilv,再回退全局表;组队均摊仍按每张罚单金额×费率。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,9 +8,10 @@ from rest_framework.response import Response
|
|||||||
from backend.models import WithdrawalDailyStats
|
from backend.models import WithdrawalDailyStats
|
||||||
from config.models import TixianQuotaDefault
|
from config.models import TixianQuotaDefault
|
||||||
from jituan.constants import CLUB_ID_DEFAULT, DATA_SCOPE_ALL
|
from jituan.constants import CLUB_ID_DEFAULT, DATA_SCOPE_ALL
|
||||||
from jituan.models import ClubLilubiao, ClubTixianQuota, ClubWithdrawConfig
|
from jituan.models import ClubFadanFenhongLilv, ClubLilubiao, ClubTixianQuota, ClubWithdrawConfig
|
||||||
from jituan.services.club_config import get_commission_rate
|
from jituan.services.club_config import get_commission_rate
|
||||||
from jituan.services.club_context import resolve_club_id_from_request, resolve_club_scope
|
from jituan.services.club_context import resolve_club_id_from_request, resolve_club_scope
|
||||||
|
from orders.models import PenaltyBonusRate
|
||||||
|
|
||||||
# 提现手续费率 → lilubiao config_type / CommissionRate Platform
|
# 提现手续费率 → lilubiao config_type / CommissionRate Platform
|
||||||
LEIXING_RATE_KEY = {
|
LEIXING_RATE_KEY = {
|
||||||
@@ -22,6 +23,15 @@ LEIXING_RATE_KEY = {
|
|||||||
6: '10', # 商家余额
|
6: '10', # 商家余额
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 罚款分红身份(与 fadan_fenhong_lilv.shenfen 一致)
|
||||||
|
PENALTY_BONUS_SHENFEN = {
|
||||||
|
1: '客服',
|
||||||
|
2: '售后',
|
||||||
|
3: '管理员',
|
||||||
|
4: '店铺',
|
||||||
|
5: '商家',
|
||||||
|
}
|
||||||
|
|
||||||
# 提现身份 leixing → 平台日总限额配置 leixing(club_tixian_quota / TixianQuotaDefault UserType)
|
# 提现身份 leixing → 平台日总限额配置 leixing(club_tixian_quota / TixianQuotaDefault UserType)
|
||||||
WITHDRAW_TOTAL_QUOTA_LEIXING = {1: 4, 2: 5, 3: 6, 4: 7, 5: 8, 6: 9}
|
WITHDRAW_TOTAL_QUOTA_LEIXING = {1: 4, 2: 5, 3: 6, 4: 7, 5: 8, 6: 9}
|
||||||
|
|
||||||
@@ -70,6 +80,39 @@ def _set_lilv(club_id, config_type, rate):
|
|||||||
row.save(update_fields=['lilv', 'UpdateTime'])
|
row.save(update_fields=['lilv', 'UpdateTime'])
|
||||||
|
|
||||||
|
|
||||||
|
def _get_penalty_bonus_rate(club_id, shenfen):
|
||||||
|
"""有效罚款分红费率:俱乐部 > 全局表。"""
|
||||||
|
club_id = _normalize_club_id(club_id)
|
||||||
|
shenfen = int(shenfen)
|
||||||
|
row = ClubFadanFenhongLilv.query.filter(club_id=club_id, shenfen=shenfen).first()
|
||||||
|
if row is not None and row.lilv is not None:
|
||||||
|
return float(row.lilv)
|
||||||
|
try:
|
||||||
|
g = PenaltyBonusRate.objects.get(Identity=shenfen)
|
||||||
|
if g.Rate is not None:
|
||||||
|
return float(g.Rate)
|
||||||
|
except PenaltyBonusRate.DoesNotExist:
|
||||||
|
pass
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def _set_penalty_bonus_rate(club_id, shenfen, rate):
|
||||||
|
club_id = _normalize_club_id(club_id)
|
||||||
|
shenfen = int(shenfen)
|
||||||
|
row, created = ClubFadanFenhongLilv.query.get_or_create(
|
||||||
|
club_id=club_id,
|
||||||
|
shenfen=shenfen,
|
||||||
|
defaults={'lilv': rate},
|
||||||
|
)
|
||||||
|
if not created:
|
||||||
|
row.lilv = rate
|
||||||
|
row.save(update_fields=['lilv', 'UpdateTime'])
|
||||||
|
|
||||||
|
|
||||||
|
def get_penalty_bonus_rates_map(club_id):
|
||||||
|
return {s: _get_penalty_bonus_rate(club_id, s) for s in PENALTY_BONUS_SHENFEN}
|
||||||
|
|
||||||
|
|
||||||
def get_tixian_feilv(club_id, leixing):
|
def get_tixian_feilv(club_id, leixing):
|
||||||
"""读取提现手续费率(各俱乐部可不同)。"""
|
"""读取提现手续费率(各俱乐部可不同)。"""
|
||||||
rate_key = LEIXING_RATE_KEY.get(leixing)
|
rate_key = LEIXING_RATE_KEY.get(leixing)
|
||||||
@@ -176,6 +219,7 @@ def build_withdraw_settings_payload(request):
|
|||||||
'withdraw_mode': get_withdraw_mode(club_id),
|
'withdraw_mode': get_withdraw_mode(club_id),
|
||||||
'rates': rate_map,
|
'rates': rate_map,
|
||||||
'order_rates': order_rate_map,
|
'order_rates': order_rate_map,
|
||||||
|
'penalty_bonus_rates': get_penalty_bonus_rates_map(club_id),
|
||||||
'quotas': quota_map,
|
'quotas': quota_map,
|
||||||
'total_limits': total_limit_map,
|
'total_limits': total_limit_map,
|
||||||
'today_totals': today_totals,
|
'today_totals': today_totals,
|
||||||
@@ -189,6 +233,7 @@ def apply_withdraw_settings_update(request, permissions):
|
|||||||
club_id = _club_id(request)
|
club_id = _club_id(request)
|
||||||
rates = request.data.get('rates', {})
|
rates = request.data.get('rates', {})
|
||||||
order_rates = request.data.get('order_rates', request.data.get('commission_rates', {}))
|
order_rates = request.data.get('order_rates', request.data.get('commission_rates', {}))
|
||||||
|
penalty_bonus_rates = request.data.get('penalty_bonus_rates', {})
|
||||||
quotas = request.data.get('quotas', {})
|
quotas = request.data.get('quotas', {})
|
||||||
total_limits = request.data.get('total_limits', {})
|
total_limits = request.data.get('total_limits', {})
|
||||||
|
|
||||||
@@ -229,6 +274,15 @@ def apply_withdraw_settings_update(request, permissions):
|
|||||||
}
|
}
|
||||||
return Response({'code': 403, 'msg': f'无权限修改{order_names[role]}费率'})
|
return Response({'code': 403, 'msg': f'无权限修改{order_names[role]}费率'})
|
||||||
|
|
||||||
|
for shenfen in PENALTY_BONUS_SHENFEN:
|
||||||
|
if _rate_key_present(penalty_bonus_rates, shenfen) and not any(
|
||||||
|
p in permissions for p in ('5500a', '5500b', '5500c')
|
||||||
|
):
|
||||||
|
return Response({
|
||||||
|
'code': 403,
|
||||||
|
'msg': f'无权限修改{PENALTY_BONUS_SHENFEN[shenfen]}罚款分红费率',
|
||||||
|
})
|
||||||
|
|
||||||
for role in [1, 2, 3, 4, 5, 6]:
|
for role in [1, 2, 3, 4, 5, 6]:
|
||||||
val = rates.get(str(role), rates.get(role))
|
val = rates.get(str(role), rates.get(role))
|
||||||
if val is not None:
|
if val is not None:
|
||||||
@@ -239,6 +293,17 @@ def apply_withdraw_settings_update(request, permissions):
|
|||||||
if val is not None:
|
if val is not None:
|
||||||
_set_lilv(club_id, order_rate_code_map[role], Decimal(str(val)))
|
_set_lilv(club_id, order_rate_code_map[role], Decimal(str(val)))
|
||||||
|
|
||||||
|
for shenfen in PENALTY_BONUS_SHENFEN:
|
||||||
|
val = penalty_bonus_rates.get(str(shenfen), penalty_bonus_rates.get(shenfen))
|
||||||
|
if val is not None:
|
||||||
|
rate = Decimal(str(val))
|
||||||
|
if rate < 0 or rate > 1:
|
||||||
|
return Response({
|
||||||
|
'code': 400,
|
||||||
|
'msg': f'{PENALTY_BONUS_SHENFEN[shenfen]}罚款分红费率须在 0~1 之间(如 0.6 表示 60%)',
|
||||||
|
})
|
||||||
|
_set_penalty_bonus_rate(club_id, shenfen, rate)
|
||||||
|
|
||||||
for role in [1, 2, 3]:
|
for role in [1, 2, 3]:
|
||||||
if str(role) in quotas:
|
if str(role) in quotas:
|
||||||
val = quotas[str(role)]
|
val = quotas[str(role)]
|
||||||
|
|||||||
@@ -43,9 +43,22 @@ def _read_global_fenhong_rate(lilv_shenfen):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _read_club_fenhong_rate(club_id, lilv_shenfen):
|
||||||
|
"""俱乐部级罚款分红费率(club_fadan_fenhong_lilv)。"""
|
||||||
|
from jituan.models import ClubFadanFenhongLilv
|
||||||
|
|
||||||
|
club_id = _normalize_club_id(club_id)
|
||||||
|
row = ClubFadanFenhongLilv.query.filter(
|
||||||
|
club_id=club_id, shenfen=int(lilv_shenfen),
|
||||||
|
).first()
|
||||||
|
if row is not None and row.lilv is not None and Decimal(str(row.lilv)) > 0:
|
||||||
|
return row.lilv
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _get_fenhong_rate(fenhongzhe_id, fenhong_shenfen, lilv_shenfen, club_id='xq'):
|
def _get_fenhong_rate(fenhongzhe_id, fenhong_shenfen, lilv_shenfen, club_id='xq'):
|
||||||
"""
|
"""
|
||||||
获取分红利率:个人单独利率 > 0 时优先;否则回退全局 fadan_fenhong_lilv。
|
获取分红利率:个人单独利率 > 0 优先;否则俱乐部配置;再回退全局 fadan_fenhong_lilv。
|
||||||
"""
|
"""
|
||||||
club_id = _normalize_club_id(club_id)
|
club_id = _normalize_club_id(club_id)
|
||||||
try:
|
try:
|
||||||
@@ -61,6 +74,10 @@ def _get_fenhong_rate(fenhongzhe_id, fenhong_shenfen, lilv_shenfen, club_id='xq'
|
|||||||
except PenaltyBonus.DoesNotExist:
|
except PenaltyBonus.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
club_rate = _read_club_fenhong_rate(club_id, lilv_shenfen)
|
||||||
|
if club_rate is not None:
|
||||||
|
return club_rate
|
||||||
|
|
||||||
return _read_global_fenhong_rate(lilv_shenfen)
|
return _read_global_fenhong_rate(lilv_shenfen)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user