205 lines
6.6 KiB
Python
205 lines
6.6 KiB
Python
import logging
|
|
from datetime import date
|
|
from decimal import Decimal
|
|
|
|
from django.db import transaction
|
|
from django.db.models import F
|
|
|
|
from config.models import DailyIncomeStat, DailyPayoutStat
|
|
from orders.models import Order, PlatformOrderExt, MerchantOrderExt, CommissionRate
|
|
from products.models import Gsfenhong
|
|
from users.models import UserDashou, UserGuanshi
|
|
|
|
from backend.utils import update_guanshi_daily_by_action
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def get_order_user_id(order):
|
|
if order.Platform == 1:
|
|
try:
|
|
ext = PlatformOrderExt.objects.get(Order=order)
|
|
return ext.BossID
|
|
except PlatformOrderExt.DoesNotExist:
|
|
return None
|
|
elif order.Platform == 2:
|
|
try:
|
|
ext = MerchantOrderExt.objects.get(Order=order)
|
|
return ext.MerchantID
|
|
except MerchantOrderExt.DoesNotExist:
|
|
return None
|
|
return None
|
|
|
|
|
|
def update_daily_income(amount):
|
|
"""
|
|
原子更新当日收入统计(金额累加,笔数加1)。
|
|
用于微信支付成功回调。
|
|
|
|
参数:
|
|
amount: Decimal 本次收入金额
|
|
"""
|
|
today = date.today()
|
|
year, month, day = today.year, today.month, today.day
|
|
|
|
with transaction.atomic():
|
|
stat, created = DailyIncomeStat.objects.select_for_update().get_or_create(
|
|
date=today,
|
|
defaults={
|
|
'year': year,
|
|
'month': month,
|
|
'day': day,
|
|
'total_amount': amount,
|
|
'total_count': 1
|
|
}
|
|
)
|
|
if not created:
|
|
# 原子累加
|
|
stat.total_amount = F('total_amount') + amount
|
|
stat.total_count = F('total_count') + 1
|
|
stat.save(update_fields=['total_amount', 'total_count'])
|
|
|
|
logger.info(
|
|
f"每日收入更新: {today}, +{amount}元, 总金额={stat.total_amount if created else stat.total_amount + amount}, 总笔数={stat.total_count if created else stat.total_count + 1}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def update_daily_payout(amount):
|
|
"""
|
|
原子更新当日出款统计(金额累加,笔数加1)。
|
|
用于提现成功、结算打款等场景。
|
|
|
|
参数:
|
|
amount: Decimal 本次出款金额
|
|
"""
|
|
today = date.today()
|
|
year, month, day = today.year, today.month, today.day
|
|
|
|
with transaction.atomic():
|
|
stat, created = DailyPayoutStat.objects.select_for_update().get_or_create(
|
|
date=today,
|
|
defaults={
|
|
'year': year,
|
|
'month': month,
|
|
'day': day,
|
|
'total_amount': amount,
|
|
'total_count': 1
|
|
}
|
|
)
|
|
if not created:
|
|
# 原子累加
|
|
stat.total_amount = F('total_amount') + amount
|
|
stat.total_count = F('total_count') + 1
|
|
stat.save(update_fields=['total_amount', 'total_count'])
|
|
|
|
logger.info(f"每日出款更新: {today}, +{amount}元, 总金额={stat.total_amount if created else stat.total_amount + amount}, 总笔数={stat.total_count if created else stat.total_count + 1}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def calc_shangjia_order_fencheng(jine):
|
|
"""
|
|
商家发单时计算打手/管事分成。
|
|
打手优先:打手+管事 > 订单金额时,管事分成为 0。
|
|
"""
|
|
jine = Decimal(str(jine))
|
|
try:
|
|
lilu_obj = CommissionRate.objects.get(Platform='3')
|
|
rate_dashou = Decimal(str(lilu_obj.Rate)) if lilu_obj.Rate and lilu_obj.Rate > 0 else Decimal('1')
|
|
except CommissionRate.DoesNotExist:
|
|
rate_dashou = Decimal('1')
|
|
|
|
lilu_guanshi_obj = CommissionRate.objects.filter(Platform='13').first()
|
|
rate_guanshi = (
|
|
Decimal(str(lilu_guanshi_obj.Rate))
|
|
if lilu_guanshi_obj and lilu_guanshi_obj.Rate is not None
|
|
else Decimal('0')
|
|
)
|
|
|
|
dashou_fencheng = (jine * rate_dashou).quantize(Decimal('0.01'))
|
|
guanshi_raw = (jine * rate_guanshi).quantize(Decimal('0.01'))
|
|
|
|
if dashou_fencheng + guanshi_raw > jine:
|
|
guanshi_fencheng = Decimal('0.00')
|
|
else:
|
|
guanshi_fencheng = guanshi_raw
|
|
|
|
return dashou_fencheng, guanshi_fencheng
|
|
|
|
|
|
def settle_shangjia_order_guanshi_fenhong(order, dashou_id):
|
|
"""
|
|
商家订单结单时结算管事分红(幂等,失败不抛异常阻断主流程)。
|
|
"""
|
|
|
|
if getattr(order, 'Platform', None) != 2:
|
|
return
|
|
|
|
guanshi_fencheng = order.ManagerCommission or Decimal('0')
|
|
if guanshi_fencheng <= 0:
|
|
return
|
|
|
|
if Gsfenhong.objects.filter(dingdan_id=order.OrderID).exists():
|
|
logger.info(f"商家订单管事分红已处理: {order.OrderID}")
|
|
return
|
|
|
|
if not dashou_id:
|
|
return
|
|
|
|
try:
|
|
dashou = UserDashou.objects.select_related('user').get(user__UserUID=dashou_id)
|
|
except UserDashou.DoesNotExist:
|
|
logger.info(f"商家订单管事分红跳过: 打手{dashou_id}不存在")
|
|
return
|
|
|
|
guanshi_id = dashou.yaoqingren
|
|
if not guanshi_id:
|
|
logger.info(f"商家订单管事分红跳过: 打手{dashou_id}无邀请管事")
|
|
return
|
|
|
|
try:
|
|
with transaction.atomic():
|
|
guanshi = UserGuanshi.objects.select_for_update().get(user__UserUID=guanshi_id)
|
|
UserGuanshi.objects.filter(id=guanshi.id).update(
|
|
yue=F('yue') + guanshi_fencheng,
|
|
chongzhifenrun=F('chongzhifenrun') + guanshi_fencheng,
|
|
)
|
|
|
|
user_main = dashou.user
|
|
Gsfenhong.objects.create(
|
|
dingdan_id=order.OrderID,
|
|
guanshi=guanshi_id,
|
|
dashouid=dashou_id,
|
|
shuoming='商家订单分红',
|
|
fenhong=guanshi_fencheng,
|
|
avatar=user_main.avatar if user_main else None,
|
|
nicheng=dashou.nicheng or '未知打手',
|
|
fenhong_leixing=3,
|
|
)
|
|
logger.info(
|
|
f"商家订单管事分红成功: 订单{order.OrderID}, 管事{guanshi_id}, "
|
|
f"打手{dashou_id}, 金额{guanshi_fencheng}元"
|
|
)
|
|
except UserGuanshi.DoesNotExist:
|
|
logger.warning(f"商家订单管事分红跳过: 管事{guanshi_id}不存在")
|
|
return
|
|
except Exception as e:
|
|
logger.error(f"商家订单管事分红失败: {e}", exc_info=True)
|
|
return
|
|
|
|
try:
|
|
update_guanshi_daily_by_action(
|
|
yonghuid=guanshi_id,
|
|
action=3,
|
|
amount=guanshi_fencheng,
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"商家订单管事日统计更新失败: {e}")
|