aaredb/backend/app/routers/logistics.py

107 lines
4.5 KiB
Python

from fastapi import APIRouter, HTTPException, Depends
from sqlalchemy.orm import Session
import logging
from datetime import datetime, timedelta
from typing import List
from app.models import Dewar as DewarModel, Slot as SlotModel, LogisticsEvent as LogisticsEventModel
from app.schemas import LogisticsEventCreate, SlotCreate, Slot as SlotSchema, Dewar as DewarSchema
from app.database import get_db
router = APIRouter()
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@router.get("/dewars", response_model=List[DewarSchema])
async def get_all_prouts(db: Session = Depends(get_db)):
try:
dewars = db.query(DewarModel).all()
logging.info(f"Retrieved {len(dewars)} dewars from the database")
return dewars
except Exception as e:
logger.error(f"An error occurred: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
@router.get("/dewar/{qr_code}", response_model=DewarSchema)
async def get_dewar_by_qr_code(qr_code: str, db: Session = Depends(get_db)):
logger.info(f"Received qr_code: {qr_code}")
trimmed_qr_code = qr_code.strip()
logger.info(f"Trimmed qr_code after stripping: {trimmed_qr_code}")
try:
dewar = db.query(DewarModel).filter(DewarModel.unique_id == trimmed_qr_code).first()
logger.info(f"Query Result: {dewar}")
if dewar:
return dewar
else:
logger.error(f"Dewar not found for unique_id: {trimmed_qr_code}")
raise HTTPException(status_code=404, detail="Dewar not found")
except Exception as e:
logger.error(f"An error occurred: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
@router.post("/dewar/scan", response_model=LogisticsEventCreate)
async def scan_dewar(event_data: LogisticsEventCreate, db: Session = Depends(get_db)):
dewar_qr_code = event_data.dewar_qr_code
location_qr_code = event_data.location_qr_code
transaction_type = event_data.transaction_type
try:
dewar = db.query(DewarModel).filter(DewarModel.unique_id == dewar_qr_code).first()
if not dewar:
raise HTTPException(status_code=404, detail="Dewar not found")
if transaction_type == 'incoming':
slot = db.query(SlotModel).filter(SlotModel.id == location_qr_code).first()
if not slot or slot.occupied:
raise HTTPException(status_code=404, detail="Slot not found or already occupied")
slot.occupied = True
log_event(db, dewar.id, slot.id, 'incoming')
elif transaction_type == 'beamline':
log_event(db, dewar.id, None, 'beamline')
elif transaction_type == 'outgoing':
slot = db.query(SlotModel).filter(SlotModel.id == location_qr_code).first()
if not slot or not slot.occupied:
raise HTTPException(status_code=404, detail="Slot not found or not occupied")
slot.occupied = False
log_event(db, dewar.id, slot.id, 'outgoing')
elif transaction_type == 'release':
slot = db.query(SlotModel).filter(SlotModel.id == location_qr_code).first()
if not slot or not slot.occupied:
raise HTTPException(status_code=404, detail="Slot not found or not occupied")
slot.occupied = False
log_event(db, dewar.id, slot.id, 'released')
db.commit()
logger.info(f"Status updated successfully for Dewar ID: {dewar.id}")
return {"message": "Status updated successfully"}
except Exception as e:
logger.error(f"An error occurred: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
def log_event(db: Session, dewar_id: int, slot_id: int, event_type: str):
new_event = LogisticsEventModel(dewar_id=dewar_id if dewar_id else None, slot_id=slot_id, event_type=event_type)
db.add(new_event)
db.commit()
logger.info(f"Logged event {event_type} for Dewar ID: {dewar_id}")
@router.get("/slots/refill-status", response_model=List[SlotSchema])
async def refill_status(db: Session = Depends(get_db)):
slots_needing_refill = db.query(SlotModel).filter(SlotModel.needs_refill == True).all()
result = []
current_time = datetime.utcnow()
for slot in slots_needing_refill:
time_until_next_refill = slot.last_refill + timedelta(hours=24) - current_time
result.append({
'slot_id': slot.id,
'needs_refill': slot.needs_refill,
'time_until_refill': str(time_until_next_refill)
})
return result