From e341459590f2a73f1fe896cb2f39cc0f12ef710c Mon Sep 17 00:00:00 2001 From: GotthardG <51994228+GotthardG@users.noreply.github.com> Date: Wed, 7 May 2025 09:39:40 +0200 Subject: [PATCH] Update beamtime assignment logic for pucks and samples Simplified and unified beamtime assignment handling for pucks and samples in the backend. Enhanced the frontend to display detailed assignment state, including shift, date, and beamline, for both pucks and dewars. This ensures consistent and accurate state management across the application. --- backend/app/routers/dewar.py | 19 +++++-- backend/app/routers/puck.py | 15 +++-- frontend/src/components/Calendar.tsx | 85 +++++++++++++++++++++------- 3 files changed, 89 insertions(+), 30 deletions(-) diff --git a/backend/app/routers/dewar.py b/backend/app/routers/dewar.py index 5dd7b8c..ce7299e 100644 --- a/backend/app/routers/dewar.py +++ b/backend/app/routers/dewar.py @@ -595,14 +595,23 @@ async def assign_beamtime_to_dewar( db: Session = Depends(get_db), ): dewar = db.query(DewarModel).filter(DewarModel.id == dewar_id).first() - if not dewar: # <- Move check earlier! + if not dewar: raise HTTPException(status_code=404, detail="Dewar not found") - if beamtime_id == 0: - dewar.beamtime_id = None - else: - dewar.beamtime_id = beamtime_id + + dewar.beamtime_id = None if beamtime_id == 0 else beamtime_id db.commit() db.refresh(dewar) + for puck in dewar.pucks: + puck.beamtime_id = None if beamtime_id == 0 else beamtime_id + for sample in puck.samples: + has_sample_event = ( + db.query(SampleEvent).filter(SampleEvent.sample_id == sample.id).count() + > 0 + ) + if not has_sample_event: + sample.beamtime_id = None if beamtime_id == 0 else beamtime_id + + db.commit() return {"status": "success", "dewar_id": dewar.id, "beamtime_id": beamtime_id} diff --git a/backend/app/routers/puck.py b/backend/app/routers/puck.py index 953bd00..5da02dd 100644 --- a/backend/app/routers/puck.py +++ b/backend/app/routers/puck.py @@ -20,6 +20,7 @@ from app.models import ( Sample as SampleModel, LogisticsEvent as LogisticsEventModel, Dewar as DewarModel, + SampleEvent, ) from app.dependencies import get_db import logging @@ -669,10 +670,16 @@ async def assign_beamtime_to_puck( puck = db.query(PuckModel).filter(PuckModel.id == puck_id).first() if not puck: raise HTTPException(status_code=404, detail="Puck not found") - if beamtime_id == 0: - puck.beamtime_id = None - else: - puck.beamtime_id = beamtime_id + + puck.beamtime_id = None if beamtime_id == 0 else beamtime_id db.commit() db.refresh(puck) + # Update samples + for sample in puck.samples: + has_sample_event = ( + db.query(SampleEvent).filter(SampleEvent.sample_id == sample.id).count() > 0 + ) + if not has_sample_event: + sample.beamtime_id = None if beamtime_id == 0 else beamtime_id + db.commit() return {"status": "success", "puck_id": puck.id, "beamtime_id": beamtime_id} diff --git a/frontend/src/components/Calendar.tsx b/frontend/src/components/Calendar.tsx index 3c06b7c..cbd6945 100644 --- a/frontend/src/components/Calendar.tsx +++ b/frontend/src/components/Calendar.tsx @@ -268,12 +268,11 @@ const Calendar: React.FC = () => { return; } - // Find out if it's already assigned to this shift! + // Get current association state const prev = eventAssociations[selectedEventId] || { dewars: [], pucks: [] }; const isAssigned = prev.pucks.includes(puckId); if (!isAssigned) { - // Assign it immediately assignPuckToBeamtime(Number(puckId), Number(beamtimeId)) .then(() => { setEventAssociations(prevAssoc => { @@ -291,7 +290,6 @@ const Calendar: React.FC = () => { console.error("Failed to assign puck to beamtime", e); }); } else { - // Unassign (patch to None) immediately unassignPuckFromBeamtime(Number(puckId)) .then(() => { setEventAssociations(prevAssoc => { @@ -387,10 +385,8 @@ const Calendar: React.FC = () => {