176 lines
6.4 KiB
Python
176 lines
6.4 KiB
Python
import uuid
|
|
from datetime import date, timedelta
|
|
from decimal import Decimal
|
|
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.models.contract_fee import ContractFee
|
|
from app.models.contract_fee_payment import ContractFeePayment
|
|
from app.models.fee_attachment import FeeAttachment
|
|
from app.models.site import Site
|
|
from app.models.special_expense import SpecialExpense
|
|
from app.models.study import Study
|
|
from app.models.user import User
|
|
|
|
|
|
async def seed_demo_fees(db: AsyncSession) -> None:
|
|
existing_contract = await db.execute(select(ContractFee.id).limit(1))
|
|
existing_special = await db.execute(select(SpecialExpense.id).limit(1))
|
|
if existing_contract.scalar_one_or_none() or existing_special.scalar_one_or_none():
|
|
return
|
|
|
|
result = await db.execute(select(Study).order_by(Study.created_at.asc()))
|
|
study = result.scalars().first()
|
|
if not study:
|
|
study = Study(
|
|
id=uuid.uuid4(),
|
|
code="DEMO-CTMS",
|
|
name="示例临床试验项目",
|
|
sponsor="示例申办方",
|
|
status="ACTIVE",
|
|
)
|
|
db.add(study)
|
|
await db.commit()
|
|
await db.refresh(study)
|
|
|
|
result = await db.execute(select(Site).where(Site.study_id == study.id))
|
|
sites = result.scalars().all()
|
|
if len(sites) < 3:
|
|
for idx in range(3 - len(sites)):
|
|
site = Site(
|
|
id=uuid.uuid4(),
|
|
study_id=study.id,
|
|
name=f"示例中心 {len(sites) + idx + 1}",
|
|
city="上海",
|
|
pi_name="张医生",
|
|
contact="010-88888888",
|
|
)
|
|
db.add(site)
|
|
await db.commit()
|
|
result = await db.execute(select(Site).where(Site.study_id == study.id))
|
|
sites = result.scalars().all()
|
|
|
|
user_result = await db.execute(select(User).order_by(User.created_at.asc()))
|
|
uploader = user_result.scalars().first()
|
|
uploader_id = uploader.id if uploader else None
|
|
|
|
today = date.today()
|
|
for idx, site in enumerate(sites[:3], start=1):
|
|
contract = ContractFee(
|
|
id=uuid.uuid4(),
|
|
project_id=study.id,
|
|
center_id=site.id,
|
|
contract_amount=Decimal("120000.00") + Decimal(idx * 10000),
|
|
contract_cases=50 + idx * 5,
|
|
actual_cases=40 + idx * 4,
|
|
settlement_amount=Decimal("80000.00") + Decimal(idx * 5000),
|
|
final_payment_amount=Decimal("20000.00") + Decimal(idx * 2000),
|
|
)
|
|
db.add(contract)
|
|
await db.commit()
|
|
await db.refresh(contract)
|
|
|
|
payments = [
|
|
ContractFeePayment(
|
|
id=uuid.uuid4(),
|
|
contract_fee_id=contract.id,
|
|
seq=1,
|
|
amount=Decimal("40000.00") + Decimal(idx * 2000),
|
|
is_paid=True,
|
|
paid_date=today - timedelta(days=30),
|
|
is_verified=True,
|
|
verified_date=today - timedelta(days=20),
|
|
remark="首付款已核销",
|
|
),
|
|
ContractFeePayment(
|
|
id=uuid.uuid4(),
|
|
contract_fee_id=contract.id,
|
|
seq=2,
|
|
amount=Decimal("30000.00") + Decimal(idx * 1000),
|
|
is_paid=True,
|
|
paid_date=today - timedelta(days=10),
|
|
is_verified=False,
|
|
remark="等待核销",
|
|
),
|
|
ContractFeePayment(
|
|
id=uuid.uuid4(),
|
|
contract_fee_id=contract.id,
|
|
seq=3,
|
|
amount=Decimal("20000.00") + Decimal(idx * 1000),
|
|
is_paid=False,
|
|
remark="未打款",
|
|
),
|
|
]
|
|
db.add_all(payments)
|
|
await db.commit()
|
|
|
|
if uploader_id:
|
|
attachments = [
|
|
FeeAttachment(
|
|
id=uuid.uuid4(),
|
|
entity_type="contract_fee",
|
|
entity_id=contract.id,
|
|
file_type="contract",
|
|
filename=f"合同-{site.name}.pdf",
|
|
mime_type="application/pdf",
|
|
size=102400,
|
|
storage_key=None,
|
|
url="https://example.com/contract-demo.pdf",
|
|
uploaded_by=uploader_id,
|
|
),
|
|
FeeAttachment(
|
|
id=uuid.uuid4(),
|
|
entity_type="contract_fee",
|
|
entity_id=contract.id,
|
|
file_type="voucher",
|
|
filename=f"凭证-{site.name}.pdf",
|
|
mime_type="application/pdf",
|
|
size=20480,
|
|
storage_key=None,
|
|
url="https://example.com/voucher-demo.pdf",
|
|
uploaded_by=uploader_id,
|
|
),
|
|
]
|
|
db.add_all(attachments)
|
|
await db.commit()
|
|
|
|
categories = ["travel", "meal", "meeting", "supplies", "other"]
|
|
for idx, category in enumerate(categories):
|
|
for seq in range(2):
|
|
expense = SpecialExpense(
|
|
id=uuid.uuid4(),
|
|
project_id=study.id,
|
|
center_id=sites[seq % len(sites)].id if sites else None,
|
|
category=category,
|
|
amount=Decimal("800.00") + Decimal(seq * 150),
|
|
happen_date=today - timedelta(days=5 * (seq + 1)),
|
|
description=f"{category} 费用示例",
|
|
is_paid=seq % 2 == 0,
|
|
paid_date=today - timedelta(days=3 * (seq + 1)) if seq % 2 == 0 else None,
|
|
is_verified=seq == 0,
|
|
verified_date=today - timedelta(days=2 * (seq + 1)) if seq == 0 else None,
|
|
created_by=uploader_id,
|
|
)
|
|
db.add(expense)
|
|
await db.commit()
|
|
|
|
result = await db.execute(select(SpecialExpense).where(SpecialExpense.project_id == study.id))
|
|
expenses = result.scalars().all()
|
|
if uploader_id:
|
|
for expense in expenses[:3]:
|
|
attachment = FeeAttachment(
|
|
id=uuid.uuid4(),
|
|
entity_type="special_expense",
|
|
entity_id=expense.id,
|
|
file_type="invoice",
|
|
filename=f"发票-{expense.id}.pdf",
|
|
mime_type="application/pdf",
|
|
size=40960,
|
|
storage_key=None,
|
|
url="https://example.com/invoice-demo.pdf",
|
|
uploaded_by=uploader_id,
|
|
)
|
|
db.add(attachment)
|
|
await db.commit()
|