根据审查结果统一以物抵顶的线下核实口径,移除当前模型、初始化脚本和前端接口中的自动折算误导文案。\n补充业务接入必须持有共享 T+ 命名锁的执行契约,明确来源快照稳定性依赖。\nWindows 部署说明区分新 supervisor 与旧任务迁移检查,避免现场并行启动旧 worker。\n\n影响范围:T+ 托管文档、业务接入契约、回款/台账模型注释和参数试算说明。\n\nCo-Authored-By: Claude Code <noreply@anthropic.com>
90 lines
3.9 KiB
Python
90 lines
3.9 KiB
Python
"""回款模型:回款记录与批次追溯。
|
||
|
||
- shipment_id 为**手动指定**的发货批次(对照表 #18):可空=暂未指定;
|
||
必须与 business_id 同属一个业务(服务层强校验,无数据库级约束可表达
|
||
跨表同属关系);指定后回款天数方可由 formula.payment_days 派生
|
||
- settlement_status 是 **M3 核算防重锚点**(需规 2.3.3「每笔回款仅核算一次,
|
||
台账记录核销状态」):预置于本表避免 M3 反向迁移改 M2 表;M3 台账建立后
|
||
由核算服务写入,M2 仅维护 0(未核算)
|
||
- receipt_date 是 M3 参数版本匹配日(对照表 #11:按回款到账日取时点参数)
|
||
- 一期禁负数金额(≥0):红字/退款冲销需求出现时先补设计再放开
|
||
"""
|
||
|
||
from datetime import date, datetime
|
||
from decimal import Decimal
|
||
|
||
from sqlalchemy import Date, DateTime, ForeignKey, Index, Numeric, String
|
||
from sqlalchemy.orm import Mapped, mapped_column
|
||
|
||
from app.models.base import (
|
||
BIGINT_UNSIGNED,
|
||
TINYINT_TYPE,
|
||
Base,
|
||
TimestampMixin,
|
||
TPlusSyncMixin,
|
||
mysql_table_args,
|
||
)
|
||
|
||
# 绩效核算状态(receipts.settlement_status)
|
||
SETTLEMENT_PENDING = 0
|
||
SETTLEMENT_DONE = 1
|
||
|
||
|
||
class Receipt(Base, TimestampMixin, TPlusSyncMixin):
|
||
"""回款表(需求 2.2.3):按业务登记到账款项,批次号系统内唯一。"""
|
||
|
||
__tablename__ = "receipts"
|
||
__table_args__ = mysql_table_args(
|
||
"回款表(手动指定发货批次;已核算回款禁改禁删)",
|
||
Index("idx_receipts_business_id", "business_id"),
|
||
Index("idx_receipts_receipt_date", "receipt_date"),
|
||
Index("idx_receipts_settlement_status", "settlement_status"),
|
||
Index("idx_receipts_shipment_id", "shipment_id"),
|
||
)
|
||
|
||
id: Mapped[int] = mapped_column(
|
||
BIGINT_UNSIGNED, primary_key=True, autoincrement=True, comment="主键ID"
|
||
)
|
||
receipt_batch_no: Mapped[str] = mapped_column(
|
||
String(32),
|
||
nullable=False,
|
||
unique=True,
|
||
comment="回款批次号,自动生成 HK{YYYYMMDD}-{4位当日序号}(系统内唯一;T+ 同步回款以 source_no 幂等)",
|
||
)
|
||
business_id: Mapped[int] = mapped_column(
|
||
BIGINT_UNSIGNED,
|
||
ForeignKey("businesses.id", ondelete="RESTRICT"),
|
||
nullable=False,
|
||
comment="业务ID(businesses.id)",
|
||
)
|
||
shipment_id: Mapped[int | None] = mapped_column(
|
||
BIGINT_UNSIGNED,
|
||
ForeignKey("shipments.id", ondelete="RESTRICT"),
|
||
comment="发货单ID(shipments.id;手动指定的回款对应批次,须与本行业务一致;NULL=暂未指定)",
|
||
)
|
||
receipt_date: Mapped[date] = mapped_column(
|
||
Date, nullable=False, comment="回款到账日(M3 按此日匹配参数版本,对照表 #11)"
|
||
)
|
||
amount: Mapped[Decimal] = mapped_column(
|
||
Numeric(14, 2), nullable=False, comment="回款金额(≥0;一期禁负数/红字)"
|
||
)
|
||
is_barter: Mapped[int] = mapped_column(
|
||
TINYINT_TYPE,
|
||
nullable=False,
|
||
server_default="0",
|
||
comment="以物抵顶标记:1是 0否(特殊绩效线下核实,系统不自动折算)",
|
||
)
|
||
settlement_status: Mapped[int] = mapped_column(
|
||
TINYINT_TYPE,
|
||
nullable=False,
|
||
server_default="0",
|
||
comment="绩效核算状态:0未核算 1已核算(M3 核算防重锚点;已核算回款禁改禁删)",
|
||
)
|
||
confirmation_status: Mapped[int] = mapped_column(
|
||
TINYINT_TYPE, nullable=False, server_default="0", comment="人工确认状态:0待确认 1已确认,独立于凭证及核算状态"
|
||
)
|
||
confirmed_by: Mapped[str | None] = mapped_column(String(64), comment="人工确认人账号快照")
|
||
confirmed_at: Mapped[datetime | None] = mapped_column(DateTime, comment="人工确认时间")
|
||
confirmed_revision: Mapped[str | None] = mapped_column(String(64), comment="人工确认时回款关键内容指纹")
|
||
remark: Mapped[str | None] = mapped_column(String(255), comment="备注")
|