now creating dewars from spreadsheet

This commit is contained in:
GotthardG
2024-11-11 21:37:59 +01:00
parent 52fe68b2bc
commit 5e6eb40033
6 changed files with 207 additions and 79 deletions

View File

@ -61,6 +61,10 @@ const ShipmentPanel: React.FC<ShipmentPanelProps> = ({
const isSelected = selectedShipment?.id === shipment.id;
const updatedShipment = isSelected ? null : shipment;
console.log("Shipment selected:", updatedShipment); // debug log
if (updatedShipment) {
console.log("Contact Person ID:", updatedShipment.contact_person_id);
console.log("Return Address ID:", updatedShipment.return_address_id);
}
selectShipment(updatedShipment);
};

View File

@ -13,10 +13,16 @@ import {
Button,
Box
} from '@mui/material';
import { SpreadsheetService, ShipmentsService } from '../../openapi';
import { SpreadsheetService, ShipmentsService, DewarsService, ApiError } from '../../openapi';
import * as ExcelJS from 'exceljs';
import { saveAs } from 'file-saver';
const HeaderMapping = {
'dewarname': 'dewar_name',
'trackingnumber': 'tracking_number',
'status': 'status'
};
const SpreadsheetTable = ({
raw_data,
errors,
@ -24,11 +30,37 @@ const SpreadsheetTable = ({
setRawData,
onCancel,
fileBlob,
shipmentId // Accept the shipmentId
selectedShipment
}) => {
const [localErrors, setLocalErrors] = useState(errors || []);
const [editingCell, setEditingCell] = useState({});
const [nonEditableCells, setNonEditableCells] = useState(new Set());
const [isSubmitting, setIsSubmitting] = useState(false);
const initialNewDewarState = {
number_of_pucks: 0,
number_of_samples: 0,
ready_date: null,
shipping_date: null,
arrival_date: null,
returning_date: null,
qrcode: 'N/A',
contact_person_id: selectedShipment?.contact_person?.id,
return_address_id: selectedShipment?.return_address?.id,
dewar_name: '',
tracking_number: 'UNKNOWN',
status: 'In preparation',
};
const [newDewar, setNewDewar] = useState(initialNewDewarState);
useEffect(() => {
setNewDewar((prev) => ({
...prev,
contact_person_id: selectedShipment?.contact_person?.id,
return_address_id: selectedShipment?.return_address?.id
}));
}, [selectedShipment]);
const generateErrorMap = (errorsList) => {
const errorMap = new Map();
@ -112,78 +144,122 @@ const SpreadsheetTable = ({
const allCellsValid = () => nonEditableCells.size === raw_data.length * headers.length;
const handleSubmit = async () => {
if (allCellsValid()) {
console.log('All data is valid. Proceeding with submission...');
const processedData = createPayload(raw_data);
const fieldToCol = {
'dewarname': 0,
'puckname': 1,
'pucktype': 2,
'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,
};
try {
const response = await ShipmentsService.addDewarPuckSampleToShipmentShipmentsShipmentIdAddDewarPuckSamplePost(shipmentId, processedData);
console.log('Shipment processed successfully:', response);
const createDewarsFromSheet = async (data, contactPerson, returnAddress) => {
if (!contactPerson?.id || !returnAddress?.id) {
console.error('contact_person_id or return_address_id is missing');
return null;
}
// 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.
const dewars = new Map(); // Use a Map to prevent duplicates
for (const row of data) {
if (!row.data) {
console.error(`Row data is missing`);
continue;
}
const dewarNameIdx = fieldToCol['dewarname'];
const dewarName = row.data[dewarNameIdx]?.trim();
if (dewarName && !dewars.has(dewarName)) {
const newDewarToPost = {
...initialNewDewarState,
dewar_name: dewarName,
tracking_number: row.data[fieldToCol['trackingnumber']] || "UNKNOWN",
status: row.data[fieldToCol['status']] || "In preparation",
contact_person_id: contactPerson.id,
return_address_id: returnAddress.id,
};
try {
const createdDewar = await DewarsService.createDewarDewarsPost(newDewarToPost);
if (createdDewar && selectedShipment) {
const updatedShipment = await ShipmentsService.addDewarToShipmentShipmentsShipmentIdAddDewarPost(
selectedShipment.id,
createdDewar.id
);
dewars.set(dewarName, updatedShipment); // Track the added dewar
}
} catch (error) {
console.error(`Error adding dewar for row: ${row.row_num}`, error);
if (error instanceof ApiError && error.body) {
console.error('Validation errors:', error.body.detail);
} else {
console.error('Unexpected error:', error);
}
}
} else if (!dewarName) {
console.error('Dewar name is missing in the row');
}
}
return Array.from(dewars.values());
};
const handleSubmit = async () => {
if (isSubmitting) return; // Prevent multiple submissions
if (!headers || headers.length === 0) {
console.error('Cannot submit, headers are not defined or empty');
return;
}
if (allCellsValid()) {
setIsSubmitting(true);
console.log('All data is valid. Proceeding with submission...');
const processedDewars = await createDewarsFromSheet(
raw_data,
selectedShipment?.contact_person,
selectedShipment?.return_address
);
if (processedDewars && processedDewars.length > 0) {
console.log('Dewars processed successfully.');
} else {
console.error('No valid dewars were created.');
}
setIsSubmitting(false);
} else {
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 workbook = new ExcelJS.Workbook();
await workbook.xlsx.load(fileBlob);
@ -227,7 +303,7 @@ const SpreadsheetTable = ({
<Button variant="contained" color="secondary" onClick={onCancel}>
Cancel
</Button>
<Button variant="contained" color="primary" onClick={handleSubmit} disabled={!allCellsValid()}>
<Button variant="contained" color="primary" onClick={handleSubmit} disabled={!allCellsValid() || isSubmitting}>
Submit
</Button>
<Button variant="contained" onClick={downloadCorrectedSpreadsheet} disabled={!allCellsValid()}>

View File

@ -166,7 +166,7 @@ const UploadDialog: React.FC<UploadDialogProps> = ({ open, onClose, selectedShip
setRawData={(newRawData) => setFileSummary((prevSummary) => ({ ...prevSummary, raw_data: newRawData }))}
onCancel={handleCancel}
fileBlob={fileBlob} // Pass the original file blob
shipmentId={selectedShipment?.id} // Pass the selected shipment ID
selectedShipment={selectedShipment} // Pass the selected shipment ID
/>
</Modal>
)}