39 lines
1.5 KiB
Python
39 lines
1.5 KiB
Python
"""落账逻辑:按订单类型复用现有扣款+加仓 / 减仓+入账仓储方法。
|
||
|
||
供两处调用:未命中分支(申购/赎回接口)与放行处置(release)。不 commit,
|
||
由外层事务统一提交,保证「落账 + 写流水 / 改订单状态」原子性。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
||
from model.trade_order import TradeOrder
|
||
from repositories.fin_account import FinAccountRepo
|
||
from repositories.fin_holdings import FinHoldingsRepo
|
||
from utils.exceptions import ParamError
|
||
|
||
|
||
async def settle(db: AsyncSession, order: TradeOrder) -> None:
|
||
"""执行落账(申购扣款+加仓 / 赎回减仓+入账)。不 commit。
|
||
|
||
- 申购:余额不足返回 False 时抛 ParamError;
|
||
- 赎回:份额不足返回 False 时抛 ParamError。
|
||
"""
|
||
account_repo = FinAccountRepo(db)
|
||
holdings_repo = FinHoldingsRepo(db)
|
||
|
||
if order.order_type == "申购":
|
||
if not await account_repo.deduct_balance(order.customer_id, order.amount):
|
||
raise ParamError("可用余额不足")
|
||
await holdings_repo.upsert(
|
||
order.customer_id, order.product_id, order.shares, order.amount
|
||
)
|
||
elif order.order_type == "赎回":
|
||
if not await holdings_repo.redeem(
|
||
order.customer_id, order.product_id, order.shares
|
||
):
|
||
raise ParamError("可赎回份额不足")
|
||
await account_repo.credit_balance(order.customer_id, order.amount)
|
||
else:
|
||
raise ParamError(f"未知订单类型:{order.order_type}")
|