费用管理内容优化-初步

This commit is contained in:
Cheng Zhou
2026-01-13 16:49:55 +08:00
parent 0c7c03069a
commit 1db36f40b0
43 changed files with 5229 additions and 26 deletions
+29
View File
@@ -0,0 +1,29 @@
import uuid
from datetime import datetime
from decimal import Decimal
from sqlalchemy import DateTime, ForeignKey, Integer, Numeric, 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_amount: Mapped[Decimal] = mapped_column(Numeric(12, 2), nullable=False)
contract_cases: Mapped[int] = mapped_column(Integer, nullable=False)
actual_cases: Mapped[int | None] = mapped_column(Integer, nullable=True)
settlement_amount: Mapped[Decimal | None] = mapped_column(Numeric(12, 2), nullable=True)
final_payment_amount: Mapped[Decimal | None] = 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()
)
@@ -0,0 +1,29 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from sqlalchemy import Boolean, Date, DateTime, ForeignKey, Integer, Numeric, Text, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base_class import Base
class ContractFeePayment(Base):
__tablename__ = "contract_fee_payments"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
contract_fee_id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True), ForeignKey("contract_fees.id"), index=True, nullable=False
)
seq: Mapped[int] = mapped_column(Integer, nullable=False)
amount: Mapped[Decimal] = mapped_column(Numeric(12, 2), nullable=False)
paid_date: Mapped[date | None] = mapped_column(Date, nullable=True)
verified_date: Mapped[date | None] = mapped_column(Date, nullable=True)
is_paid: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default="false")
is_verified: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default="false")
remark: Mapped[str | None] = mapped_column(Text, 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()
)
+25
View File
@@ -0,0 +1,25 @@
import uuid
from datetime import datetime
from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, Text, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base_class import Base
class FeeAttachment(Base):
__tablename__ = "fee_attachments"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
entity_type: Mapped[str] = mapped_column(String(50), nullable=False)
entity_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), nullable=False)
file_type: Mapped[str] = mapped_column(String(30), nullable=False)
filename: Mapped[str] = mapped_column(String(255), nullable=False)
mime_type: Mapped[str | None] = mapped_column(String(100), nullable=True)
size: Mapped[int] = mapped_column(Integer, nullable=False)
storage_key: Mapped[str | None] = mapped_column(String(500), nullable=True)
url: Mapped[str | None] = mapped_column(Text, nullable=True)
uploaded_by: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
uploaded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())
is_deleted: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default="false")
+30
View File
@@ -0,0 +1,30 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from sqlalchemy import Boolean, Date, DateTime, ForeignKey, Numeric, String, Text, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base_class import Base
class SpecialExpense(Base):
__tablename__ = "special_expenses"
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 | None] = mapped_column(UUID(as_uuid=True), ForeignKey("sites.id"), index=True, nullable=True)
category: Mapped[str] = mapped_column(String(50), nullable=False)
amount: Mapped[Decimal] = mapped_column(Numeric(12, 2), nullable=False)
happen_date: Mapped[date | None] = mapped_column(Date, nullable=True)
description: Mapped[str | None] = mapped_column(Text, nullable=True)
is_paid: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default="false")
paid_date: Mapped[date | None] = mapped_column(Date, nullable=True)
is_verified: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default="false")
verified_date: Mapped[date | None] = mapped_column(Date, nullable=True)
created_by: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True), ForeignKey("users.id"), 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()
)