项目概览、参与者管理初步优化(未接入真实数据)
This commit is contained in:
+33
-12
@@ -6,6 +6,8 @@ from sqlalchemy import select, update as sa_update
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.crud import visit as visit_crud
|
||||
from app.models.study import Study
|
||||
from app.models.visit import Visit
|
||||
from app.models.site import Site
|
||||
from app.models.subject import Subject
|
||||
from app.schemas.subject import SubjectCreate, SubjectUpdate
|
||||
@@ -26,6 +28,7 @@ async def create_subject(db: AsyncSession, study_id: uuid.UUID, subject_in: Subj
|
||||
subject_no=subject_in.subject_no,
|
||||
status="SCREENING",
|
||||
screening_date=subject_in.screening_date,
|
||||
consent_date=subject_in.consent_date,
|
||||
enrollment_date=None,
|
||||
completion_date=None,
|
||||
drop_reason=None,
|
||||
@@ -41,7 +44,6 @@ async def create_subject(db: AsyncSession, study_id: uuid.UUID, subject_in: Subj
|
||||
visit_in=None,
|
||||
subject=subject,
|
||||
visit_code="V0",
|
||||
visit_name="Screening",
|
||||
planned_date=subject.screening_date,
|
||||
)
|
||||
return subject
|
||||
@@ -74,25 +76,44 @@ async def generate_default_visits(db: AsyncSession, subject: Subject) -> None:
|
||||
# Baseline + Follow-up visits based on enrollment_date
|
||||
if not subject.enrollment_date:
|
||||
return
|
||||
result = await db.execute(select(Study).where(Study.id == subject.study_id))
|
||||
study = result.scalar_one_or_none()
|
||||
if not study:
|
||||
return
|
||||
|
||||
visit_total = study.visit_total or 3
|
||||
visit_interval_days = study.visit_interval_days or 30
|
||||
window_start_offset = study.visit_window_start_offset
|
||||
window_end_offset = study.visit_window_end_offset
|
||||
baseline_date = subject.enrollment_date
|
||||
follow1 = baseline_date + timedelta(days=30)
|
||||
follow2 = baseline_date + timedelta(days=60)
|
||||
visits_data = [
|
||||
("V1", "Baseline", baseline_date),
|
||||
("FU1", "Follow-up 1", follow1),
|
||||
("FU2", "Follow-up 2", follow2),
|
||||
]
|
||||
for code, name, plan_date in visits_data:
|
||||
|
||||
result = await db.execute(select(Visit.visit_code).where(Visit.subject_id == subject.id))
|
||||
existing_codes = {row[0] for row in result.all()}
|
||||
if "V1" not in existing_codes:
|
||||
window_start = baseline_date + timedelta(days=window_start_offset) if window_start_offset is not None else None
|
||||
window_end = baseline_date + timedelta(days=window_end_offset) if window_end_offset is not None else None
|
||||
await visit_crud.create_visit(
|
||||
db,
|
||||
study_id=subject.study_id,
|
||||
visit_in=None,
|
||||
subject=subject,
|
||||
visit_code=code,
|
||||
visit_name=name,
|
||||
planned_date=plan_date,
|
||||
visit_code="V1",
|
||||
planned_date=baseline_date,
|
||||
window_start=window_start,
|
||||
window_end=window_end,
|
||||
)
|
||||
|
||||
await visit_crud.create_followup_visits(
|
||||
db,
|
||||
study_id=subject.study_id,
|
||||
subject=subject,
|
||||
base_date=baseline_date,
|
||||
visit_total=visit_total,
|
||||
visit_interval_days=visit_interval_days,
|
||||
window_start_offset=window_start_offset,
|
||||
window_end_offset=window_end_offset,
|
||||
)
|
||||
|
||||
|
||||
async def update_subject(db: AsyncSession, subject: Subject, subject_in: SubjectUpdate) -> Subject:
|
||||
update_data = subject_in.model_dump(exclude_unset=True)
|
||||
|
||||
Reference in New Issue
Block a user