Files
Cheng Zhou 720c98765f 迁移合同费用通用附件
1、删除旧费用附件 API、CRUD、模型和专用前端面板,统一改用通用附件能力。

2、调整合同费用接口为 study_id 语义,并补充合同、凭证、发票等附件类型的权限映射。

3、将合同费用新建和编辑改为抽屉流程,详情页与列表页复用同一编辑组件。

4、补充数据库迁移、附件列表、合同费用抽屉和权限场景测试,覆盖旧权限移除与新流程。
2026-06-04 11:07:13 +08:00

41 lines
2.0 KiB
Python

from __future__ import annotations
from typing import Optional
import uuid
from datetime import date, datetime
from decimal import Decimal
from sqlalchemy import Date, DateTime, ForeignKey, Integer, Numeric, String, Text, UniqueConstraint, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base_class import Base
class ContractFee(Base):
__tablename__ = "contract_fees"
__table_args__ = (
UniqueConstraint("project_id", "center_id", name="uq_contract_fees_project_center"),
)
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
project_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("studies.id"), index=True, nullable=False)
center_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("sites.id"), index=True, nullable=False)
contract_no: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
signed_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True)
contract_amount: Mapped[Decimal] = mapped_column(Numeric(12, 2), nullable=False)
currency: Mapped[str] = mapped_column(String(10), nullable=False, default="CNY")
remark: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
contract_cases: Mapped[int] = mapped_column(Integer, nullable=False)
actual_cases: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
settlement_amount: Mapped[Optional[Decimal]] = mapped_column(Numeric(12, 2), nullable=True)
final_payment_amount: Mapped[Optional[Decimal]] = mapped_column(Numeric(12, 2), nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
)
@property
def study_id(self) -> uuid.UUID:
return self.project_id