From dc1c8f413654300794756304ae8ca4660b108aab Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Sun, 6 Jul 2025 22:24:01 +0200 Subject: [PATCH] Fix importing the bill of materials --- src/components/JobCard.tsx | 67 +++++++++++++++++++-------------- src/components/JobForm.tsx | 18 +++++++-- src/pages/JobDetails.tsx | 18 ++++++++- src/services/billItemService.ts | 18 ++++++++- src/services/dataService.ts | 15 +++++--- 5 files changed, 96 insertions(+), 40 deletions(-) diff --git a/src/components/JobCard.tsx b/src/components/JobCard.tsx index 832293c..c0225de 100644 --- a/src/components/JobCard.tsx +++ b/src/components/JobCard.tsx @@ -19,13 +19,13 @@ interface JobCardProps { isTracked?: boolean; } -const JobCard: React.FC = ({ - job, - onEdit, - onDelete, - onUpdateProduced, +const JobCard: React.FC = ({ + job, + onEdit, + onDelete, + onUpdateProduced, onImportBOM, - isTracked = false + isTracked = false }) => { const navigate = useNavigate(); const [isEditingProduced, setIsEditingProduced] = useState(false); @@ -33,10 +33,10 @@ const JobCard: React.FC = ({ const [copyingBom, setCopyingBom] = useState(false); const { toast } = useToast(); - const sortedExpenditures = [...job.expenditures].sort((a, b) => + const sortedExpenditures = [...job.expenditures].sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() ); - const sortedIncome = [...job.income].sort((a, b) => + const sortedIncome = [...job.income].sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() ); @@ -95,23 +95,34 @@ const JobCard: React.FC = ({ }; const importBillOfMaterials = async () => { + if (!onImportBOM) { + toast({ + title: "Error", + description: "Import functionality is not available", + variant: "destructive", + duration: 2000, + }); + return; + } + try { const clipboardText = await navigator.clipboard.readText(); const lines = clipboardText.split('\n').filter(line => line.trim()); const items: { name: string; quantity: number }[] = []; - + for (const line of lines) { - const parts = line.trim().split(/\s+/); + const parts = line.trim().split(/[\s\t]+/); if (parts.length >= 2) { const name = parts.slice(0, -1).join(' '); - const quantity = parseInt(parts[parts.length - 1]); + const quantityPart = parts[parts.length - 1].replace(/,/g, ''); + const quantity = parseInt(quantityPart); if (name && !isNaN(quantity)) { items.push({ name, quantity }); } } } - - if (items.length > 0 && onImportBOM) { + + if (items.length > 0) { onImportBOM(job.id, items); toast({ title: "BOM Imported", @@ -150,7 +161,7 @@ const JobCard: React.FC = ({ const text = job.billOfMaterials .map(item => `${item.name}\t${item.quantity.toLocaleString()}`) .join('\n'); - + try { await navigator.clipboard.writeText(text); setCopyingBom(true); @@ -202,7 +213,7 @@ const JobCard: React.FC = ({ }; return ( - @@ -232,7 +243,7 @@ const JobCard: React.FC = ({ autoFocus /> ) : ( - = ({
- -