now creating dewars, pucks and samples from spreadsheet and replacing dewars if a dewar with the same name exists

This commit is contained in:
GotthardG
2024-11-12 17:03:38 +01:00
parent 86883133a7
commit 8f7c90bab0
5 changed files with 327 additions and 134 deletions

View File

@ -1,4 +1,4 @@
from sqlalchemy import Column, Integer, String, Date, ForeignKey
from sqlalchemy import Column, Integer, String, Date, ForeignKey, JSON
from sqlalchemy.orm import relationship
from app.database import Base
from app.calculations import calculate_number_of_pucks, calculate_number_of_samples
@ -107,6 +107,7 @@ class Sample(Base):
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
sample_name = Column(String, index=True) # Matches `sample_name` in data creation
position = Column(Integer) # Matches `position` in data creation script
data_collection_parameters = Column(JSON, nullable=True)
# Foreign keys and relationships
puck_id = Column(Integer, ForeignKey('pucks.id'))

View File

@ -1,9 +1,12 @@
from fastapi import APIRouter, HTTPException, status, Depends
from sqlalchemy.orm import Session, joinedload
from typing import List
import uuid
import logging
from sqlalchemy.exc import SQLAlchemyError
from pydantic import ValidationError
from app.schemas import Dewar as DewarSchema, DewarCreate, DewarUpdate
from app.models import Dewar as DewarModel, Puck as PuckModel
from app.models import Dewar as DewarModel, Puck as PuckModel, \
Sample as SampleModel # Assuming SampleModel is defined in models
from app.dependencies import get_db
router = APIRouter()
@ -17,24 +20,55 @@ async def get_dewars(db: Session = Depends(get_db)):
@router.post("/", response_model=DewarSchema, status_code=status.HTTP_201_CREATED)
async def create_dewar(dewar: DewarCreate, db: Session = Depends(get_db)) -> DewarSchema:
db_dewar = DewarModel(
dewar_name=dewar.dewar_name,
tracking_number=dewar.tracking_number,
status=dewar.status,
ready_date=dewar.ready_date,
shipping_date=dewar.shipping_date,
arrival_date=dewar.arrival_date,
returning_date=dewar.returning_date,
qrcode=dewar.qrcode,
contact_person_id=dewar.contact_person_id,
return_address_id=dewar.return_address_id
)
try:
db_dewar = DewarModel(
dewar_name=dewar.dewar_name,
tracking_number=dewar.tracking_number,
status=dewar.status,
ready_date=dewar.ready_date,
shipping_date=dewar.shipping_date,
arrival_date=dewar.arrival_date,
returning_date=dewar.returning_date,
qrcode=dewar.qrcode,
contact_person_id=dewar.contact_person_id,
return_address_id=dewar.return_address_id
)
db.add(db_dewar)
db.commit()
db.refresh(db_dewar)
db.add(db_dewar)
db.commit()
db.refresh(db_dewar)
return db_dewar
for puck_data in dewar.pucks:
puck = PuckModel(
dewar_id=db_dewar.id,
puck_name=puck_data.puck_name,
puck_type=puck_data.puck_type,
puck_location_in_dewar=puck_data.puck_location_in_dewar,
)
db.add(puck)
db.commit()
db.refresh(puck)
for sample_data in puck_data.samples:
sample = SampleModel(
puck_id=puck.id,
sample_name=sample_data.sample_name,
position=sample_data.position,
# Ensure only valid attributes are set
data_collection_parameters=sample_data.data_collection_parameters,
)
db.add(sample)
db.commit()
db.refresh(sample)
return db_dewar
except SQLAlchemyError as e:
logging.error(f"Database error occurred: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
except ValidationError as e:
logging.error(f"Validation error occurred: {e}")
raise HTTPException(status_code=400, detail="Validation error")
@router.get("/{dewar_id}", response_model=DewarSchema)

View File

@ -9,7 +9,7 @@ from sqlalchemy.exc import SQLAlchemyError
from app.models import Shipment as ShipmentModel, ContactPerson as ContactPersonModel, Address as AddressModel, \
Proposal as ProposalModel, Dewar as DewarModel, Puck as PuckModel, Sample as SampleModel
from app.schemas import ShipmentCreate, UpdateShipmentComments, Shipment as ShipmentSchema, DewarUpdate, \
ContactPerson as ContactPersonSchema, Sample as SampleSchema, DewarCreate, PuckCreate, SampleCreate
ContactPerson as ContactPersonSchema, Sample as SampleSchema, DewarCreate, PuckCreate, SampleCreate, DewarSchema
from app.database import get_db
from app.crud import get_shipments, get_shipment_by_id
@ -38,6 +38,19 @@ async def fetch_shipments(id: Optional[int] = Query(None), db: Session = Depends
logging.info(f"Shipment ID: {shipment.id}, Shipment Name: {shipment.shipment_name}")
return shipments
@router.get("/{shipment_id}/dewars", response_model=List[DewarSchema])
async def get_dewars_by_shipment_id(shipment_id: int, db: Session = Depends(get_db)):
shipment = db.query(ShipmentModel).filter(ShipmentModel.id == shipment_id).first()
if not shipment:
raise HTTPException(status_code=404, detail="Shipment not found")
dewars = db.query(DewarModel).filter(DewarModel.shipment_id == shipment_id).all()
if not dewars:
raise HTTPException(status_code=404, detail="No dewars found for this shipment")
return dewars
@router.post("", response_model=ShipmentSchema, status_code=status.HTTP_201_CREATED)
async def create_shipment(shipment: ShipmentCreate, db: Session = Depends(get_db)):
@ -220,58 +233,55 @@ async def update_shipment_comments(shipment_id: int, comments_data: UpdateShipme
@router.post("/{shipment_id}/add_dewar_puck_sample", response_model=ShipmentSchema, status_code=status.HTTP_201_CREATED)
async def add_dewar_puck_sample_to_shipment(
shipment_id: int,
payload: DewarCreate,
db: Session = Depends(get_db)
):
def add_dewar_puck_sample_to_shipment(shipment_id: int, payload: DewarCreate, db: Session = Depends(get_db)):
shipment = db.query(ShipmentModel).filter(ShipmentModel.id == shipment_id).first()
if not shipment:
logging.error(f"Shipment not found with ID: {shipment_id}")
raise HTTPException(status_code=404, detail="Shipment not found")
try:
dewar = DewarModel(
shipment_id=shipment_id,
dewar_name=payload.dewar_name,
tracking_number=payload.tracking_number,
status=payload.status,
contact_person_id=payload.contact_person_id,
return_address_id=payload.return_address_id,
)
db.add(dewar)
db.commit()
db.refresh(dewar)
for puck_data in payload.pucks:
puck = PuckModel(
dewar_id=dewar.id,
puck_name=puck_data.puck_name,
puck_type=puck_data.puck_type,
puck_location_in_dewar=puck_data.puck_location_in_dewar,
)
db.add(puck)
db.commit()
db.refresh(puck)
for sample_data in puck_data.samples:
sample = SampleModel(
puck_id=puck.id,
sample_name=sample_data.sample_name,
position=sample_data.position,
data_collection_parameters=sample_data.data_collection_parameters,
)
db.add(sample)
for dewar_data in payload.dewars:
dewar = db.query(DewarModel).filter(DewarModel.dewar_name == dewar_data.dewar_name).first()
if dewar:
# Update existing dewar
dewar.tracking_number = dewar_data.tracking_number
dewar.status = dewar_data.status
db.commit()
db.refresh(sample)
else:
dewar = DewarModel(
shipment_id=shipment_id,
dewar_name=dewar_data.dewar_name,
tracking_number=dewar_data.tracking_number,
status=dewar_data.status,
)
db.add(dewar)
db.commit()
db.refresh(dewar)
for puck_data in dewar_data.pucks:
puck = PuckModel(
dewar_id=dewar.id,
puck_name=puck_data.puck_name,
puck_type=puck_data.puck_type,
puck_location_in_dewar=puck_data.puck_location_in_dewar,
)
db.add(puck)
db.commit()
db.refresh(puck)
for sample_data in puck_data.samples:
sample = SampleModel(
puck_id=puck.id,
sample_name=sample_data.sample_name,
position=sample_data.position,
)
db.add(sample)
db.commit()
db.refresh(sample)
db.refresh(shipment)
except SQLAlchemyError as e:
logging.error(f"Database error occurred: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
raise HTTPException(status_code=500, detail=f"Database error: {e}")
except ValidationError as e:
logging.error(f"Validation error occurred: {e}")
raise HTTPException(status_code=400, detail="Validation error")
raise HTTPException(status_code=400, detail=f"Validation error: {e}")
logging.info(f"Successfully added dewar, puck, and sample for shipment ID: {shipment_id}")
return shipment
return shipment

View File

@ -101,7 +101,8 @@ class Sample(BaseModel):
class SampleCreate(BaseModel):
sample_name: str = Field(..., alias="crystalname")
position: int = Field(..., alias="positioninpuck")
data_collection_parameters: DataCollectionParameters
data_collection_parameters: Optional[DataCollectionParameters] = None
results: Optional[Results] = None
class Config:
populate_by_name = True
@ -115,8 +116,11 @@ class PuckBase(BaseModel):
puck_location_in_dewar: int
class PuckCreate(PuckBase):
pass
class PuckCreate(BaseModel):
puck_name: str
puck_type: str
puck_location_in_dewar: int
samples: List[SampleCreate] = []
class PuckUpdate(BaseModel):
@ -152,6 +156,7 @@ class DewarBase(BaseModel):
qrcode: str
contact_person_id: Optional[int]
return_address_id: Optional[int]
pucks: List[PuckCreate] = []
class DewarCreate(DewarBase):
@ -181,6 +186,17 @@ class DewarUpdate(BaseModel):
contact_person_id: Optional[int] = None
address_id: Optional[int] = None
class DewarSchema(BaseModel):
id: int
dewar_name: str
tracking_number: str
status: str
contact_person_id: int
return_address_id: int
class Config:
from_attributes = True
# Proposal schemas
class Proposal(BaseModel):