2026-10-12 23:22:34 -04:00
|
|
|
|
"""发货模型:发货单与发货产品明细。
|
|
|
|
|
|
|
|
|
|
|
|
- ship_date 是**回款天数计算基准日**(对照表 #1:发货日首日计第 1 天),
|
|
|
|
|
|
回款指定本发货单后由 formula.payment_days 派生回款天数,不在本表落库
|
|
|
|
|
|
- 运费仅记录展示,不计入毛利润口径(对照表 #2)
|
|
|
|
|
|
- total_amount 为明细行汇总冗余,服务层事务内维护
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from datetime import date
|
|
|
|
|
|
from decimal import Decimal
|
|
|
|
|
|
|
|
|
|
|
|
from sqlalchemy import Date, ForeignKey, Index, Numeric, String
|
|
|
|
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
|
|
|
|
|
|
|
|
from app.models.base import (
|
|
|
|
|
|
BIGINT_UNSIGNED,
|
|
|
|
|
|
Base,
|
|
|
|
|
|
TimestampMixin,
|
|
|
|
|
|
TPlusSyncMixin,
|
|
|
|
|
|
mysql_table_args,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Shipment(Base, TimestampMixin, TPlusSyncMixin):
|
|
|
|
|
|
"""发货单表(需求 2.2.2):每笔发货对应一个业务,支持分批发货。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "shipments"
|
|
|
|
|
|
__table_args__ = mysql_table_args(
|
|
|
|
|
|
"发货单表(发货日为回款天数基准日,发货日首日计第 1 天)",
|
|
|
|
|
|
Index("idx_shipments_business_id", "business_id"),
|
|
|
|
|
|
Index("idx_shipments_ship_date", "ship_date"),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(
|
|
|
|
|
|
BIGINT_UNSIGNED, primary_key=True, autoincrement=True, comment="主键ID"
|
|
|
|
|
|
)
|
|
|
|
|
|
shipment_no: Mapped[str] = mapped_column(
|
|
|
|
|
|
String(32),
|
|
|
|
|
|
nullable=False,
|
|
|
|
|
|
unique=True,
|
|
|
|
|
|
comment="发货单号,自动生成 SH{YYYYMMDD}-{4位当日序号}(内部追溯用)",
|
|
|
|
|
|
)
|
|
|
|
|
|
business_id: Mapped[int] = mapped_column(
|
|
|
|
|
|
BIGINT_UNSIGNED,
|
|
|
|
|
|
ForeignKey("businesses.id", ondelete="RESTRICT"),
|
|
|
|
|
|
nullable=False,
|
|
|
|
|
|
comment="业务ID(businesses.id;终态业务禁止新发货)",
|
|
|
|
|
|
)
|
|
|
|
|
|
ship_date: Mapped[date] = mapped_column(
|
|
|
|
|
|
Date, nullable=False, comment="发货日期(回款天数基准日,发货日首日=第 1 天)"
|
|
|
|
|
|
)
|
2026-11-05 05:47:13 -05:00
|
|
|
|
freight_amount: Mapped[Decimal | None] = mapped_column(
|
2026-10-12 23:22:34 -04:00
|
|
|
|
Numeric(14, 2),
|
2026-11-05 05:47:13 -05:00
|
|
|
|
nullable=True,
|
2026-10-12 23:22:34 -04:00
|
|
|
|
comment="运费金额(仅记录展示;不计入毛利润口径,对照表 #2)",
|
|
|
|
|
|
)
|
|
|
|
|
|
total_amount: Mapped[Decimal] = mapped_column(
|
|
|
|
|
|
Numeric(14, 2),
|
|
|
|
|
|
nullable=False,
|
|
|
|
|
|
server_default="0",
|
|
|
|
|
|
comment="发货总金额(明细行汇总冗余,服务层事务内维护,禁手工直改)",
|
|
|
|
|
|
)
|
|
|
|
|
|
remark: Mapped[str | None] = mapped_column(String(255), comment="备注")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ShipmentItem(Base, TimestampMixin):
|
|
|
|
|
|
"""发货产品明细表(需求 2.2.2):记录发货的产品名称、规格、数量等。
|
|
|
|
|
|
|
|
|
|
|
|
价格口径两可(T+ 供价或人工录入,待 IT 确认):sale_price 可空人工补,
|
|
|
|
|
|
amount 由服务层按 数量×单价 计算固化。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "shipment_items"
|
|
|
|
|
|
__table_args__ = mysql_table_args(
|
|
|
|
|
|
"发货产品明细表",
|
|
|
|
|
|
Index("idx_shipment_items_shipment_id", "shipment_id"),
|
|
|
|
|
|
Index("idx_shipment_items_product_id", "product_id"),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(
|
|
|
|
|
|
BIGINT_UNSIGNED, primary_key=True, autoincrement=True, comment="主键ID"
|
|
|
|
|
|
)
|
|
|
|
|
|
shipment_id: Mapped[int] = mapped_column(
|
|
|
|
|
|
BIGINT_UNSIGNED,
|
|
|
|
|
|
ForeignKey("shipments.id", ondelete="RESTRICT"),
|
|
|
|
|
|
nullable=False,
|
|
|
|
|
|
comment="发货单ID(shipments.id)",
|
|
|
|
|
|
)
|
|
|
|
|
|
product_id: Mapped[int | None] = mapped_column(
|
|
|
|
|
|
BIGINT_UNSIGNED,
|
|
|
|
|
|
ForeignKey("products.id", ondelete="RESTRICT"),
|
|
|
|
|
|
comment="产品ID(products.id;NULL=自由录入)",
|
|
|
|
|
|
)
|
|
|
|
|
|
product_name: Mapped[str] = mapped_column(
|
|
|
|
|
|
String(128), nullable=False, comment="产品名称(引用产品时冗余固化)"
|
|
|
|
|
|
)
|
|
|
|
|
|
spec_model: Mapped[str] = mapped_column(
|
|
|
|
|
|
String(128),
|
|
|
|
|
|
nullable=False,
|
|
|
|
|
|
server_default="''",
|
|
|
|
|
|
comment="规格型号(冗余固化;空串对齐 products 组合唯一键口径)",
|
|
|
|
|
|
)
|
|
|
|
|
|
unit: Mapped[str | None] = mapped_column(String(16), comment="计量单位")
|
|
|
|
|
|
quantity: Mapped[Decimal] = mapped_column(
|
|
|
|
|
|
Numeric(14, 2), nullable=False, comment="发货数量(>0)"
|
|
|
|
|
|
)
|
|
|
|
|
|
sale_price: Mapped[Decimal | None] = mapped_column(
|
|
|
|
|
|
Numeric(14, 4), comment="发货单价(元;T+ 同步或人工,口径待 IT 确认)"
|
|
|
|
|
|
)
|
|
|
|
|
|
amount: Mapped[Decimal] = mapped_column(
|
|
|
|
|
|
Numeric(14, 2),
|
|
|
|
|
|
nullable=False,
|
|
|
|
|
|
comment="行金额 = 数量×单价(服务层计算固化,不信任前端传值)",
|
|
|
|
|
|
)
|