178 lines
7.2 KiB
Python
178 lines
7.2 KiB
Python
import logging
|
|
from django.db import models
|
|
from .models import Order, CommissionLog, Distributor
|
|
# To avoid circular imports, import other models inside function if needed
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def handle_post_payment(order):
|
|
"""
|
|
处理订单支付成功后的业务逻辑
|
|
包括:
|
|
1. 更新活动报名状态
|
|
2. 发送活动报名短信
|
|
3. 计算分销佣金
|
|
4. 发送普通订单短信
|
|
"""
|
|
print(f"开始处理订单 {order.id} 支付后逻辑...")
|
|
|
|
# 1. Handle Activity Signup
|
|
if hasattr(order, 'activity') and order.activity:
|
|
try:
|
|
# Use apps.get_model to avoid circular dependency
|
|
from django.apps import apps
|
|
ActivitySignup = apps.get_model('community', 'ActivitySignup')
|
|
|
|
signup = ActivitySignup.objects.filter(order=order).first()
|
|
|
|
# Fallback: try to find by user and activity if not found by order
|
|
if not signup and order.wechat_user:
|
|
print(f"Warning: ActivitySignup not found by order {order.id}, trying by user/activity")
|
|
signup = ActivitySignup.objects.filter(
|
|
user=order.wechat_user,
|
|
activity=order.activity,
|
|
status='unpaid'
|
|
).first()
|
|
if signup:
|
|
print(f"Found signup {signup.id} by user/activity, linking order...")
|
|
signup.order = order
|
|
signup.save()
|
|
|
|
if signup:
|
|
# Determine status based on activity setting
|
|
# Use the model method if available, otherwise manual logic
|
|
if hasattr(signup, 'check_payment_status'):
|
|
signup.check_payment_status()
|
|
print(f"活动报名状态已更新(check_payment_status): {signup.id} -> {signup.status}")
|
|
else:
|
|
new_status = 'confirmed' if signup.activity.auto_confirm else 'pending'
|
|
signup.status = new_status
|
|
signup.save()
|
|
print(f"活动报名状态已更新: {signup.id} -> {new_status}")
|
|
|
|
# Send Activity SMS
|
|
try:
|
|
from .sms_utils import notify_user_activity_signup_success
|
|
notify_user_activity_signup_success(order, signup)
|
|
except Exception as sms_e:
|
|
print(f"发送活动报名短信失败: {str(sms_e)}")
|
|
|
|
else:
|
|
print(f"Error: No ActivitySignup found for paid order {order.id}")
|
|
|
|
except Exception as e:
|
|
print(f"更新活动报名状态失败: {str(e)}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
|
|
# 2. 计算佣金 (旧版销售员系统 & 新版分销员系统)
|
|
try:
|
|
# 旧版销售员系统
|
|
salesperson = order.salesperson
|
|
if salesperson:
|
|
# 1. 计算直接佣金 (一级)
|
|
# 优先级: 产品独立分润比例 > 销售员个人分润比例
|
|
rate_1 = 0
|
|
if order.config:
|
|
rate_1 = order.config.commission_rate if order.config.commission_rate > 0 else salesperson.commission_rate
|
|
elif order.course:
|
|
# 课程暂时使用销售员默认比例
|
|
rate_1 = salesperson.commission_rate
|
|
|
|
amount_1 = order.total_price * rate_1
|
|
|
|
if amount_1 > 0:
|
|
CommissionLog.objects.create(
|
|
order=order,
|
|
salesperson=salesperson,
|
|
amount=amount_1,
|
|
level=1,
|
|
status='pending'
|
|
)
|
|
print(f"生成一级佣金(Salesperson): {salesperson.name} - {amount_1}")
|
|
|
|
# 2. 计算上级佣金 (二级)
|
|
parent = salesperson.parent
|
|
if parent:
|
|
rate_2 = parent.second_level_rate
|
|
amount_2 = order.total_price * rate_2
|
|
|
|
if amount_2 > 0:
|
|
CommissionLog.objects.create(
|
|
order=order,
|
|
salesperson=parent,
|
|
amount=amount_2,
|
|
level=2,
|
|
status='pending'
|
|
)
|
|
print(f"生成二级佣金(Salesperson): {parent.name} - {amount_2}")
|
|
|
|
# 新版分销员系统
|
|
distributor = order.distributor
|
|
if distributor:
|
|
# 1. 计算直接佣金 (一级)
|
|
# 优先级: 产品独立分润比例 > 分销员个人分润比例
|
|
rate_1 = 0
|
|
if order.config:
|
|
rate_1 = order.config.commission_rate if order.config.commission_rate > 0 else distributor.commission_rate
|
|
elif order.course:
|
|
# 课程暂时使用分销员默认比例
|
|
rate_1 = distributor.commission_rate
|
|
|
|
amount_1 = order.total_price * rate_1
|
|
|
|
if amount_1 > 0:
|
|
CommissionLog.objects.create(
|
|
order=order,
|
|
distributor=distributor,
|
|
amount=amount_1,
|
|
level=1,
|
|
status='settled' # 简化流程,直接结算到余额
|
|
)
|
|
# 更新余额
|
|
distributor.total_earnings += amount_1
|
|
distributor.withdrawable_balance += amount_1
|
|
distributor.save()
|
|
print(f"生成一级佣金(Distributor): {distributor.user.nickname} - {amount_1}")
|
|
|
|
# 2. 计算上级佣金 (二级)
|
|
parent = distributor.parent
|
|
if parent:
|
|
# 二级固定比例 2% (0.02)
|
|
rate_2 = 0.02
|
|
amount_2 = order.total_price * models.DecimalField(max_digits=5, decimal_places=4).to_python(rate_2)
|
|
|
|
if amount_2 > 0:
|
|
CommissionLog.objects.create(
|
|
order=order,
|
|
distributor=parent,
|
|
amount=amount_2,
|
|
level=2,
|
|
status='settled'
|
|
)
|
|
# 更新余额
|
|
parent.total_earnings += amount_2
|
|
parent.withdrawable_balance += amount_2
|
|
parent.save()
|
|
print(f"生成二级佣金(Distributor): {parent.user.nickname} - {amount_2}")
|
|
|
|
except Exception as e:
|
|
print(f"佣金计算失败: {str(e)}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
|
|
# 3. 发送普通商品/课程购买的短信通知(排除活动报名,避免重复发送)
|
|
# 活动报名的短信已经在上面发送过了
|
|
if not (hasattr(order, 'activity') and order.activity):
|
|
try:
|
|
from .sms_utils import notify_admins_order_paid, notify_user_order_paid
|
|
notify_admins_order_paid(order)
|
|
notify_user_order_paid(order)
|
|
except Exception as e:
|
|
print(f"发送短信通知失败: {str(e)}")
|
|
else:
|
|
# 额外保险:如果是活动订单,手动标记不触发 signals 中的支付/发货通知
|
|
# 因为 signals 可能会在 save() 时触发
|
|
order._was_paid = False
|
|
order._was_shipped = False
|