Fix formatting with black
This commit is contained in:
@@ -2,7 +2,11 @@ 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
|
||||
from ..models import (
|
||||
Dewar as DewarModel,
|
||||
Slot as SlotModel,
|
||||
LogisticsEvent as LogisticsEventModel,
|
||||
)
|
||||
from ..schemas import LogisticsEventCreate, SlotSchema, Dewar as DewarSchema
|
||||
from ..database import get_db
|
||||
import logging
|
||||
@@ -14,7 +18,9 @@ logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def calculate_time_until_refill(last_refill: Optional[datetime], refill_interval_hours: int = 1) -> int:
|
||||
def calculate_time_until_refill(
|
||||
last_refill: Optional[datetime], refill_interval_hours: int = 1
|
||||
) -> int:
|
||||
refill_interval = timedelta(hours=refill_interval_hours)
|
||||
now = datetime.now()
|
||||
|
||||
@@ -27,30 +33,54 @@ def calculate_time_until_refill(last_refill: Optional[datetime], refill_interval
|
||||
|
||||
@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}")
|
||||
logger.info(
|
||||
f"Returning dewar to storage: {data.dewar_qr_code} at location {data.location_qr_code}"
|
||||
)
|
||||
|
||||
try:
|
||||
# Log the incoming payload
|
||||
logger.info("Received payload: %s", data.json())
|
||||
|
||||
dewar = db.query(DewarModel).filter(DewarModel.unique_id == data.dewar_qr_code).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")
|
||||
|
||||
original_slot = db.query(SlotModel).filter(SlotModel.dewar_unique_id == data.dewar_qr_code).first()
|
||||
original_slot = (
|
||||
db.query(SlotModel)
|
||||
.filter(SlotModel.dewar_unique_id == data.dewar_qr_code)
|
||||
.first()
|
||||
)
|
||||
if original_slot and original_slot.qr_code != data.location_qr_code:
|
||||
logger.error(f"Dewar {data.dewar_qr_code} is associated with slot {original_slot.qr_code}")
|
||||
raise HTTPException(status_code=400, detail=f"Dewar {data.dewar_qr_code} is associated with a different slot {original_slot.qr_code}.")
|
||||
logger.error(
|
||||
f"Dewar {data.dewar_qr_code} is associated with slot {original_slot.qr_code}"
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Dewar {data.dewar_qr_code} is associated with a different slot {original_slot.qr_code}.",
|
||||
)
|
||||
|
||||
slot = db.query(SlotModel).filter(SlotModel.qr_code == data.location_qr_code).first()
|
||||
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")
|
||||
|
||||
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")
|
||||
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
|
||||
@@ -61,7 +91,9 @@ async def return_to_storage(data: LogisticsEventCreate, db: Session = Depends(ge
|
||||
log_event(db, dewar.id, slot.id, "returned")
|
||||
db.commit()
|
||||
|
||||
logger.info(f"Dewar {data.dewar_qr_code} successfully returned to storage slot {slot.qr_code}.")
|
||||
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:
|
||||
@@ -71,6 +103,7 @@ async def return_to_storage(data: LogisticsEventCreate, db: Session = Depends(ge
|
||||
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)):
|
||||
logger.info(f"Received event data: {event_data}")
|
||||
@@ -82,7 +115,9 @@ async def scan_dewar(event_data: LogisticsEventCreate, db: Session = Depends(get
|
||||
# Validate Dewar QR Code
|
||||
if not dewar_qr_code or not dewar_qr_code.strip():
|
||||
logger.error("Dewar QR Code is null or empty")
|
||||
raise HTTPException(status_code=422, detail="Dewar QR Code cannot be null or empty")
|
||||
raise HTTPException(
|
||||
status_code=422, detail="Dewar QR Code cannot be null or empty"
|
||||
)
|
||||
|
||||
# Retrieve the Dewar
|
||||
dewar = db.query(DewarModel).filter(DewarModel.unique_id == dewar_qr_code).first()
|
||||
@@ -92,31 +127,42 @@ async def scan_dewar(event_data: LogisticsEventCreate, db: Session = Depends(get
|
||||
|
||||
# Check for Outgoing QR Codes and set transaction type
|
||||
if location_qr_code in ["Outgoing X10-SA", "Outgoing X06-SA"]:
|
||||
transaction_type = 'outgoing'
|
||||
transaction_type = "outgoing"
|
||||
|
||||
# Retrieve the Slot associated with the Dewar (for outgoing)
|
||||
slot = None
|
||||
if transaction_type == 'outgoing':
|
||||
slot = db.query(SlotModel).filter(SlotModel.dewar_unique_id == dewar.unique_id).first()
|
||||
if transaction_type == "outgoing":
|
||||
slot = (
|
||||
db.query(SlotModel)
|
||||
.filter(SlotModel.dewar_unique_id == dewar.unique_id)
|
||||
.first()
|
||||
)
|
||||
if not slot:
|
||||
logger.error(f"No slot associated with dewar for outgoing: {dewar_qr_code}")
|
||||
raise HTTPException(status_code=404, detail="No slot associated with dewar for outgoing")
|
||||
raise HTTPException(
|
||||
status_code=404, detail="No slot associated with dewar for outgoing"
|
||||
)
|
||||
|
||||
# Incoming Logic
|
||||
if transaction_type == 'incoming':
|
||||
if transaction_type == "incoming":
|
||||
slot = db.query(SlotModel).filter(SlotModel.qr_code == location_qr_code).first()
|
||||
if not slot or slot.occupied:
|
||||
logger.error(f"Slot not found or already occupied: {location_qr_code}")
|
||||
raise HTTPException(status_code=400, detail="Slot not found or already occupied")
|
||||
raise HTTPException(
|
||||
status_code=400, detail="Slot not found or already occupied"
|
||||
)
|
||||
slot.dewar_unique_id = dewar.unique_id
|
||||
slot.occupied = True
|
||||
elif transaction_type == 'outgoing':
|
||||
elif transaction_type == "outgoing":
|
||||
if not slot.occupied or slot.dewar_unique_id != dewar.unique_id:
|
||||
logger.error(f"Slot not valid for outgoing: {location_qr_code}")
|
||||
raise HTTPException(status_code=400, detail="Dewar not associated with the slot for outgoing")
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Dewar not associated with the slot for outgoing",
|
||||
)
|
||||
slot.dewar_unique_id = None
|
||||
slot.occupied = False
|
||||
elif transaction_type == 'beamline':
|
||||
elif transaction_type == "beamline":
|
||||
slot = db.query(SlotModel).filter(SlotModel.qr_code == location_qr_code).first()
|
||||
if not slot:
|
||||
logger.error(f"Beamline location not found: {location_qr_code}")
|
||||
@@ -128,10 +174,12 @@ async def scan_dewar(event_data: LogisticsEventCreate, db: Session = Depends(get
|
||||
log_event(db, dewar.id, slot.id if slot else None, transaction_type)
|
||||
db.commit()
|
||||
logger.info(
|
||||
f"Transaction completed: {transaction_type} for dewar {dewar_qr_code} in slot {slot.qr_code if slot else 'N/A'}")
|
||||
f"Transaction completed: {transaction_type} for dewar {dewar_qr_code} in slot {slot.qr_code if slot else 'N/A'}"
|
||||
)
|
||||
|
||||
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()
|
||||
@@ -147,14 +195,16 @@ async def get_all_slots(db: Session = Depends(get_db)):
|
||||
|
||||
if slot.dewar_unique_id:
|
||||
# Calculate time until refill
|
||||
last_refill_event = db.query(LogisticsEventModel) \
|
||||
.join(DewarModel, DewarModel.id == LogisticsEventModel.dewar_id) \
|
||||
last_refill_event = (
|
||||
db.query(LogisticsEventModel)
|
||||
.join(DewarModel, DewarModel.id == LogisticsEventModel.dewar_id)
|
||||
.filter(
|
||||
DewarModel.unique_id == slot.dewar.unique_id,
|
||||
LogisticsEventModel.event_type == "refill"
|
||||
) \
|
||||
.order_by(LogisticsEventModel.timestamp.desc()) \
|
||||
DewarModel.unique_id == slot.dewar.unique_id,
|
||||
LogisticsEventModel.event_type == "refill",
|
||||
)
|
||||
.order_by(LogisticsEventModel.timestamp.desc())
|
||||
.first()
|
||||
)
|
||||
|
||||
if last_refill_event:
|
||||
last_refill = last_refill_event.timestamp
|
||||
@@ -163,21 +213,27 @@ async def get_all_slots(db: Session = Depends(get_db)):
|
||||
time_until_refill = -1
|
||||
|
||||
# Fetch the latest beamline event
|
||||
last_beamline_event = db.query(LogisticsEventModel) \
|
||||
.join(DewarModel, DewarModel.id == LogisticsEventModel.dewar_id) \
|
||||
last_beamline_event = (
|
||||
db.query(LogisticsEventModel)
|
||||
.join(DewarModel, DewarModel.id == LogisticsEventModel.dewar_id)
|
||||
.filter(
|
||||
DewarModel.unique_id == slot.dewar.unique_id,
|
||||
LogisticsEventModel.event_type == "beamline"
|
||||
) \
|
||||
.order_by(LogisticsEventModel.timestamp.desc()) \
|
||||
DewarModel.unique_id == slot.dewar.unique_id,
|
||||
LogisticsEventModel.event_type == "beamline",
|
||||
)
|
||||
.order_by(LogisticsEventModel.timestamp.desc())
|
||||
.first()
|
||||
)
|
||||
|
||||
if last_beamline_event:
|
||||
# Set retrievedTimestamp to the timestamp of the beamline event
|
||||
retrievedTimestamp = last_beamline_event.timestamp.isoformat()
|
||||
|
||||
# Fetch the associated slot's label for beamlineLocation
|
||||
associated_slot = db.query(SlotModel).filter(SlotModel.id == last_beamline_event.slot_id).first()
|
||||
associated_slot = (
|
||||
db.query(SlotModel)
|
||||
.filter(SlotModel.id == last_beamline_event.slot_id)
|
||||
.first()
|
||||
)
|
||||
beamlineLocation = associated_slot.label if associated_slot else None
|
||||
|
||||
# Mark as being at a beamline
|
||||
@@ -204,7 +260,11 @@ async def get_all_slots(db: Session = Depends(get_db)):
|
||||
at_beamline=at_beamline,
|
||||
retrievedTimestamp=retrievedTimestamp,
|
||||
beamlineLocation=beamlineLocation,
|
||||
shipment_name=slot.dewar.shipment.shipment_name if slot.dewar and slot.dewar.shipment else None,
|
||||
shipment_name=(
|
||||
slot.dewar.shipment.shipment_name
|
||||
if slot.dewar and slot.dewar.shipment
|
||||
else None
|
||||
),
|
||||
contact_person=contact_person,
|
||||
local_contact="local contact placeholder",
|
||||
)
|
||||
@@ -214,7 +274,6 @@ async def get_all_slots(db: Session = Depends(get_db)):
|
||||
return slots_with_refill_time
|
||||
|
||||
|
||||
|
||||
@router.post("/dewar/refill", response_model=dict)
|
||||
async def refill_dewar(qr_code: str, db: Session = Depends(get_db)):
|
||||
logger.info(f"Refilling dewar with QR code: {qr_code}")
|
||||
@@ -236,9 +295,14 @@ async def refill_dewar(qr_code: str, db: Session = Depends(get_db)):
|
||||
db.commit()
|
||||
|
||||
time_until_refill_seconds = calculate_time_until_refill(now)
|
||||
logger.info(f"Dewar refilled successfully with time_until_refill: {time_until_refill_seconds}")
|
||||
logger.info(
|
||||
f"Dewar refilled successfully with time_until_refill: {time_until_refill_seconds}"
|
||||
)
|
||||
|
||||
return {"message": "Dewar refilled successfully", "time_until_refill": time_until_refill_seconds}
|
||||
return {
|
||||
"message": "Dewar refilled successfully",
|
||||
"time_until_refill": time_until_refill_seconds,
|
||||
}
|
||||
|
||||
|
||||
@router.get("/dewars", response_model=List[DewarSchema])
|
||||
@@ -250,7 +314,9 @@ async def get_all_dewars(db: Session = Depends(get_db)):
|
||||
@router.get("/dewar/{unique_id}", response_model=DewarSchema)
|
||||
async def get_dewar_by_unique_id(unique_id: str, db: Session = Depends(get_db)):
|
||||
logger.info(f"Received request for dewar with unique_id: {unique_id}")
|
||||
dewar = db.query(DewarModel).filter(DewarModel.unique_id == unique_id.strip()).first()
|
||||
dewar = (
|
||||
db.query(DewarModel).filter(DewarModel.unique_id == unique_id.strip()).first()
|
||||
)
|
||||
if not dewar:
|
||||
logger.warning(f"Dewar with unique_id '{unique_id}' not found.")
|
||||
raise HTTPException(status_code=404, detail="Dewar not found")
|
||||
@@ -263,8 +329,10 @@ def log_event(db: Session, dewar_id: int, slot_id: Optional[int], event_type: st
|
||||
dewar_id=dewar_id,
|
||||
slot_id=slot_id,
|
||||
event_type=event_type,
|
||||
timestamp=datetime.now()
|
||||
timestamp=datetime.now(),
|
||||
)
|
||||
db.add(new_event)
|
||||
db.commit()
|
||||
logger.info(f"Logged event: {event_type} for dewar: {dewar_id} in slot: {slot_id if slot_id else 'N/A'}")
|
||||
logger.info(
|
||||
f"Logged event: {event_type} for dewar: {dewar_id} in slot: {slot_id if slot_id else 'N/A'}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user