Enhance Dewar handling and display in logistics system
Added new fields and enriched data representations in DewarStatusTab, backend schemas, and APIs to improve dewar tracking and management. Introduced new API endpoint `/dewar/table` for simplified data rendering. Applied logging and validations for missing relationships.
This commit is contained in:
@ -7,7 +7,14 @@ from ..models import (
|
||||
Slot as SlotModel,
|
||||
LogisticsEvent as LogisticsEventModel,
|
||||
)
|
||||
from ..schemas import LogisticsEventCreate, SlotSchema, Dewar as DewarSchema
|
||||
from ..schemas import (
|
||||
LogisticsEventCreate,
|
||||
SlotSchema,
|
||||
Dewar as DewarSchema,
|
||||
DewarTable,
|
||||
ContactMinimal,
|
||||
AddressMinimal,
|
||||
)
|
||||
from ..database import get_db
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
@ -342,6 +349,64 @@ async def get_all_dewars(db: Session = Depends(get_db)):
|
||||
return dewars
|
||||
|
||||
|
||||
@router.get("/dewar/table", response_model=List[DewarTable])
|
||||
async def get_all_dewars_table(db: Session = Depends(get_db)):
|
||||
dewars = db.query(DewarModel).all()
|
||||
|
||||
# Flatten relationships for simplified frontend rendering
|
||||
response = []
|
||||
for dewar in dewars:
|
||||
response.append(
|
||||
DewarTable(
|
||||
id=dewar.id,
|
||||
shipment_id=dewar.shipment_id
|
||||
if hasattr(dewar, "shipment_id")
|
||||
else None,
|
||||
dewar_name=dewar.dewar_name,
|
||||
shipment_name=dewar.shipment.shipment_name if dewar.shipment else "N/A",
|
||||
# Use the most recent event if available
|
||||
status=dewar.events[-1].event_type if dewar.events else "No Events",
|
||||
tracking_number=dewar.tracking_number or "N/A",
|
||||
slot_id=dewar.slot[0].id
|
||||
if dewar.slot
|
||||
else None, # Use first slot if available
|
||||
contact=[
|
||||
ContactMinimal(
|
||||
firstname=dewar.contact.firstname,
|
||||
lastname=dewar.contact.lastname,
|
||||
email=dewar.contact.email,
|
||||
id=dewar.contact.id,
|
||||
)
|
||||
]
|
||||
if dewar.contact
|
||||
else [],
|
||||
address=[
|
||||
AddressMinimal(
|
||||
house_number=dewar.return_address.house_number,
|
||||
street=dewar.return_address.street,
|
||||
city=dewar.return_address.city,
|
||||
state=dewar.return_address.state,
|
||||
country=dewar.return_address.country,
|
||||
zipcode=dewar.return_address.zipcode,
|
||||
id=dewar.return_address.id,
|
||||
)
|
||||
]
|
||||
if dewar.return_address
|
||||
else [],
|
||||
events=dewar.events[-1].slot_id if dewar.events else "No Events",
|
||||
last_updated=dewar.events[-1].timestamp if dewar.events else None,
|
||||
)
|
||||
)
|
||||
|
||||
# Add logging for missing relationships
|
||||
if not hasattr(dewar, "pgroups"):
|
||||
logger.warning(f"Dewar {dewar.id} is missing 'pgroups'")
|
||||
if not hasattr(dewar, "shipment_id"):
|
||||
logger.warning(f"Dewar {dewar.id} is missing 'shipment_id'")
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@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}")
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import List, Optional
|
||||
from typing import List, Optional, Union
|
||||
from datetime import datetime
|
||||
from pydantic import BaseModel, EmailStr, constr, Field, field_validator
|
||||
from datetime import date
|
||||
@ -410,6 +410,13 @@ class ContactUpdate(BaseModel):
|
||||
email: Optional[EmailStr] = None
|
||||
|
||||
|
||||
class ContactMinimal(BaseModel):
|
||||
firstname: str
|
||||
lastname: str
|
||||
email: EmailStr
|
||||
id: int
|
||||
|
||||
|
||||
class AddressCreate(BaseModel):
|
||||
pgroups: str
|
||||
house_number: Optional[str] = None
|
||||
@ -438,6 +445,16 @@ class AddressUpdate(BaseModel):
|
||||
country: Optional[str] = None
|
||||
|
||||
|
||||
class AddressMinimal(BaseModel):
|
||||
house_number: str
|
||||
street: str
|
||||
city: str
|
||||
state: Optional[str] = None
|
||||
zipcode: str
|
||||
country: str
|
||||
id: int
|
||||
|
||||
|
||||
class Sample(BaseModel):
|
||||
id: int
|
||||
sample_name: str
|
||||
@ -578,6 +595,28 @@ class DewarSchema(BaseModel):
|
||||
# Tracking will also become an event
|
||||
|
||||
|
||||
class DewarTable(BaseModel):
|
||||
id: int
|
||||
pgroups: Optional[str] = None # Make "pgroups" optional
|
||||
shipment_id: Optional[int] = None # Make "shipment_id" optional
|
||||
shipment_name: str
|
||||
dewar_name: str
|
||||
tracking_number: Optional[str] = None
|
||||
dewar_type_id: Optional[int] = None
|
||||
dewar_serial_number_id: Optional[int] = None
|
||||
unique_id: Optional[str] = None
|
||||
status: Optional[str] = None
|
||||
contact: Optional[List[ContactMinimal]] = None
|
||||
address: Optional[List[AddressMinimal]] = None
|
||||
event_id: Optional[int] = None
|
||||
slot_id: Optional[int] = None
|
||||
events: Optional[Union[str, int]] = None
|
||||
last_updated: Optional[datetime] = None
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class Proposal(BaseModel):
|
||||
id: int
|
||||
number: str
|
||||
|
Reference in New Issue
Block a user