now associating a dewar to a slot

This commit is contained in:
GotthardG 2024-11-19 13:43:54 +01:00
parent 48fd2c3a7c
commit fa1e9c86b8
4 changed files with 41 additions and 18 deletions

View File

@ -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")
dewar = relationship("Dewar", back_populates="events")
slot_id = Column(String, ForeignKey('slots.id'), nullable=True)

View File

@ -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)

View File

@ -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

View File

@ -31,16 +31,11 @@ interface StorageProps {
}
const Storage: React.FC<StorageProps> = ({ name, selectedSlot, slotsData, onSelectSlot }) => {
const [highlightedSlot, setHighlightedSlot] = useState<SlotData | null>(null);
const handleSlotSelect = (slot: SlotData) => {
setHighlightedSlot(slot);
onSelectSlot(slot);
console.log('Selected slot:', slot);
};
console.log("Rendering Storage Component with name:", name);
return (
<StorageContainer>
<Typography variant="h5">{name} Slots</Typography>
@ -54,11 +49,6 @@ const Storage: React.FC<StorageProps> = ({ name, selectedSlot, slotsData, onSele
/>
))}
</StorageWrapper>
{highlightedSlot && (
<Typography variant="subtitle1">
Selected Slot: {highlightedSlot.label}
</Typography>
)}
</StorageContainer>
);
};