changed models and schemasa
This commit is contained in:
parent
7125cc5b50
commit
52fe68b2bc
@ -102,38 +102,39 @@ shipments = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
pucks = [
|
pucks = [
|
||||||
Puck(id=1, puck_name="PUCK001", puck_type="Unipuck", puck_location_in_dewar=1, positions=[], dewar_id=1),
|
Puck(id=1, puck_name="PUCK001", puck_type="Unipuck", puck_location_in_dewar=1, dewar_id=1),
|
||||||
Puck(id=2, puck_name="PUCK002", puck_type="Unipuck", puck_location_in_dewar=2, positions=[], dewar_id=1),
|
Puck(id=2, puck_name="PUCK002", puck_type="Unipuck", puck_location_in_dewar=2, dewar_id=1),
|
||||||
Puck(id=3, puck_name="PUCK003", puck_type="Unipuck", puck_location_in_dewar=3, positions=[], dewar_id=1),
|
Puck(id=3, puck_name="PUCK003", puck_type="Unipuck", puck_location_in_dewar=3, dewar_id=1),
|
||||||
Puck(id=4, puck_name="PUCK004", puck_type="Unipuck", puck_location_in_dewar=4, positions=[], dewar_id=1),
|
Puck(id=4, puck_name="PUCK004", puck_type="Unipuck", puck_location_in_dewar=4, dewar_id=1),
|
||||||
Puck(id=5, puck_name="PUCK005", puck_type="Unipuck", puck_location_in_dewar=5, positions=[], dewar_id=1),
|
Puck(id=5, puck_name="PUCK005", puck_type="Unipuck", puck_location_in_dewar=5, dewar_id=1),
|
||||||
Puck(id=6, puck_name="PUCK006", puck_type="Unipuck", puck_location_in_dewar=6, positions=[], dewar_id=1),
|
Puck(id=6, puck_name="PUCK006", puck_type="Unipuck", puck_location_in_dewar=6, dewar_id=1),
|
||||||
Puck(id=7, puck_name="PUCK007", puck_type="Unipuck", puck_location_in_dewar=7, positions=[], dewar_id=1),
|
Puck(id=7, puck_name="PUCK007", puck_type="Unipuck", puck_location_in_dewar=7, dewar_id=1),
|
||||||
Puck(id=8, puck_name="PK001", puck_type="Unipuck", puck_location_in_dewar=1, positions=[], dewar_id=2),
|
Puck(id=8, puck_name="PK001", puck_type="Unipuck", puck_location_in_dewar=1, dewar_id=2),
|
||||||
Puck(id=9, puck_name="PK002", puck_type="Unipuck", puck_location_in_dewar=2, positions=[], dewar_id=2),
|
Puck(id=9, puck_name="PK002", puck_type="Unipuck", puck_location_in_dewar=2, dewar_id=2),
|
||||||
Puck(id=10, puck_name="PK003", puck_type="Unipuck", puck_location_in_dewar=3, positions=[], dewar_id=2),
|
Puck(id=10, puck_name="PK003", puck_type="Unipuck", puck_location_in_dewar=3, dewar_id=2),
|
||||||
Puck(id=11, puck_name="PK004", puck_type="Unipuck", puck_location_in_dewar=4, positions=[], dewar_id=2),
|
Puck(id=11, puck_name="PK004", puck_type="Unipuck", puck_location_in_dewar=4, dewar_id=2),
|
||||||
Puck(id=12, puck_name="PK005", puck_type="Unipuck", puck_location_in_dewar=5, positions=[], dewar_id=2),
|
Puck(id=12, puck_name="PK005", puck_type="Unipuck", puck_location_in_dewar=5, dewar_id=2),
|
||||||
Puck(id=13, puck_name="PK006", puck_type="Unipuck", puck_location_in_dewar=6, positions=[], dewar_id=2),
|
Puck(id=13, puck_name="PK006", puck_type="Unipuck", puck_location_in_dewar=6, dewar_id=2),
|
||||||
Puck(id=14, puck_name="P001", puck_type="Unipuck", puck_location_in_dewar=1, positions=[], dewar_id=3),
|
Puck(id=14, puck_name="P001", puck_type="Unipuck", puck_location_in_dewar=1, dewar_id=3),
|
||||||
Puck(id=15, puck_name="P002", puck_type="Unipuck", puck_location_in_dewar=2, positions=[], dewar_id=3),
|
Puck(id=15, puck_name="P002", puck_type="Unipuck", puck_location_in_dewar=2, dewar_id=3),
|
||||||
Puck(id=16, puck_name="P003", puck_type="Unipuck", puck_location_in_dewar=3, positions=[], dewar_id=3),
|
Puck(id=16, puck_name="P003", puck_type="Unipuck", puck_location_in_dewar=3, dewar_id=3),
|
||||||
Puck(id=17, puck_name="P004", puck_type="Unipuck", puck_location_in_dewar=4, positions=[], dewar_id=3),
|
Puck(id=17, puck_name="P004", puck_type="Unipuck", puck_location_in_dewar=4, dewar_id=3),
|
||||||
Puck(id=18, puck_name="P005", puck_type="Unipuck", puck_location_in_dewar=5, positions=[], dewar_id=3),
|
Puck(id=18, puck_name="P005", puck_type="Unipuck", puck_location_in_dewar=5, dewar_id=3),
|
||||||
Puck(id=19, puck_name="P006", puck_type="Unipuck", puck_location_in_dewar=6, positions=[], dewar_id=3),
|
Puck(id=19, puck_name="P006", puck_type="Unipuck", puck_location_in_dewar=6, dewar_id=3),
|
||||||
Puck(id=20, puck_name="P007", puck_type="Unipuck", puck_location_in_dewar=7, positions=[], dewar_id=3),
|
Puck(id=20, puck_name="P007", puck_type="Unipuck", puck_location_in_dewar=7, dewar_id=3),
|
||||||
Puck(id=21, puck_name="PC002", puck_type="Unipuck", puck_location_in_dewar=2, positions=[], dewar_id=4),
|
Puck(id=21, puck_name="PC002", puck_type="Unipuck", puck_location_in_dewar=2, dewar_id=4),
|
||||||
Puck(id=22, puck_name="PC003", puck_type="Unipuck", puck_location_in_dewar=3, positions=[], dewar_id=4),
|
Puck(id=22, puck_name="PC003", puck_type="Unipuck", puck_location_in_dewar=3, dewar_id=4),
|
||||||
Puck(id=23, puck_name="PC004", puck_type="Unipuck", puck_location_in_dewar=4, positions=[], dewar_id=4),
|
Puck(id=23, puck_name="PC004", puck_type="Unipuck", puck_location_in_dewar=4, dewar_id=4),
|
||||||
Puck(id=24, puck_name="PC005", puck_type="Unipuck", puck_location_in_dewar=5, positions=[], dewar_id=4),
|
Puck(id=24, puck_name="PC005", puck_type="Unipuck", puck_location_in_dewar=5, dewar_id=4),
|
||||||
Puck(id=25, puck_name="PC006", puck_type="Unipuck", puck_location_in_dewar=6, positions=[], dewar_id=4),
|
Puck(id=25, puck_name="PC006", puck_type="Unipuck", puck_location_in_dewar=6, dewar_id=4),
|
||||||
Puck(id=26, puck_name="PC007", puck_type="Unipuck", puck_location_in_dewar=7, positions=[], dewar_id=4),
|
Puck(id=26, puck_name="PC007", puck_type="Unipuck", puck_location_in_dewar=7, dewar_id=4),
|
||||||
Puck(id=27, puck_name="PKK004", puck_type="Unipuck", puck_location_in_dewar=4, positions=[], dewar_id=5),
|
Puck(id=27, puck_name="PKK004", puck_type="Unipuck", puck_location_in_dewar=4, dewar_id=5),
|
||||||
Puck(id=28, puck_name="PKK005", puck_type="Unipuck", puck_location_in_dewar=5, positions=[], dewar_id=5),
|
Puck(id=28, puck_name="PKK005", puck_type="Unipuck", puck_location_in_dewar=5, dewar_id=5),
|
||||||
Puck(id=29, puck_name="PKK006", puck_type="Unipuck", puck_location_in_dewar=6, positions=[], dewar_id=5),
|
Puck(id=29, puck_name="PKK006", puck_type="Unipuck", puck_location_in_dewar=6, dewar_id=5),
|
||||||
Puck(id=30, puck_name="PKK007", puck_type="Unipuck", puck_location_in_dewar=7, positions=[], dewar_id=5)
|
Puck(id=30, puck_name="PKK007", puck_type="Unipuck", puck_location_in_dewar=7, dewar_id=5)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
samples = []
|
samples = []
|
||||||
sample_id_counter = 1
|
sample_id_counter = 1
|
||||||
|
|
||||||
@ -143,7 +144,11 @@ for puck in pucks:
|
|||||||
|
|
||||||
for pos in range(1, 17):
|
for pos in range(1, 17):
|
||||||
if pos in occupied_positions:
|
if pos in occupied_positions:
|
||||||
sample = Sample(id=sample_id_counter, sample_name=f"Sample{sample_id_counter:03}", puck_id=puck.id)
|
sample = Sample(
|
||||||
puck.positions.append(sample)
|
id=sample_id_counter,
|
||||||
|
sample_name=f"Sample{sample_id_counter:03}",
|
||||||
|
position=pos,
|
||||||
|
puck_id=puck.id
|
||||||
|
)
|
||||||
samples.append(sample)
|
samples.append(sample)
|
||||||
sample_id_counter += 1
|
sample_id_counter += 1
|
@ -69,11 +69,13 @@ class Dewar(Base):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def number_of_pucks(self) -> int:
|
def number_of_pucks(self) -> int:
|
||||||
return calculate_number_of_pucks(self)
|
return len(self.pucks) if self.pucks else 0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def number_of_samples(self) -> int:
|
def number_of_samples(self) -> int:
|
||||||
return calculate_number_of_samples(self)
|
if not self.pucks:
|
||||||
|
return 0
|
||||||
|
return sum(len(puck.samples) for puck in self.pucks)
|
||||||
|
|
||||||
|
|
||||||
class Proposal(Base):
|
class Proposal(Base):
|
||||||
@ -88,20 +90,24 @@ class Proposal(Base):
|
|||||||
class Puck(Base):
|
class Puck(Base):
|
||||||
__tablename__ = 'pucks'
|
__tablename__ = 'pucks'
|
||||||
|
|
||||||
id = Column(String, primary_key=True)
|
id = Column(Integer, primary_key=True, index=True)
|
||||||
puck_name = Column(String)
|
puck_name = Column(String, index=True)
|
||||||
puck_type = Column(String)
|
puck_type = Column(String)
|
||||||
puck_location_in_dewar = Column(Integer)
|
puck_location_in_dewar = Column(Integer)
|
||||||
dewar_id = Column(Integer, ForeignKey('dewars.id')) # Note: changed to String
|
|
||||||
|
|
||||||
positions = relationship("Sample", back_populates="puck")
|
# Foreign keys and relationships
|
||||||
dewar = relationship("Dewar", back_populates="pucks")
|
dewar_id = Column(Integer, ForeignKey('dewars.id'))
|
||||||
|
dewar = relationship("Dewar", back_populates="pucks") # Properly define the other side of the relationship
|
||||||
|
samples = relationship("Sample", back_populates="puck")
|
||||||
|
|
||||||
|
|
||||||
class Sample(Base):
|
class Sample(Base):
|
||||||
__tablename__ = 'samples'
|
__tablename__ = 'samples'
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True, index=True)
|
||||||
sample_name = Column(String)
|
sample_name = Column(String, index=True) # Matches `sample_name` in data creation
|
||||||
|
position = Column(Integer) # Matches `position` in data creation script
|
||||||
|
|
||||||
|
# Foreign keys and relationships
|
||||||
puck_id = Column(Integer, ForeignKey('pucks.id'))
|
puck_id = Column(Integer, ForeignKey('pucks.id'))
|
||||||
puck = relationship("Puck", back_populates="positions")
|
puck = relationship("Puck", back_populates="samples")
|
||||||
|
@ -1,24 +1,27 @@
|
|||||||
|
# app/routers/shipment.py
|
||||||
|
|
||||||
from fastapi import APIRouter, HTTPException, status, Query, Depends
|
from fastapi import APIRouter, HTTPException, status, Query, Depends
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
import uuid
|
|
||||||
import json
|
|
||||||
from datetime import date
|
|
||||||
import logging
|
import logging
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from app.models import Shipment as ShipmentModel, ContactPerson as ContactPersonModel, Address as AddressModel, Proposal as ProposalModel, Dewar as DewarModel
|
from app.models import Shipment as ShipmentModel, ContactPerson as ContactPersonModel, Address as AddressModel, \
|
||||||
from app.schemas import ShipmentCreate, UpdateShipmentComments, Shipment as ShipmentSchema, DewarUpdate, ContactPerson as ContactPersonSchema
|
Proposal as ProposalModel, Dewar as DewarModel
|
||||||
from app.schemas import Sample as SampleSchema
|
from app.schemas import ShipmentCreate, UpdateShipmentComments, Shipment as ShipmentSchema, DewarUpdate, \
|
||||||
|
ContactPerson as ContactPersonSchema, Sample as SampleSchema, DewarCreate, PuckCreate, SampleCreate
|
||||||
from app.database import get_db
|
from app.database import get_db
|
||||||
from app.crud import get_shipments, get_shipment_by_id
|
from app.crud import get_shipments, get_shipment_by_id
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
def default_serializer(obj):
|
def default_serializer(obj):
|
||||||
if isinstance(obj, date):
|
if isinstance(obj, date):
|
||||||
return obj.isoformat()
|
return obj.isoformat()
|
||||||
raise TypeError(f"Type {type(obj)} not serializable")
|
raise TypeError(f"Type {type(obj)} not serializable")
|
||||||
|
|
||||||
|
|
||||||
@router.get("", response_model=List[ShipmentSchema])
|
@router.get("", response_model=List[ShipmentSchema])
|
||||||
async def fetch_shipments(id: Optional[int] = Query(None), db: Session = Depends(get_db)):
|
async def fetch_shipments(id: Optional[int] = Query(None), db: Session = Depends(get_db)):
|
||||||
if id:
|
if id:
|
||||||
@ -35,6 +38,7 @@ async def fetch_shipments(id: Optional[int] = Query(None), db: Session = Depends
|
|||||||
logging.info(f"Shipment ID: {shipment.id}, Shipment Name: {shipment.shipment_name}")
|
logging.info(f"Shipment ID: {shipment.id}, Shipment Name: {shipment.shipment_name}")
|
||||||
return shipments
|
return shipments
|
||||||
|
|
||||||
|
|
||||||
@router.post("", response_model=ShipmentSchema, status_code=status.HTTP_201_CREATED)
|
@router.post("", response_model=ShipmentSchema, status_code=status.HTTP_201_CREATED)
|
||||||
async def create_shipment(shipment: ShipmentCreate, db: Session = Depends(get_db)):
|
async def create_shipment(shipment: ShipmentCreate, db: Session = Depends(get_db)):
|
||||||
contact_person = db.query(ContactPersonModel).filter(ContactPersonModel.id == shipment.contact_person_id).first()
|
contact_person = db.query(ContactPersonModel).filter(ContactPersonModel.id == shipment.contact_person_id).first()
|
||||||
@ -68,6 +72,7 @@ async def create_shipment(shipment: ShipmentCreate, db: Session = Depends(get_db
|
|||||||
|
|
||||||
return db_shipment
|
return db_shipment
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/{shipment_id}", status_code=status.HTTP_204_NO_CONTENT)
|
@router.delete("/{shipment_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||||
async def delete_shipment(id: int, db: Session = Depends(get_db)):
|
async def delete_shipment(id: int, db: Session = Depends(get_db)):
|
||||||
shipment = db.query(ShipmentModel).filter(ShipmentModel.id == id).first()
|
shipment = db.query(ShipmentModel).filter(ShipmentModel.id == id).first()
|
||||||
@ -77,6 +82,7 @@ async def delete_shipment(id: int, db: Session = Depends(get_db)):
|
|||||||
db.commit()
|
db.commit()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@router.put("/{shipment_id}", response_model=ShipmentSchema)
|
@router.put("/{shipment_id}", response_model=ShipmentSchema)
|
||||||
async def update_shipment(id: int, updated_shipment: ShipmentCreate, db: Session = Depends(get_db)):
|
async def update_shipment(id: int, updated_shipment: ShipmentCreate, db: Session = Depends(get_db)):
|
||||||
print("Received payload:", json.dumps(updated_shipment.dict(), indent=2, default=default_serializer))
|
print("Received payload:", json.dumps(updated_shipment.dict(), indent=2, default=default_serializer))
|
||||||
@ -145,6 +151,7 @@ async def add_dewar_to_shipment(id: int, dewar_id: int, db: Session = Depends(ge
|
|||||||
db.refresh(shipment)
|
db.refresh(shipment)
|
||||||
return shipment
|
return shipment
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/{shipment_id}/remove_dewar/{dewar_id}", response_model=ShipmentSchema)
|
@router.delete("/{shipment_id}/remove_dewar/{dewar_id}", response_model=ShipmentSchema)
|
||||||
async def remove_dewar_from_shipment(shipment_id: int, dewar_id: int, db: Session = Depends(get_db)):
|
async def remove_dewar_from_shipment(shipment_id: int, dewar_id: int, db: Session = Depends(get_db)):
|
||||||
shipment = db.query(ShipmentModel).filter(ShipmentModel.id == shipment_id).first()
|
shipment = db.query(ShipmentModel).filter(ShipmentModel.id == shipment_id).first()
|
||||||
@ -160,11 +167,13 @@ async def remove_dewar_from_shipment(shipment_id: int, dewar_id: int, db: Sessio
|
|||||||
db.refresh(shipment)
|
db.refresh(shipment)
|
||||||
return shipment
|
return shipment
|
||||||
|
|
||||||
|
|
||||||
@router.get("/contact_persons", response_model=List[ContactPersonSchema])
|
@router.get("/contact_persons", response_model=List[ContactPersonSchema])
|
||||||
async def get_shipment_contact_persons(db: Session = Depends(get_db)):
|
async def get_shipment_contact_persons(db: Session = Depends(get_db)):
|
||||||
contact_persons = db.query(ContactPersonModel).all()
|
contact_persons = db.query(ContactPersonModel).all()
|
||||||
return contact_persons
|
return contact_persons
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{shipment_id}/samples", response_model=List[SampleSchema])
|
@router.get("/{shipment_id}/samples", response_model=List[SampleSchema])
|
||||||
def get_samples_in_shipment(id: int, db: Session = Depends(get_db)):
|
def get_samples_in_shipment(id: int, db: Session = Depends(get_db)):
|
||||||
shipment = db.query(ShipmentModel).filter(ShipmentModel.id == id).first()
|
shipment = db.query(ShipmentModel).filter(ShipmentModel.id == id).first()
|
||||||
@ -174,27 +183,25 @@ def get_samples_in_shipment(id: int, db: Session = Depends(get_db)):
|
|||||||
samples = []
|
samples = []
|
||||||
for dewar in shipment.dewars:
|
for dewar in shipment.dewars:
|
||||||
for puck in dewar.pucks:
|
for puck in dewar.pucks:
|
||||||
samples.extend(puck.positions)
|
samples.extend(puck.samples)
|
||||||
|
|
||||||
return samples
|
return samples
|
||||||
|
|
||||||
@router.get("/{shipment_id}/dewars/{dewar_id}/samples", response_model=List[SampleSchema])
|
|
||||||
def get_samples_in_dewar(
|
@router.get("/shipments/{shipment_id}/dewars/{dewar_id}/samples", response_model=List[SampleSchema])
|
||||||
shipment_id: int, dewar_id: int, db: Session = Depends(get_db)
|
def get_samples_in_dewar(shipment_id: int, dewar_id: int, db: Session = Depends(get_db)):
|
||||||
):
|
shipment = get_shipment_by_id(db, shipment_id)
|
||||||
shipment = db.query(ShipmentModel).filter(ShipmentModel.id == shipment_id).first()
|
if not shipment:
|
||||||
if shipment is None:
|
|
||||||
raise HTTPException(status_code=404, detail="Shipment not found")
|
raise HTTPException(status_code=404, detail="Shipment not found")
|
||||||
|
|
||||||
dewar = db.query(DewarModel).filter(
|
dewar = next((d for d in shipment.dewars if d.id == dewar_id), None)
|
||||||
DewarModel.id == dewar_id, DewarModel.shipment_id == shipment_id
|
if not dewar:
|
||||||
).first()
|
raise HTTPException(status_code=404, detail="Dewar not found")
|
||||||
if dewar is None:
|
|
||||||
raise HTTPException(status_code=404, detail="Dewar not found in shipment")
|
|
||||||
|
|
||||||
samples = []
|
samples = []
|
||||||
for puck in dewar.pucks:
|
for puck in dewar.pucks:
|
||||||
samples.extend(puck.positions)
|
for sample in puck.samples:
|
||||||
|
samples.append(sample)
|
||||||
|
|
||||||
return samples
|
return samples
|
||||||
|
|
||||||
@ -208,4 +215,51 @@ async def update_shipment_comments(id: int, comments_data: UpdateShipmentComment
|
|||||||
shipment.comments = comments_data.comments
|
shipment.comments = comments_data.comments
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(shipment)
|
db.refresh(shipment)
|
||||||
return shipment
|
return shipment
|
||||||
|
|
||||||
|
|
||||||
|
@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)):
|
||||||
|
shipment = db.query(ShipmentModel).filter(ShipmentModel.id == shipment_id).first()
|
||||||
|
if not shipment:
|
||||||
|
raise HTTPException(status_code=404, detail="Shipment not found")
|
||||||
|
|
||||||
|
for dewar_data in payload.dewars:
|
||||||
|
dewar = Dewar(
|
||||||
|
shipment_id=shipment_id,
|
||||||
|
dewar_name=dewar_data.dewar_name,
|
||||||
|
tracking_number=dewar_data.tracking_number,
|
||||||
|
status=dewar_data.status,
|
||||||
|
contact_person_id=dewar_data.contact_person_id,
|
||||||
|
return_address_id=dewar_data.return_address_id,
|
||||||
|
)
|
||||||
|
db.add(dewar)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(dewar)
|
||||||
|
|
||||||
|
for puck_data in dewar_data.pucks:
|
||||||
|
puck = Puck(
|
||||||
|
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 = Sample(
|
||||||
|
puck_id=puck.id,
|
||||||
|
sample_name=sample_data.sample_name,
|
||||||
|
position=sample_data.position,
|
||||||
|
data_collection_parameters=DataCollectionParameters(
|
||||||
|
**sample_data.data_collection_parameters
|
||||||
|
),
|
||||||
|
)
|
||||||
|
db.add(sample)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(sample)
|
||||||
|
|
||||||
|
db.refresh(shipment)
|
||||||
|
return shipment
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
from pydantic import BaseModel, EmailStr, constr
|
from pydantic import BaseModel, EmailStr, constr, Field
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
|
|
||||||
@ -35,9 +35,11 @@ class DataCollectionParameters(BaseModel):
|
|||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class Results(BaseModel):
|
class Results(BaseModel):
|
||||||
# Define attributes for Results here
|
# Define attributes for Results here
|
||||||
pass # Placeholder for now, should be expanded later with actual fields
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Contact Person schemas
|
# Contact Person schemas
|
||||||
class ContactPersonBase(BaseModel):
|
class ContactPersonBase(BaseModel):
|
||||||
@ -57,12 +59,14 @@ class ContactPerson(ContactPersonBase):
|
|||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class ContactPersonUpdate(BaseModel):
|
class ContactPersonUpdate(BaseModel):
|
||||||
firstname: str | None = None
|
firstname: str | None = None
|
||||||
lastname: str | None = None
|
lastname: str | None = None
|
||||||
phone_number: str | None = None
|
phone_number: str | None = None
|
||||||
email: EmailStr | None = None
|
email: EmailStr | None = None
|
||||||
|
|
||||||
|
|
||||||
# Address schemas
|
# Address schemas
|
||||||
class AddressCreate(BaseModel):
|
class AddressCreate(BaseModel):
|
||||||
street: str
|
street: str
|
||||||
@ -77,21 +81,31 @@ class Address(AddressCreate):
|
|||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class AddressUpdate(BaseModel):
|
class AddressUpdate(BaseModel):
|
||||||
street: str | None = None
|
street: str | None = None
|
||||||
city: str | None = None
|
city: str | None = None
|
||||||
zipcode: str | None = None
|
zipcode: str | None = None
|
||||||
country: str | None = None
|
country: str | None = None
|
||||||
|
|
||||||
# Sample schemas
|
|
||||||
class Sample(BaseModel):
|
class Sample(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
sample_name: str
|
sample_name: str
|
||||||
data_collection_parameters: Optional[DataCollectionParameters] = None
|
position: int # Position within the puck
|
||||||
results: Optional[Results] = None
|
puck_id: int
|
||||||
|
crystalname: Optional[str] = Field(None)
|
||||||
|
positioninpuck: Optional[int] = Field(None)
|
||||||
|
|
||||||
|
|
||||||
|
class SampleCreate(BaseModel):
|
||||||
|
sample_name: str = Field(..., alias="crystalname")
|
||||||
|
position: int = Field(..., alias="positioninpuck")
|
||||||
|
data_collection_parameters: DataCollectionParameters
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
populate_by_name = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Puck schemas
|
# Puck schemas
|
||||||
@ -102,7 +116,7 @@ class PuckBase(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class PuckCreate(PuckBase):
|
class PuckCreate(PuckBase):
|
||||||
positions: List[int] = []
|
pass
|
||||||
|
|
||||||
|
|
||||||
class PuckUpdate(BaseModel):
|
class PuckUpdate(BaseModel):
|
||||||
@ -110,12 +124,15 @@ class PuckUpdate(BaseModel):
|
|||||||
puck_type: Optional[str] = None
|
puck_type: Optional[str] = None
|
||||||
puck_location_in_dewar: Optional[int] = None
|
puck_location_in_dewar: Optional[int] = None
|
||||||
dewar_id: Optional[int] = None
|
dewar_id: Optional[int] = None
|
||||||
positions: Optional[List[int]] = None
|
|
||||||
|
|
||||||
|
|
||||||
class Puck(PuckBase):
|
class Puck(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
positions: List[Sample] = []
|
puck_name: str
|
||||||
|
puck_type: str
|
||||||
|
puck_location_in_dewar: int
|
||||||
|
dewar_id: int
|
||||||
|
samples: List[Sample] = [] # List of samples within this puck
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
@ -137,8 +154,13 @@ class DewarBase(BaseModel):
|
|||||||
return_address_id: Optional[int]
|
return_address_id: Optional[int]
|
||||||
|
|
||||||
|
|
||||||
class DewarCreate(DewarBase):
|
class DewarCreate(BaseModel):
|
||||||
pass
|
dewar_name: str = Field(..., alias="dewarname")
|
||||||
|
tracking_number: Optional[str]
|
||||||
|
status: Optional[str] = None
|
||||||
|
contact_person_id: Optional[int] = None
|
||||||
|
return_address_id: Optional[int] = None
|
||||||
|
pucks: List[PuckCreate] = []
|
||||||
|
|
||||||
|
|
||||||
class Dewar(DewarBase):
|
class Dewar(DewarBase):
|
||||||
@ -146,7 +168,7 @@ class Dewar(DewarBase):
|
|||||||
shipment_id: Optional[int]
|
shipment_id: Optional[int]
|
||||||
contact_person: Optional[ContactPerson]
|
contact_person: Optional[ContactPerson]
|
||||||
return_address: Optional[Address]
|
return_address: Optional[Address]
|
||||||
pucks: Optional[List[Puck]] = []
|
pucks: List[Puck] = [] # List of pucks within this dewar
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
@ -184,7 +206,7 @@ class Shipment(BaseModel):
|
|||||||
contact_person: Optional[ContactPerson]
|
contact_person: Optional[ContactPerson]
|
||||||
return_address: Optional[Address]
|
return_address: Optional[Address]
|
||||||
proposal: Optional[Proposal]
|
proposal: Optional[Proposal]
|
||||||
dewars: Optional[List[Dewar]] = []
|
dewars: List[Dewar] = []
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
@ -198,11 +220,11 @@ class ShipmentCreate(BaseModel):
|
|||||||
contact_person_id: int
|
contact_person_id: int
|
||||||
return_address_id: int
|
return_address_id: int
|
||||||
proposal_id: int
|
proposal_id: int
|
||||||
dewars: Optional[List[DewarUpdate]] = []
|
dewars: List[DewarCreate] = []
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class UpdateShipmentComments(BaseModel):
|
class UpdateShipmentComments(BaseModel):
|
||||||
comments: str
|
comments: str
|
||||||
|
@ -1,31 +1,27 @@
|
|||||||
# app/services/shipment_processor.py
|
# Adjusting the ShipmentProcessor for better error handling and alignment
|
||||||
|
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from app.models import Shipment, Dewar, Puck, Sample
|
from app.models import Shipment, Dewar, Puck, Sample, DataCollectionParameters
|
||||||
from app.schemas import ShipmentCreate, ShipmentResponse
|
from app.schemas import ShipmentCreate, ShipmentResponse
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class ShipmentProcessor:
|
class ShipmentProcessor:
|
||||||
def __init__(self, db: Session):
|
def __init__(self, db: Session):
|
||||||
self.db = db
|
self.db = db
|
||||||
|
|
||||||
def process_shipment(self, shipment: ShipmentCreate) -> ShipmentResponse:
|
def process_shipment(self, shipment: ShipmentCreate) -> ShipmentResponse:
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
try:
|
try:
|
||||||
# Creating new Shipment
|
|
||||||
new_shipment = Shipment(
|
new_shipment = Shipment(
|
||||||
shipment_name=shipment.shipment_name,
|
shipment_name=shipment.shipment_name,
|
||||||
shipment_date=shipment.shipment_date,
|
shipment_date=shipment.shipment_date,
|
||||||
shipment_status=shipment.shipment_status, # Adjusted to match model
|
shipment_status=shipment.shipment_status,
|
||||||
# other shipment-related fields if any
|
|
||||||
)
|
)
|
||||||
self.db.add(new_shipment)
|
self.db.add(new_shipment)
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
self.db.refresh(new_shipment)
|
self.db.refresh(new_shipment)
|
||||||
|
|
||||||
# Link Dewars
|
|
||||||
for dewar_data in shipment.dewars:
|
for dewar_data in shipment.dewars:
|
||||||
dewar = Dewar(
|
dewar = Dewar(
|
||||||
shipment_id=new_shipment.id,
|
shipment_id=new_shipment.id,
|
||||||
@ -39,7 +35,6 @@ class ShipmentProcessor:
|
|||||||
self.db.commit()
|
self.db.commit()
|
||||||
self.db.refresh(dewar)
|
self.db.refresh(dewar)
|
||||||
|
|
||||||
# Link Pucks
|
|
||||||
for puck_data in dewar_data.pucks:
|
for puck_data in dewar_data.pucks:
|
||||||
puck = Puck(
|
puck = Puck(
|
||||||
dewar_id=dewar.id,
|
dewar_id=dewar.id,
|
||||||
@ -51,18 +46,19 @@ class ShipmentProcessor:
|
|||||||
self.db.commit()
|
self.db.commit()
|
||||||
self.db.refresh(puck)
|
self.db.refresh(puck)
|
||||||
|
|
||||||
# Link Samples
|
|
||||||
for sample_data in puck_data.samples:
|
for sample_data in puck_data.samples:
|
||||||
|
data_collection_params = DataCollectionParameters(
|
||||||
|
**sample_data.data_collection_parameters.dict(by_alias=True))
|
||||||
sample = Sample(
|
sample = Sample(
|
||||||
puck_id=puck.id,
|
puck_id=puck.id,
|
||||||
sample_name=sample_data.sample_name,
|
sample_name=sample_data.sample_name,
|
||||||
position=sample_data.position,
|
position=sample_data.position,
|
||||||
|
data_collection_parameters=data_collection_params
|
||||||
)
|
)
|
||||||
self.db.add(sample)
|
self.db.add(sample)
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
self.db.refresh(sample)
|
self.db.refresh(sample)
|
||||||
|
|
||||||
# Return a response wrapped in the ShipmentResponse schema
|
|
||||||
return ShipmentResponse(
|
return ShipmentResponse(
|
||||||
shipment_id=new_shipment.id,
|
shipment_id=new_shipment.id,
|
||||||
status="success",
|
status="success",
|
||||||
|
@ -42,6 +42,8 @@ const DewarDetails: React.FC<DewarDetailsProps> = ({
|
|||||||
const [changesMade, setChangesMade] = useState(false);
|
const [changesMade, setChangesMade] = useState(false);
|
||||||
const [feedbackMessage, setFeedbackMessage] = useState('');
|
const [feedbackMessage, setFeedbackMessage] = useState('');
|
||||||
const [openSnackbar, setOpenSnackbar] = useState(false);
|
const [openSnackbar, setOpenSnackbar] = useState(false);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [error, setError] = useState('');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const setInitialContactPerson = () => {
|
const setInitialContactPerson = () => {
|
||||||
@ -92,22 +94,33 @@ const DewarDetails: React.FC<DewarDetailsProps> = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchSamples = async () => {
|
const fetchSamples = async () => {
|
||||||
if (dewar.id && Array.isArray(dewar.pucks)) {
|
if (dewar.id) {
|
||||||
try {
|
try {
|
||||||
const samples = await ShipmentsService.getSamplesInDewarShipmentsShipmentIdDewarsDewarIdSamplesGet(shipmentId, dewar.id);
|
const fetchedSamples = await ShipmentsService.getSamplesInDewarShipmentsShipmentsShipmentIdDewarsDewarIdSamplesGet(shipmentId, dewar.id);
|
||||||
|
console.log("Fetched Samples: ", fetchedSamples);
|
||||||
|
|
||||||
const updatedPuckStatuses = dewar.pucks.map(puck => {
|
const updatedPuckStatuses = dewar.pucks.map(puck => {
|
||||||
if (!Array.isArray(puck.positions)) return [];
|
// Filter samples for the current puck
|
||||||
return puck.positions.map(position => {
|
const puckSamples = fetchedSamples.filter(sample => sample.puck_id === puck.id);
|
||||||
const isOccupied = samples.some(sample => sample.id === position.id);
|
|
||||||
return isOccupied ? 'filled' : 'empty';
|
// Initialize positions as 'empty'
|
||||||
|
const statusArray = Array(16).fill('empty');
|
||||||
|
|
||||||
|
// Update positions based on puckSamples' positions
|
||||||
|
puckSamples.forEach(sample => {
|
||||||
|
if (sample.position >= 1 && sample.position <= 16) {
|
||||||
|
statusArray[sample.position - 1] = 'filled'; // Adjust for 0-based index
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return statusArray;
|
||||||
});
|
});
|
||||||
|
|
||||||
setPuckStatuses(updatedPuckStatuses);
|
setPuckStatuses(updatedPuckStatuses);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFeedbackMessage('Failed to load samples. Please try again later.');
|
setError('Failed to load samples. Please try again later.');
|
||||||
setOpenSnackbar(true);
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -190,6 +190,7 @@ const ShipmentPanel: React.FC<ShipmentPanelProps> = ({
|
|||||||
<UploadDialog
|
<UploadDialog
|
||||||
open={uploadDialogOpen}
|
open={uploadDialogOpen}
|
||||||
onClose={closeUploadDialog}
|
onClose={closeUploadDialog}
|
||||||
|
selectedShipment={selectedShipment} // <-- Pass selectedShipment here
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
@ -13,11 +13,19 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Box
|
Box
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { SpreadsheetService } from '../../openapi';
|
import { SpreadsheetService, ShipmentsService } from '../../openapi';
|
||||||
import * as ExcelJS from 'exceljs';
|
import * as ExcelJS from 'exceljs';
|
||||||
import { saveAs } from 'file-saver';
|
import { saveAs } from 'file-saver';
|
||||||
|
|
||||||
const SpreadsheetTable = ({ raw_data, errors, headers, setRawData, onCancel, fileBlob }) => {
|
const SpreadsheetTable = ({
|
||||||
|
raw_data,
|
||||||
|
errors,
|
||||||
|
headers,
|
||||||
|
setRawData,
|
||||||
|
onCancel,
|
||||||
|
fileBlob,
|
||||||
|
shipmentId // Accept the shipmentId
|
||||||
|
}) => {
|
||||||
const [localErrors, setLocalErrors] = useState(errors || []);
|
const [localErrors, setLocalErrors] = useState(errors || []);
|
||||||
const [editingCell, setEditingCell] = useState({});
|
const [editingCell, setEditingCell] = useState({});
|
||||||
const [nonEditableCells, setNonEditableCells] = useState(new Set());
|
const [nonEditableCells, setNonEditableCells] = useState(new Set());
|
||||||
@ -25,7 +33,7 @@ const SpreadsheetTable = ({ raw_data, errors, headers, setRawData, onCancel, fil
|
|||||||
const generateErrorMap = (errorsList) => {
|
const generateErrorMap = (errorsList) => {
|
||||||
const errorMap = new Map();
|
const errorMap = new Map();
|
||||||
if (Array.isArray(errorsList)) {
|
if (Array.isArray(errorsList)) {
|
||||||
errorsList.forEach(error => {
|
errorsList.forEach((error) => {
|
||||||
const key = `${error.row}-${headers[error.cell]}`;
|
const key = `${error.row}-${headers[error.cell]}`;
|
||||||
errorMap.set(key, error.message);
|
errorMap.set(key, error.message);
|
||||||
});
|
});
|
||||||
@ -64,7 +72,7 @@ const SpreadsheetTable = ({ raw_data, errors, headers, setRawData, onCancel, fil
|
|||||||
|
|
||||||
currentRow.data[colIndex] = newValue;
|
currentRow.data[colIndex] = newValue;
|
||||||
|
|
||||||
setEditingCell(prev => {
|
setEditingCell((prev) => {
|
||||||
const updated = { ...prev };
|
const updated = { ...prev };
|
||||||
delete updated[`${rowIndex}-${colIndex}`];
|
delete updated[`${rowIndex}-${colIndex}`];
|
||||||
return updated;
|
return updated;
|
||||||
@ -80,10 +88,10 @@ const SpreadsheetTable = ({ raw_data, errors, headers, setRawData, onCancel, fil
|
|||||||
if (response.is_valid !== undefined) {
|
if (response.is_valid !== undefined) {
|
||||||
if (response.is_valid) {
|
if (response.is_valid) {
|
||||||
const updatedErrors = localErrors.filter(
|
const updatedErrors = localErrors.filter(
|
||||||
error => !(error.row === currentRow.row_num && error.cell === colIndex)
|
(error) => !(error.row === currentRow.row_num && error.cell === colIndex)
|
||||||
);
|
);
|
||||||
setLocalErrors(updatedErrors);
|
setLocalErrors(updatedErrors);
|
||||||
setNonEditableCells(prev => new Set([...prev, `${rowIndex}-${colIndex}`]));
|
setNonEditableCells((prev) => new Set([...prev, `${rowIndex}-${colIndex}`]));
|
||||||
} else {
|
} else {
|
||||||
const updatedErrors = [
|
const updatedErrors = [
|
||||||
...localErrors,
|
...localErrors,
|
||||||
@ -107,11 +115,75 @@ const SpreadsheetTable = ({ raw_data, errors, headers, setRawData, onCancel, fil
|
|||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (allCellsValid()) {
|
if (allCellsValid()) {
|
||||||
console.log('All data is valid. Proceeding with submission...');
|
console.log('All data is valid. Proceeding with submission...');
|
||||||
|
const processedData = createPayload(raw_data);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await ShipmentsService.addDewarPuckSampleToShipmentShipmentsShipmentIdAddDewarPuckSamplePost(shipmentId, processedData);
|
||||||
|
console.log('Shipment processed successfully:', response);
|
||||||
|
|
||||||
|
// Handle success actions, e.g., display notification, reset state, etc.
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error processing shipment:', error);
|
||||||
|
// Handle error actions, e.g., display notification, etc.
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('There are validation errors in the dataset. Please correct them before submission.');
|
console.log('There are validation errors in the dataset. Please correct them before submission.');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createPayload = (data) => {
|
||||||
|
const allowedFields = [
|
||||||
|
'priority', 'comments', 'directory', 'proteinname', 'oscillation', 'aperture',
|
||||||
|
'exposure', 'totalrange', 'transmission', 'dose', 'targetresolution', 'datacollectiontype',
|
||||||
|
'processingpipeline', 'spacegroupnumber', 'cellparameters', 'rescutkey', 'rescutvalue',
|
||||||
|
'userresolution', 'pdbid', 'autoprocfull', 'procfull', 'adpenabled', 'noano',
|
||||||
|
'ffcscampaign', 'trustedhigh', 'autoprocextraparams', 'chiphiangles'
|
||||||
|
];
|
||||||
|
|
||||||
|
let dewars = {};
|
||||||
|
|
||||||
|
data.forEach((row) => {
|
||||||
|
const dewarname = row.data[headers.indexOf('dewarname')];
|
||||||
|
const puckname = row.data[headers.indexOf('puckname')];
|
||||||
|
const crystalname = row.data[headers.indexOf('crystalname')];
|
||||||
|
const positioninpuck = row.data[headers.indexOf('positioninpuck')];
|
||||||
|
|
||||||
|
if (!dewars[dewarname]) {
|
||||||
|
dewars[dewarname] = {
|
||||||
|
dewarname: dewarname,
|
||||||
|
pucks: {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dewars[dewarname].pucks[puckname]) {
|
||||||
|
dewars[dewarname].pucks[puckname] = {
|
||||||
|
puckname: puckname,
|
||||||
|
samples: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const dataCollectionParams = {};
|
||||||
|
headers.forEach((header, index) => {
|
||||||
|
if (allowedFields.includes(header)) {
|
||||||
|
dataCollectionParams[header] = row.data[index];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dewars[dewarname].pucks[puckname].samples.push({
|
||||||
|
crystalname: crystalname,
|
||||||
|
positioninpuck: positioninpuck,
|
||||||
|
data_collection_parameters: dataCollectionParams
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const dewarsList = Object.values(dewars).map(dewar => ({
|
||||||
|
dewarname: dewar.dewarname,
|
||||||
|
pucks: Object.values(dewar.pucks)
|
||||||
|
}));
|
||||||
|
|
||||||
|
return { dewars: dewarsList };
|
||||||
|
};
|
||||||
|
|
||||||
const downloadCorrectedSpreadsheet = async () => {
|
const downloadCorrectedSpreadsheet = async () => {
|
||||||
const workbook = new ExcelJS.Workbook();
|
const workbook = new ExcelJS.Workbook();
|
||||||
await workbook.xlsx.load(fileBlob);
|
await workbook.xlsx.load(fileBlob);
|
||||||
|
@ -8,11 +8,8 @@ interface UnipuckProps {
|
|||||||
|
|
||||||
const Unipuck: React.FC<UnipuckProps> = ({ pucks, samples }) => {
|
const Unipuck: React.FC<UnipuckProps> = ({ pucks, samples }) => {
|
||||||
const renderPuck = (sampleStatus: string[]) => {
|
const renderPuck = (sampleStatus: string[]) => {
|
||||||
if (!sampleStatus) {
|
sampleStatus = sampleStatus || Array(16).fill('empty'); // Ensure no null status array
|
||||||
sampleStatus = Array(16).fill('empty');
|
return (
|
||||||
}
|
|
||||||
|
|
||||||
const puckSVG = (
|
|
||||||
<svg width="100" height="100" viewBox="0 0 100 100">
|
<svg width="100" height="100" viewBox="0 0 100 100">
|
||||||
<circle cx="50" cy="50" r="45" stroke="black" strokeWidth="2" fill="none" />
|
<circle cx="50" cy="50" r="45" stroke="black" strokeWidth="2" fill="none" />
|
||||||
{[...Array(11)].map((_, index) => {
|
{[...Array(11)].map((_, index) => {
|
||||||
@ -29,7 +26,6 @@ const Unipuck: React.FC<UnipuckProps> = ({ pucks, samples }) => {
|
|||||||
})}
|
})}
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
return puckSVG;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (pucks === 0) {
|
if (pucks === 0) {
|
||||||
|
@ -23,9 +23,10 @@ import * as ExcelJS from 'exceljs';
|
|||||||
interface UploadDialogProps {
|
interface UploadDialogProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
selectedShipment: any; // Adjust the type based on your implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
const UploadDialog: React.FC<UploadDialogProps> = ({ open, onClose }) => {
|
const UploadDialog: React.FC<UploadDialogProps> = ({ open, onClose, selectedShipment }) => {
|
||||||
const [uploadError, setUploadError] = useState<string | null>(null);
|
const [uploadError, setUploadError] = useState<string | null>(null);
|
||||||
const [fileSummary, setFileSummary] = useState<{
|
const [fileSummary, setFileSummary] = useState<{
|
||||||
data: any[];
|
data: any[];
|
||||||
@ -37,7 +38,7 @@ const UploadDialog: React.FC<UploadDialogProps> = ({ open, onClose }) => {
|
|||||||
pucks: string[];
|
pucks: string[];
|
||||||
samples_count: number;
|
samples_count: number;
|
||||||
samples: string[];
|
samples: string[];
|
||||||
headers: string[]; // Headers must be part of this object
|
headers: string[];
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
const [fileBlob, setFileBlob] = useState<Blob | null>(null); // New state to store the file blob
|
const [fileBlob, setFileBlob] = useState<Blob | null>(null); // New state to store the file blob
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
@ -165,6 +166,7 @@ const UploadDialog: React.FC<UploadDialogProps> = ({ open, onClose }) => {
|
|||||||
setRawData={(newRawData) => setFileSummary((prevSummary) => ({ ...prevSummary, raw_data: newRawData }))}
|
setRawData={(newRawData) => setFileSummary((prevSummary) => ({ ...prevSummary, raw_data: newRawData }))}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
fileBlob={fileBlob} // Pass the original file blob
|
fileBlob={fileBlob} // Pass the original file blob
|
||||||
|
shipmentId={selectedShipment?.id} // Pass the selected shipment ID
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
)}
|
)}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user