From fa1e9c86b83ec68accad568ce4b1e7d8cfa0b86c Mon Sep 17 00:00:00 2001 From: GotthardG <51994228+GotthardG@users.noreply.github.com> Date: Tue, 19 Nov 2024 13:43:54 +0100 Subject: [PATCH] now associating a dewar to a slot --- backend/app/models.py | 8 ++++++- backend/app/routers/logistics.py | 35 ++++++++++++++++++++++++---- backend/app/schemas.py | 6 +++-- logistics/src/components/Storage.tsx | 10 -------- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/backend/app/models.py b/backend/app/models.py index 87bf5f6..914ac49 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -86,6 +86,7 @@ class Dewar(Base): dewar_type = relationship("DewarType") dewar_serial_number = relationship("DewarSerialNumber") + slot = relationship("Slot", back_populates="dewar") @property def number_of_pucks(self) -> int: @@ -144,6 +145,9 @@ class Slot(Base): needs_refill = Column(Boolean, default=False) last_refill = Column(DateTime, default=datetime.utcnow) time_until_refill = Column(Integer) # store as total seconds + dewar_unique_id = Column(String, ForeignKey('dewars.unique_id'), nullable=True) # Added field + dewar = relationship("Dewar", back_populates="slot") + @property def calculate_time_until_refill(self): @@ -151,6 +155,7 @@ class Slot(Base): return self.last_refill + self.time_until_refill - datetime.utcnow() return None + class LogisticsEvent(Base): __tablename__ = 'logistics_events' id = Column(Integer, primary_key=True, index=True, autoincrement=True) @@ -158,4 +163,5 @@ class LogisticsEvent(Base): event_type = Column(String, nullable=False) timestamp = Column(DateTime, default=datetime.utcnow) - dewar = relationship("Dewar", back_populates="events") \ No newline at end of file + dewar = relationship("Dewar", back_populates="events") + slot_id = Column(String, ForeignKey('slots.id'), nullable=True) \ No newline at end of file diff --git a/backend/app/routers/logistics.py b/backend/app/routers/logistics.py index f25edf9..1b7077a 100644 --- a/backend/app/routers/logistics.py +++ b/backend/app/routers/logistics.py @@ -1,22 +1,42 @@ from fastapi import APIRouter, HTTPException, Depends from sqlalchemy.orm import Session -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, Slot as SlotSchema, Dewar as DewarSchema from app.database import get_db import logging +from datetime import datetime, timedelta router = APIRouter() logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) +def calculate_time_until_refill(last_refill: datetime) -> int: + refill_interval = timedelta(hours=24) # Example interval + now = datetime.now() + time_until_next_refill = last_refill + refill_interval - now + return int(time_until_next_refill.total_seconds()) @router.get("/slots", response_model=List[SlotSchema]) async def get_all_slots(db: Session = Depends(get_db)): slots = db.query(SlotModel).all() - return slots + slots_with_refill_time = [] + for slot in slots: + slot_data = SlotSchema( + id=slot.id, + qr_code=slot.qr_code, + label=slot.label, + qr_base=slot.qr_base, + occupied=slot.occupied, + needs_refill=slot.needs_refill, + last_refill=slot.last_refill, + time_until_refill=calculate_time_until_refill(slot.last_refill), + dewar_unique_id=slot.dewar_unique_id, + dewar_name=slot.dewar.dewar_name if slot.dewar else None + ) + slots_with_refill_time.append(slot_data) + return slots_with_refill_time @router.get("/dewars", response_model=List[DewarSchema]) async def get_all_dewars(db: Session = Depends(get_db)): @@ -39,20 +59,25 @@ async def scan_dewar(event_data: LogisticsEventCreate, db: Session = Depends(get location_qr_code = event_data.location_qr_code transaction_type = event_data.transaction_type + print(f"Scanning dewar {dewar_qr_code} for slot {location_qr_code} with transaction type {transaction_type}") + dewar = db.query(DewarModel).filter(DewarModel.unique_id == dewar_qr_code).first() if not dewar: raise HTTPException(status_code=404, detail="Dewar not found") slot = db.query(SlotModel).filter(SlotModel.qr_code == location_qr_code).first() + if transaction_type == 'incoming': if not slot or slot.occupied: raise HTTPException(status_code=400, detail="Slot not found or already occupied") - slot.dewar_id = dewar.id + print(f"Associating dewar {dewar.unique_id} with slot {slot.qr_code}") + slot.dewar_unique_id = dewar.unique_id # Properly associate with the unique_id slot.occupied = True elif transaction_type == 'outgoing': - if not slot or not slot.occupied or slot.dewar_id != dewar.id: + if not slot or not slot.occupied or slot.dewar_unique_id != dewar.unique_id: raise HTTPException(status_code=400, detail="Slot not found or dewar not associated with slot") - slot.dewar_id = None + print(f"Disassociating dewar {dewar.unique_id} from slot {slot.qr_code}") + slot.dewar_unique_id = None # Remove the association slot.occupied = False log_event(db, dewar.id, slot.id if slot else None, transaction_type) diff --git a/backend/app/schemas.py b/backend/app/schemas.py index 2f29d41..b9b8db6 100644 --- a/backend/app/schemas.py +++ b/backend/app/schemas.py @@ -281,11 +281,13 @@ class Slot(BaseModel): id: str qr_code: str label: str - qr_base: str + qr_base: Optional[str] occupied: bool needs_refill: bool last_refill: datetime - time_until_refill: str + time_until_refill: int # Can't be Optional + dewar_unique_id: Optional[str] # Ensure this field exists + dewar_name: Optional[str] = None # Optional for convenience class Config: from_attributes = True \ No newline at end of file diff --git a/logistics/src/components/Storage.tsx b/logistics/src/components/Storage.tsx index 0cdb96f..566c67f 100644 --- a/logistics/src/components/Storage.tsx +++ b/logistics/src/components/Storage.tsx @@ -31,16 +31,11 @@ interface StorageProps { } const Storage: React.FC = ({ name, selectedSlot, slotsData, onSelectSlot }) => { - const [highlightedSlot, setHighlightedSlot] = useState(null); - const handleSlotSelect = (slot: SlotData) => { - setHighlightedSlot(slot); onSelectSlot(slot); console.log('Selected slot:', slot); }; - console.log("Rendering Storage Component with name:", name); - return ( {name} Slots @@ -54,11 +49,6 @@ const Storage: React.FC = ({ name, selectedSlot, slotsData, onSele /> ))} - {highlightedSlot && ( - - Selected Slot: {highlightedSlot.label} - - )} ); };