now creating dewars, pucks and samples from spreadsheet and replacing dewars if a dewar with the same name exists
This commit is contained in:
parent
86883133a7
commit
8f7c90bab0
@ -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 sqlalchemy.orm import relationship
|
||||||
from app.database import Base
|
from app.database import Base
|
||||||
from app.calculations import calculate_number_of_pucks, calculate_number_of_samples
|
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)
|
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
|
||||||
sample_name = Column(String, index=True) # Matches `sample_name` in data creation
|
sample_name = Column(String, index=True) # Matches `sample_name` in data creation
|
||||||
position = Column(Integer) # Matches `position` in data creation script
|
position = Column(Integer) # Matches `position` in data creation script
|
||||||
|
data_collection_parameters = Column(JSON, nullable=True)
|
||||||
|
|
||||||
# Foreign keys and relationships
|
# Foreign keys and relationships
|
||||||
puck_id = Column(Integer, ForeignKey('pucks.id'))
|
puck_id = Column(Integer, ForeignKey('pucks.id'))
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
from fastapi import APIRouter, HTTPException, status, Depends
|
from fastapi import APIRouter, HTTPException, status, Depends
|
||||||
from sqlalchemy.orm import Session, joinedload
|
from sqlalchemy.orm import Session, joinedload
|
||||||
from typing import List
|
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.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
|
from app.dependencies import get_db
|
||||||
|
|
||||||
router = APIRouter()
|
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)
|
@router.post("/", response_model=DewarSchema, status_code=status.HTTP_201_CREATED)
|
||||||
async def create_dewar(dewar: DewarCreate, db: Session = Depends(get_db)) -> DewarSchema:
|
async def create_dewar(dewar: DewarCreate, db: Session = Depends(get_db)) -> DewarSchema:
|
||||||
db_dewar = DewarModel(
|
try:
|
||||||
dewar_name=dewar.dewar_name,
|
db_dewar = DewarModel(
|
||||||
tracking_number=dewar.tracking_number,
|
dewar_name=dewar.dewar_name,
|
||||||
status=dewar.status,
|
tracking_number=dewar.tracking_number,
|
||||||
ready_date=dewar.ready_date,
|
status=dewar.status,
|
||||||
shipping_date=dewar.shipping_date,
|
ready_date=dewar.ready_date,
|
||||||
arrival_date=dewar.arrival_date,
|
shipping_date=dewar.shipping_date,
|
||||||
returning_date=dewar.returning_date,
|
arrival_date=dewar.arrival_date,
|
||||||
qrcode=dewar.qrcode,
|
returning_date=dewar.returning_date,
|
||||||
contact_person_id=dewar.contact_person_id,
|
qrcode=dewar.qrcode,
|
||||||
return_address_id=dewar.return_address_id
|
contact_person_id=dewar.contact_person_id,
|
||||||
)
|
return_address_id=dewar.return_address_id
|
||||||
|
)
|
||||||
|
|
||||||
db.add(db_dewar)
|
db.add(db_dewar)
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(db_dewar)
|
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)
|
@router.get("/{dewar_id}", response_model=DewarSchema)
|
||||||
|
@ -9,7 +9,7 @@ from sqlalchemy.exc import SQLAlchemyError
|
|||||||
from app.models import Shipment as ShipmentModel, ContactPerson as ContactPersonModel, Address as AddressModel, \
|
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
|
Proposal as ProposalModel, Dewar as DewarModel, Puck as PuckModel, Sample as SampleModel
|
||||||
from app.schemas import ShipmentCreate, UpdateShipmentComments, Shipment as ShipmentSchema, DewarUpdate, \
|
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.database import get_db
|
||||||
from app.crud import get_shipments, get_shipment_by_id
|
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}")
|
logging.info(f"Shipment ID: {shipment.id}, Shipment Name: {shipment.shipment_name}")
|
||||||
return shipments
|
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)
|
@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)):
|
||||||
@ -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)
|
@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(
|
def add_dewar_puck_sample_to_shipment(shipment_id: int, payload: DewarCreate, db: Session = Depends(get_db)):
|
||||||
shipment_id: int,
|
|
||||||
payload: DewarCreate,
|
|
||||||
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()
|
||||||
if not shipment:
|
if not shipment:
|
||||||
logging.error(f"Shipment not found with ID: {shipment_id}")
|
|
||||||
raise HTTPException(status_code=404, detail="Shipment not found")
|
raise HTTPException(status_code=404, detail="Shipment not found")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dewar = DewarModel(
|
for dewar_data in payload.dewars:
|
||||||
shipment_id=shipment_id,
|
dewar = db.query(DewarModel).filter(DewarModel.dewar_name == dewar_data.dewar_name).first()
|
||||||
dewar_name=payload.dewar_name,
|
if dewar:
|
||||||
tracking_number=payload.tracking_number,
|
# Update existing dewar
|
||||||
status=payload.status,
|
dewar.tracking_number = dewar_data.tracking_number
|
||||||
contact_person_id=payload.contact_person_id,
|
dewar.status = dewar_data.status
|
||||||
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)
|
|
||||||
db.commit()
|
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)
|
db.refresh(shipment)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
logging.error(f"Database error occurred: {e}")
|
raise HTTPException(status_code=500, detail=f"Database error: {e}")
|
||||||
raise HTTPException(status_code=500, detail="Internal server error")
|
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
logging.error(f"Validation error occurred: {e}")
|
raise HTTPException(status_code=400, detail=f"Validation error: {e}")
|
||||||
raise HTTPException(status_code=400, detail="Validation error")
|
|
||||||
|
|
||||||
logging.info(f"Successfully added dewar, puck, and sample for shipment ID: {shipment_id}")
|
return shipment
|
||||||
return shipment
|
|
@ -101,7 +101,8 @@ class Sample(BaseModel):
|
|||||||
class SampleCreate(BaseModel):
|
class SampleCreate(BaseModel):
|
||||||
sample_name: str = Field(..., alias="crystalname")
|
sample_name: str = Field(..., alias="crystalname")
|
||||||
position: int = Field(..., alias="positioninpuck")
|
position: int = Field(..., alias="positioninpuck")
|
||||||
data_collection_parameters: DataCollectionParameters
|
data_collection_parameters: Optional[DataCollectionParameters] = None
|
||||||
|
results: Optional[Results] = None
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
populate_by_name = True
|
populate_by_name = True
|
||||||
@ -115,8 +116,11 @@ class PuckBase(BaseModel):
|
|||||||
puck_location_in_dewar: int
|
puck_location_in_dewar: int
|
||||||
|
|
||||||
|
|
||||||
class PuckCreate(PuckBase):
|
class PuckCreate(BaseModel):
|
||||||
pass
|
puck_name: str
|
||||||
|
puck_type: str
|
||||||
|
puck_location_in_dewar: int
|
||||||
|
samples: List[SampleCreate] = []
|
||||||
|
|
||||||
|
|
||||||
class PuckUpdate(BaseModel):
|
class PuckUpdate(BaseModel):
|
||||||
@ -152,6 +156,7 @@ class DewarBase(BaseModel):
|
|||||||
qrcode: str
|
qrcode: str
|
||||||
contact_person_id: Optional[int]
|
contact_person_id: Optional[int]
|
||||||
return_address_id: Optional[int]
|
return_address_id: Optional[int]
|
||||||
|
pucks: List[PuckCreate] = []
|
||||||
|
|
||||||
|
|
||||||
class DewarCreate(DewarBase):
|
class DewarCreate(DewarBase):
|
||||||
@ -181,6 +186,17 @@ class DewarUpdate(BaseModel):
|
|||||||
contact_person_id: Optional[int] = None
|
contact_person_id: Optional[int] = None
|
||||||
address_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
|
# Proposal schemas
|
||||||
class Proposal(BaseModel):
|
class Proposal(BaseModel):
|
||||||
|
@ -11,7 +11,12 @@ import {
|
|||||||
TextField,
|
TextField,
|
||||||
Typography,
|
Typography,
|
||||||
Button,
|
Button,
|
||||||
Box
|
Box,
|
||||||
|
Dialog,
|
||||||
|
DialogActions,
|
||||||
|
DialogContent,
|
||||||
|
DialogContentText,
|
||||||
|
DialogTitle
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { SpreadsheetService, ShipmentsService, DewarsService, ApiError } from '../../openapi';
|
import { SpreadsheetService, ShipmentsService, DewarsService, ApiError } from '../../openapi';
|
||||||
import * as ExcelJS from 'exceljs';
|
import * as ExcelJS from 'exceljs';
|
||||||
@ -30,6 +35,9 @@ const SpreadsheetTable = ({
|
|||||||
const [editingCell, setEditingCell] = useState({});
|
const [editingCell, setEditingCell] = useState({});
|
||||||
const [nonEditableCells, setNonEditableCells] = useState(new Set());
|
const [nonEditableCells, setNonEditableCells] = useState(new Set());
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
|
const [showUpdateDialog, setShowUpdateDialog] = useState(false);
|
||||||
|
const [dewarsToReplace, setDewarsToReplace] = useState([]);
|
||||||
|
const [dewarsToCreate, setDewarsToCreate] = useState(new Map());
|
||||||
|
|
||||||
const initialNewDewarState = {
|
const initialNewDewarState = {
|
||||||
number_of_pucks: 0,
|
number_of_pucks: 0,
|
||||||
@ -44,7 +52,7 @@ const SpreadsheetTable = ({
|
|||||||
dewar_name: '',
|
dewar_name: '',
|
||||||
tracking_number: 'UNKNOWN',
|
tracking_number: 'UNKNOWN',
|
||||||
status: 'In preparation',
|
status: 'In preparation',
|
||||||
pucks: []
|
pucks: [] // Ensure 'pucks' array exists
|
||||||
};
|
};
|
||||||
|
|
||||||
const [newDewar, setNewDewar] = useState(initialNewDewarState);
|
const [newDewar, setNewDewar] = useState(initialNewDewarState);
|
||||||
@ -141,36 +149,80 @@ const SpreadsheetTable = ({
|
|||||||
'dewarname': 0,
|
'dewarname': 0,
|
||||||
'puckname': 1,
|
'puckname': 1,
|
||||||
'pucktype': 2,
|
'pucktype': 2,
|
||||||
// Add other fields as needed
|
'crystalname': 3,
|
||||||
|
'positioninpuck': 4,
|
||||||
|
'priority': 5,
|
||||||
|
'comments': 6,
|
||||||
|
'directory': 7,
|
||||||
|
'proteinname': 8,
|
||||||
|
'oscillation': 9,
|
||||||
|
'aperture': 10,
|
||||||
|
'exposure': 11,
|
||||||
|
'totalrange': 12,
|
||||||
|
'transmission': 13,
|
||||||
|
'dose': 14,
|
||||||
|
'targetresolution': 15,
|
||||||
|
'datacollectiontype': 16,
|
||||||
|
'processingpipeline': 17,
|
||||||
|
'spacegroupnumber': 18,
|
||||||
|
'cellparameters': 19,
|
||||||
|
'rescutkey': 20,
|
||||||
|
'rescutvalue': 21,
|
||||||
|
'userresolution': 22,
|
||||||
|
'pdbid': 23,
|
||||||
|
'autoprocfull': 24,
|
||||||
|
'procfull': 25,
|
||||||
|
'adpenabled': 26,
|
||||||
|
'noano': 27,
|
||||||
|
'ffcscampaign': 28,
|
||||||
|
'trustedhigh': 29,
|
||||||
|
'autoprocextraparams': 30,
|
||||||
|
'chiphiangles': 31
|
||||||
};
|
};
|
||||||
|
|
||||||
const createDewarsFromSheet = async (data, contactPerson, returnAddress) => {
|
const checkIfDewarExists = async (dewarName) => {
|
||||||
|
if (!selectedShipment) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const shipDewars = await ShipmentsService.getDewarsByShipmentIdShipmentsShipmentIdDewarsGet(selectedShipment.id);
|
||||||
|
return shipDewars.find((d) => d.dewar_name === dewarName);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch existing dewars:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createOrUpdateDewarsFromSheet = async (data, contactPerson, returnAddress) => {
|
||||||
if (!contactPerson?.id || !returnAddress?.id) {
|
if (!contactPerson?.id || !returnAddress?.id) {
|
||||||
console.error('contact_person_id or return_address_id is missing');
|
console.error('contact_person_id or return_address_id is missing');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dewars = new Map();
|
const dewars = new Map();
|
||||||
|
const puckPositionMap = new Map();
|
||||||
|
const dewarsToReplace = [];
|
||||||
|
|
||||||
const dewarNameIdx = fieldToCol['dewarname'];
|
const dewarNameIdx = fieldToCol['dewarname'];
|
||||||
const puckNameIdx = fieldToCol['puckname'];
|
const puckNameIdx = fieldToCol['puckname'];
|
||||||
const puckTypeIdx = fieldToCol['pucktype'];
|
const puckTypeIdx = fieldToCol['pucktype'];
|
||||||
|
const sampleNameIdx = fieldToCol['crystalname'];
|
||||||
|
const samplePositionIdx = fieldToCol['positioninpuck'];
|
||||||
|
|
||||||
let puckPositionInDewar = 1;
|
for (let rowIndex = 0; rowIndex < data.length; rowIndex++) {
|
||||||
|
const row = data[rowIndex];
|
||||||
|
|
||||||
for (const row of data) {
|
|
||||||
if (!row.data) {
|
if (!row.data) {
|
||||||
console.error(`Row data is missing`);
|
console.error('Row data is missing');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dewarName = typeof row.data[dewarNameIdx] === 'string' ? row.data[dewarNameIdx].trim() : null;
|
const dewarName = typeof row.data[dewarNameIdx] === 'string' ? row.data[dewarNameIdx].trim() : null;
|
||||||
const puckName = typeof row.data[puckNameIdx] === 'string' ? row.data[puckNameIdx].trim() : null;
|
const puckName = row.data[puckNameIdx] !== undefined && row.data[puckNameIdx] !== null ? String(row.data[puckNameIdx]).trim() : null;
|
||||||
const puckType = typeof row.data[puckTypeIdx] === 'string' ? row.data[puckTypeIdx] : 'Unipuck';
|
const puckType = typeof row.data[puckTypeIdx] === 'string' ? row.data[puckTypeIdx] : 'Unipuck';
|
||||||
|
const sampleName = typeof row.data[sampleNameIdx] === 'string' ? row.data[sampleNameIdx].trim() : null;
|
||||||
|
const samplePosition = row.data[samplePositionIdx] !== undefined && row.data[samplePositionIdx] !== null ? Number(row.data[samplePositionIdx]) : null;
|
||||||
|
|
||||||
console.log(`Processing Dewar: ${dewarName}, Puck: ${puckName}, Type: ${puckType}`);
|
if (dewarName && puckName) {
|
||||||
|
|
||||||
if (dewarName) {
|
|
||||||
let dewar;
|
let dewar;
|
||||||
if (!dewars.has(dewarName)) {
|
if (!dewars.has(dewarName)) {
|
||||||
dewar = {
|
dewar = {
|
||||||
@ -181,44 +233,116 @@ const SpreadsheetTable = ({
|
|||||||
pucks: []
|
pucks: []
|
||||||
};
|
};
|
||||||
dewars.set(dewarName, dewar);
|
dewars.set(dewarName, dewar);
|
||||||
puckPositionInDewar = 1;
|
puckPositionMap.set(dewarName, new Map());
|
||||||
console.log(`Created new dewar: ${dewarName}`);
|
|
||||||
|
// Check if the dewar exists in the shipment
|
||||||
|
const existingDewar = await checkIfDewarExists(dewarName);
|
||||||
|
if (existingDewar) {
|
||||||
|
dewarsToReplace.push(existingDewar);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dewar = dewars.get(dewarName);
|
dewar = dewars.get(dewarName);
|
||||||
puckPositionInDewar++;
|
|
||||||
console.log(`Found existing dewar: ${dewarName}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const puck = {
|
let puckPositions = puckPositionMap.get(dewarName);
|
||||||
puck_name: puckName || 'test', // Fixed puck name
|
if (!puckPositions.has(puckName)) {
|
||||||
puck_type: puckType || 'Unipuck', // Fixed puck type
|
puckPositions.set(puckName, puckPositions.size + 1);
|
||||||
puck_position_in_dewar: puckPositionInDewar
|
}
|
||||||
};
|
const puckPosition = puckPositions.get(puckName);
|
||||||
dewar.pucks.push(puck);
|
|
||||||
|
|
||||||
console.log(`Added puck: ${JSON.stringify(puck)}`);
|
let puck = dewar.pucks.find(p => p.puck_name === puckName);
|
||||||
|
if (!puck) {
|
||||||
|
puck = {
|
||||||
|
puck_name: puckName,
|
||||||
|
puck_type: puckType,
|
||||||
|
puck_location_in_dewar: puckPosition,
|
||||||
|
samples: []
|
||||||
|
};
|
||||||
|
dewar.pucks.push(puck);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sample = {
|
||||||
|
sample_name: sampleName,
|
||||||
|
position: samplePosition,
|
||||||
|
results: null // Placeholder for results field
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isNaN(sample.position)) {
|
||||||
|
console.error(`Invalid sample position for sample ${sample.sample_name} in puck ${puckName}`);
|
||||||
|
} else {
|
||||||
|
puck.samples.push(sample);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('Dewar name is missing in the row');
|
if (!dewarName) {
|
||||||
|
console.error(`Dewar name is missing in row ${rowIndex}`);
|
||||||
|
}
|
||||||
|
if (!puckName) {
|
||||||
|
console.error(`Puck name is missing in row ${rowIndex}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const dewarsArray = Array.from(dewars.values());
|
const dewarsArray = Array.from(dewars.values());
|
||||||
|
|
||||||
|
// Save dewars array for later use in handleConfirmUpdate
|
||||||
|
setDewarsToCreate(dewars);
|
||||||
|
|
||||||
|
if (dewarsArray.length > 0 && dewarsToReplace.length > 0) {
|
||||||
|
setDewarsToReplace(dewarsToReplace);
|
||||||
|
setShowUpdateDialog(true);
|
||||||
|
} else {
|
||||||
|
await handleDewarCreation(dewarsArray);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleConfirmUpdate = async () => {
|
||||||
|
if (dewarsToReplace.length === 0) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (const dewar of dewarsToReplace) {
|
||||||
|
await DewarsService.deleteDewarDewarsDewarIdDelete(dewar.id);
|
||||||
|
}
|
||||||
|
const dewarsArray = Array.from(dewarsToCreate.values());
|
||||||
|
await handleDewarCreation(dewarsArray);
|
||||||
|
console.log('Dewars replaced successfully');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error replacing dewar', error);
|
||||||
|
if (error instanceof ApiError && error.body) {
|
||||||
|
console.error('Validation errors:', error.body.detail);
|
||||||
|
} else {
|
||||||
|
console.error('Unexpected error:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setShowUpdateDialog(false);
|
||||||
|
setDewarsToReplace([]);
|
||||||
|
setDewarsToCreate(new Map());
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancelUpdate = () => {
|
||||||
|
setShowUpdateDialog(false);
|
||||||
|
setDewarsToReplace([]);
|
||||||
|
setDewarsToCreate(new Map());
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDewarCreation = async (dewarsArray) => {
|
||||||
for (const dewar of dewarsArray) {
|
for (const dewar of dewarsArray) {
|
||||||
try {
|
try {
|
||||||
// Call to create the dewar
|
if (!dewar.pucks || dewar.pucks.length === 0) {
|
||||||
const createdDewar = await DewarsService.createDewarDewarsPost(dewar);
|
console.error(`Dewar ${dewar.dewar_name} does not have any pucks.`);
|
||||||
console.log(`Created dewar: ${createdDewar.id}`);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const createdDewar = await DewarsService.createDewarDewarsPost(dewar);
|
||||||
|
|
||||||
// Add dewar to the shipment if created successfully
|
|
||||||
if (createdDewar && selectedShipment) {
|
if (createdDewar && selectedShipment) {
|
||||||
await ShipmentsService.addDewarToShipmentShipmentsShipmentIdAddDewarPost(
|
await ShipmentsService.addDewarToShipmentShipmentsShipmentIdAddDewarPost(
|
||||||
selectedShipment.id,
|
selectedShipment.id,
|
||||||
createdDewar.id
|
createdDewar.id
|
||||||
);
|
);
|
||||||
console.log(`Added dewar to shipment: ${createdDewar.id}`);
|
console.log(`Dewar ${createdDewar.dewar_name} with ID ${createdDewar.id} created and added to the shipment.`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error adding dewar`, error);
|
console.error('Error adding dewar', error);
|
||||||
if (error instanceof ApiError && error.body) {
|
if (error instanceof ApiError && error.body) {
|
||||||
console.error('Validation errors:', error.body.detail);
|
console.error('Validation errors:', error.body.detail);
|
||||||
} else {
|
} else {
|
||||||
@ -226,8 +350,6 @@ const SpreadsheetTable = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dewarsArray;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
@ -241,18 +363,12 @@ const SpreadsheetTable = ({
|
|||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
console.log('All data is valid. Proceeding with submission...');
|
console.log('All data is valid. Proceeding with submission...');
|
||||||
|
|
||||||
const processedDewars = await createDewarsFromSheet(
|
await createOrUpdateDewarsFromSheet(
|
||||||
raw_data,
|
raw_data,
|
||||||
selectedShipment?.contact_person,
|
selectedShipment?.contact_person,
|
||||||
selectedShipment?.return_address
|
selectedShipment?.return_address
|
||||||
);
|
);
|
||||||
|
|
||||||
if (processedDewars && processedDewars.length > 0) {
|
|
||||||
console.log('Dewars processed successfully.');
|
|
||||||
} else {
|
|
||||||
console.error('No valid dewars were created.');
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
} 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.');
|
||||||
@ -270,22 +386,12 @@ const SpreadsheetTable = ({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const buffer = await workbook.xlsx.writeBuffer();
|
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||||
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||||
|
saveAs(blob, 'corrected_spreadsheet.xlsx');
|
||||||
saveAs(blob, 'corrected_data.xlsx');
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log('Raw data:', raw_data);
|
|
||||||
console.log('Errors:', localErrors);
|
|
||||||
console.log('Headers:', headers);
|
|
||||||
}, [raw_data, localErrors, headers]);
|
|
||||||
|
|
||||||
if (!raw_data || !headers) {
|
|
||||||
return <div>Loading...</div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableContainer component={Paper}>
|
<TableContainer component={Paper}>
|
||||||
<Table>
|
<Table>
|
||||||
@ -323,21 +429,25 @@ const SpreadsheetTable = ({
|
|||||||
return (
|
return (
|
||||||
<TableCell key={colIndex} align="center">
|
<TableCell key={colIndex} align="center">
|
||||||
<Tooltip title={errorMessage || ""} arrow disableHoverListener={!isInvalid}>
|
<Tooltip title={errorMessage || ""} arrow disableHoverListener={!isInvalid}>
|
||||||
<TextField
|
{isInvalid ? (
|
||||||
value={editingValue !== undefined ? editingValue : cellValue}
|
<TextField
|
||||||
onChange={(e) => setEditingCell({ ...editingCell, [`${rowIndex}-${colIndex}`]: e.target.value })}
|
value={editingValue !== undefined ? editingValue : cellValue}
|
||||||
onKeyDown={(e) => {
|
onChange={(e) => setEditingCell({ ...editingCell, [`${rowIndex}-${colIndex}`]: e.target.value })}
|
||||||
if (e.key === "Enter") {
|
onKeyDown={(e) => {
|
||||||
handleCellEdit(rowIndex, colIndex);
|
if (e.key === "Enter") {
|
||||||
}
|
handleCellEdit(rowIndex, colIndex);
|
||||||
}}
|
}
|
||||||
onBlur={() => handleCellBlur(rowIndex, colIndex)}
|
}}
|
||||||
error={isInvalid}
|
onBlur={() => handleCellBlur(rowIndex, colIndex)}
|
||||||
fullWidth
|
error={isInvalid}
|
||||||
variant="outlined"
|
fullWidth
|
||||||
size="small"
|
variant="outlined"
|
||||||
disabled={isReadonly}
|
size="small"
|
||||||
/>
|
disabled={isReadonly}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
cellValue
|
||||||
|
)}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
);
|
);
|
||||||
@ -346,6 +456,28 @@ const SpreadsheetTable = ({
|
|||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
open={showUpdateDialog}
|
||||||
|
onClose={handleCancelUpdate}
|
||||||
|
aria-labelledby="alert-dialog-title"
|
||||||
|
aria-describedby="alert-dialog-description"
|
||||||
|
>
|
||||||
|
<DialogTitle id="alert-dialog-title">Replace Dewars</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogContentText id="alert-dialog-description">
|
||||||
|
The following dewars already exist: {dewarsToReplace.map(dewar => dewar.dewar_name).join(', ')}. Would you like to replace them?
|
||||||
|
</DialogContentText>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={handleCancelUpdate} color="primary">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button onClick={handleConfirmUpdate} color="primary" autoFocus>
|
||||||
|
Replace
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user