can now return the dewar to its slot

This commit is contained in:
GotthardG
2024-11-28 10:09:28 +01:00
parent fbb868e255
commit a42124a56f
2 changed files with 35 additions and 43 deletions

View File

@ -87,6 +87,7 @@ class Dewar(Base):
dewar_serial_number = relationship("DewarSerialNumber")
slot = relationship("Slot", back_populates="dewar")
events = relationship("LogisticsEvent", back_populates="dewar")
beamline_location = None
@property
def number_of_pucks(self) -> int:

View File

@ -1,4 +1,5 @@
from fastapi import APIRouter, HTTPException, Depends
from pydantic import ValidationError
from sqlalchemy.orm import Session, joinedload
from typing import List, Optional
from ..models import Dewar as DewarModel, Slot as SlotModel, LogisticsEvent as LogisticsEventModel
@ -24,55 +25,46 @@ def calculate_time_until_refill(last_refill: Optional[datetime], refill_interval
return max(0, int(time_until_next_refill.total_seconds()))
@router.post("/dewars/retrieve", response_model=DewarSchema)
async def retrieve_or_return_dewar(data: LogisticsEventCreate, db: Session = Depends(get_db)):
logger.info(f"Received data for retrieve_or_return_dewar: {data}")
dewar = db.query(DewarModel).filter(DewarModel.unique_id == data.dewar_qr_code).first()
if not dewar:
raise HTTPException(status_code=404, detail="Dewar not found")
@router.post("/dewars/return", response_model=DewarSchema)
async def return_to_storage(data: LogisticsEventCreate, db: Session = Depends(get_db)):
logger.info(f"Returning dewar to storage: {data.dewar_qr_code} at location {data.location_qr_code}")
# Fetch the associated slot if it exists
slot = db.query(SlotModel).filter(SlotModel.qr_code == data.location_qr_code).first()
if not slot:
raise HTTPException(status_code=404, detail="Slot not found")
try:
# Log the incoming payload
logger.info("Received payload: %s", data.json())
# Check the last event for this dewar to determine the next action
last_event = db.query(LogisticsEventModel).filter(
LogisticsEventModel.dewar_id == dewar.id
).order_by(LogisticsEventModel.timestamp.desc()).first()
dewar = db.query(DewarModel).filter(DewarModel.unique_id == data.dewar_qr_code).first()
if not dewar:
logger.error(f"Dewar not found for unique ID: {data.dewar_qr_code}")
raise HTTPException(status_code=404, detail="Dewar not found")
if last_event and last_event.event_type == "retrieved":
# Create a 'returned' event if the last event was 'retrieved'
new_event = LogisticsEventModel(
dewar_id=dewar.id,
slot_id=slot.id,
event_type="returned",
timestamp=datetime.now(),
)
dewar.last_retrieved_timestamp = None
slot = db.query(SlotModel).filter(SlotModel.qr_code == data.location_qr_code).first()
if not slot:
logger.error(f"Slot not found for QR code: {data.location_qr_code}")
raise HTTPException(status_code=404, detail="Slot not found")
# Update the location to the slot
if slot.occupied and slot.dewar_unique_id != data.dewar_qr_code:
logger.error(f"Slot {data.location_qr_code} is already occupied by another dewar")
raise HTTPException(status_code=400, detail="Selected slot is already occupied by another dewar")
# Update slot with dewar information
slot.dewar_unique_id = dewar.unique_id
slot.occupied = True
dewar.last_retrieved_timestamp = None
# Log the event
log_event(db, dewar.id, slot.id, "returned")
db.commit()
logger.info(f"Dewar {dewar.unique_id} returned to slot {slot.qr_code} successfully.")
else:
# Create a 'retrieved' event
new_event = LogisticsEventModel(
dewar_id=dewar.id,
slot_id=None,
event_type="retrieved",
timestamp=datetime.now(),
)
dewar.last_retrieved_timestamp = new_event.timestamp.isoformat()
logger.info(f"Dewar {dewar.unique_id} retrieved successfully.")
db.add(new_event)
db.commit()
db.refresh(dewar)
return dewar
logger.info(f"Dewar {data.dewar_qr_code} successfully returned to storage slot {slot.qr_code}.")
db.refresh(dewar)
return dewar
except ValidationError as e:
logger.error(f"Validation error: {e.json()}")
raise HTTPException(status_code=400, detail="Invalid payload")
except Exception as e:
logger.error(f"Unexpected error: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
@router.post("/dewar/scan", response_model=dict)
async def scan_dewar(event_data: LogisticsEventCreate, db: Session = Depends(get_db)):
@ -109,13 +101,12 @@ async def scan_dewar(event_data: LogisticsEventCreate, db: Session = Depends(get
logger.error(f"Beamline location not found: {location_qr_code}")
raise HTTPException(status_code=400, detail="Beamline location not found")
dewar.beamline_location = location_qr_code
logger.info(f"Dewar {dewar_qr_code} assigned to beamline {location_qr_code}")
log_event(db, dewar.id, slot.id if slot else None, transaction_type)
db.commit()
return {"message": "Status updated successfully"}
@router.get("/slots", response_model=List[SlotSchema])
async def get_all_slots(db: Session = Depends(get_db)):
slots = db.query(SlotModel).options(joinedload(SlotModel.dewar)).all()