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()