This commit is contained in:
aaron 2025-03-13 09:28:58 +08:00
parent 7019d0a62a
commit 8775148fab
3 changed files with 125 additions and 19 deletions

39
app/models/settlement.py Normal file
View File

@ -0,0 +1,39 @@
from sqlalchemy import Column, Integer, String, DateTime, JSON, Date, ForeignKey
from sqlalchemy.sql import func
from pydantic import BaseModel, Field
from typing import Optional, Dict, Any
from datetime import date, datetime
from .database import Base
from .community import CommunityDB
class SettlementHistoryDB(Base):
"""结算历史记录表"""
__tablename__ = "settlement_history"
id = Column(Integer, primary_key=True, autoincrement=True)
settle_date = Column(Date, nullable=False, index=True, comment="结算日期")
community_id = Column(Integer, ForeignKey("communities.id"), nullable=False, index=True, comment="小区ID")
community_name = Column(String(100), nullable=False, comment="小区名称")
settle_details = Column(JSON, nullable=False, comment="结算详情JSON格式")
create_time = Column(DateTime(timezone=True), server_default=func.now(), comment="创建时间")
class Config:
orm_mode = True
# Pydantic 模型
class SettlementHistoryCreate(BaseModel):
settle_date: date
community_id: int
community_name: str
settle_details: Dict[str, Any]
class SettlementHistoryInfo(BaseModel):
id: int
settle_date: date
community_id: int
community_name: str
settle_details: Dict[str, Any]
create_time: datetime
class Config:
from_attributes = True

View File

@ -15,8 +15,9 @@ from app.models.user import UserDB, UserRole
from app.models.community_set import CommunitySet
from app.models.community_set_mapping import CommunitySetMapping
from app.core.account import AccountManager
from app.models.settlement import SettlementHistoryDB
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
async def daily_community_order_statistics():
"""每日小区订单统计任务
@ -52,7 +53,7 @@ async def daily_community_order_statistics():
JOIN
communities c ON o.address_community_id = c.id
WHERE
o.create_time BETWEEN :start_time AND :end_time
o.completed_time BETWEEN :start_time AND :end_time
AND o.status = 'COMPLETED'
GROUP BY
c.id, c.name
@ -244,7 +245,26 @@ async def daily_partner_settlement():
total_original_amount = 0
total_final_amount = 0
settlement_history = []
for stat in yesterday_stats:
# 检查是否已存在该日期的结算记录
existing_settlement = db.query(SettlementHistoryDB).filter(
SettlementHistoryDB.settle_date == yesterday,
SettlementHistoryDB.community_id == stat.community_id,
).first()
if existing_settlement:
logger.info(f"小区 {stat.community_name} 已存在结算记录,跳过结算")
continue
# 结算明细
settle_details = {
"total_order_amount": stat.total_original_amount,
"total_pay_amount": stat.total_final_amount
}
print(f"日期:{stat.stats_date} 小区: {stat.community_name} 订单数: {stat.order_count} 订单金额: {stat.total_original_amount} 支付金额: {stat.total_final_amount}")
total_order_count += stat.order_count
total_original_amount += stat.total_original_amount
@ -274,48 +294,93 @@ async def daily_partner_settlement():
platform_profit_sharing = community.community_profit_sharing.platform_rate
# 计算运营商分成金额
per_partner_profit = stat.total_final_amount * (float(partner_profit_sharing) / len(partner_ids)) / 100
partner_profit = stat.total_final_amount * (float(partner_profit_sharing)) / 100
admin_profit = stat.total_final_amount * (float(admin_profit_sharing) / 100)
delivery_profit = stat.total_final_amount * (float(delivery_profit_sharing) / 100)
platform_profit = stat.total_final_amount * (float(platform_profit_sharing) / 100)
# 如果没有运营商、服务商,则需要沉淀到平台
profit_sediment = {
"partner_profit": partner_profit,
"admin_profit": admin_profit
}
# 计算每个运营商的分成金额
for partner_id in partner_ids:
partner_profit = per_partner_profit
print(f"运营商 {partner_id} 分成金额: {partner_profit}")
total_partner_profit += partner_profit
per_partner_profit = partner_profit / len(partner_ids)
print(f"运营商 {partner_id} 分成金额: {per_partner_profit}")
total_partner_profit += per_partner_profit
settle_details["partner_profit"] = {
"user_id": partner_id,
"profit": per_partner_profit
}
# 更新运营商账户余额
if partner_profit > 0:
if per_partner_profit > 0:
account_manager = AccountManager(db)
account_manager.change_balance(partner_id, partner_profit, f"{stat.community_name} 订单收益")
account_manager.change_balance(partner_id, per_partner_profit, f"{stat.community_name} 订单收益")
# 计算沉淀金额
profit_sediment["partner_profit"] -= per_partner_profit
# 计算服务商分成
admin_profit = stat.total_final_amount * (float(admin_profit_sharing) / 100)
print(f"服务商分成金额: {admin_profit}")
total_admin_profit += admin_profit
settle_details["admin_profit"] = {
"user_id": community.admin_id,
"profit": admin_profit
}
if admin_profit > 0 and community.admin_id and community.admin_id > 0:
account_manager = AccountManager(db)
account_manager.change_balance(community.admin_id, admin_profit, f"{stat.community_name} 订单收益")
else:
# 计算沉淀金额
profit_sediment["admin_profit"] -= admin_profit
# 计算配送员分成
delivery_profit = stat.total_final_amount * (float(delivery_profit_sharing) / 100)
print(f"配送员分成金额: {delivery_profit}")
total_delivery_profit += delivery_profit
# if delivery_profit > 0:
# account_manager = AccountManager(db)
# account_manager.change_balance(community.admin_id, delivery_profit, f"{stat.community_name} 订单收益")
settle_details["delivery_profit"] = {
"user_id": 0,
"profit": delivery_profit
}
# 计算平台分成
platform_profit = stat.total_final_amount * (float(platform_profit_sharing) / 100)
print(f"平台分成金额: {platform_profit}")
total_platform_profit += platform_profit
# 计算分成 + 沉淀金额
final_platform_profit = platform_profit + profit_sediment["partner_profit"] + profit_sediment["admin_profit"]
if platform_profit > 0:
print(f"平台分成 + 沉淀金额: {final_platform_profit}")
total_platform_profit += final_platform_profit
settle_details["platform_profit"] = {
"user_id": settings.PLATFORM_USER_ID,
"profit": final_platform_profit
}
if final_platform_profit > 0:
account_manager = AccountManager(db)
account_manager.change_balance(settings.PLATFORM_USER_ID, platform_profit, f"{stat.community_name} 订单收益")
account_manager.change_balance(settings.PLATFORM_USER_ID, final_platform_profit, f"{stat.community_name} 订单收益")
# 保存结算明细
settlement = SettlementHistoryDB(
settle_date=yesterday,
community_id=stat.community_id,
community_name=stat.community_name,
settle_details=settle_details
)
settlement_history.append(settlement)
db.add_all(settlement_history)
db.commit()
# 生成分润报告
message = f"""### {yesterday.strftime("%Y-%m-%d")} 分润报告
@ -327,7 +392,7 @@ async def daily_partner_settlement():
> - 支付总金额: {total_final_amount:.1f}
### 分润汇总
> - 合伙人分成: {total_partner_profit:.1f}
> - 运营商分成: {total_partner_profit:.1f}
> - 服务商分成: {total_admin_profit:.1f}
> - 配送员分成: {total_delivery_profit:.1f}
> - 平台分成: {total_platform_profit:.1f}
@ -341,6 +406,8 @@ async def daily_partner_settlement():
logger.info("每日合伙人结算报告已发送到企业微信")
except Exception as e:
logger.error(f"发送企业微信消息失败: {str(e)}")
except Exception as e:
db.rollback()
logger.error(f"运行每日合伙人结算任务失败: {str(e)}")

Binary file not shown.