Fix creating bill items

This commit is contained in:
2025-07-04 16:44:06 +02:00
parent 6f60993621
commit 63f3db6197
4 changed files with 39 additions and 40 deletions

View File

@@ -6,7 +6,7 @@ import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { IndBillitemRecordNoId, IndJobStatusOptions, IndJobRecordNoId, IndFacilityRecord } from '@/lib/pbtypes';
import { IndBillitemRecordNoId, IndJobStatusOptions, IndJobRecordNoId, IndFacilityRecord, IndBillitemRecord } from '@/lib/pbtypes';
import MaterialsImportExport from './MaterialsImportExport';
import { IndJob } from '@/lib/types';
// import { getFacilities } from '@/services/facilityService';
@@ -19,8 +19,8 @@ interface JobFormProps {
const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
// const [facilities, setFacilities] = useState<IndFacilityRecord[]>([]);
const [billOfMaterials, setBillOfMaterials] = useState<IndBillitemRecordNoId[]>(job?.billOfMaterials || []);
const [consumedMaterials, setConsumedMaterials] = useState<IndBillitemRecordNoId[]>(job?.consumedMaterials || []);
const [billOfMaterials, setBillOfMaterials] = useState<IndBillitemRecord[]>(job?.billOfMaterials || []);
const [consumedMaterials, setConsumedMaterials] = useState<IndBillitemRecord[]>(job?.consumedMaterials || []);
const [formData, setFormData] = useState({
outputItem: job?.outputItem || '',
outputQuantity: job?.outputQuantity || 0,
@@ -209,7 +209,7 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
<TabsContent value="materials" className="space-y-4">
<MaterialsImportExport
jobId={job?.id || ''}
job={job}
billOfMaterials={billOfMaterials}
consumedMaterials={consumedMaterials}
onBillOfMaterialsUpdate={setBillOfMaterials}

View File

@@ -4,19 +4,21 @@ import { Button } from '@/components/ui/button';
import { Textarea } from '@/components/ui/textarea';
import { Label } from '@/components/ui/label';
import { Import, Download, FileText } from 'lucide-react';
import { IndBillitemRecordNoId } from '@/lib/pbtypes';
import { IndBillitemRecord } from '@/lib/pbtypes';
import { IndJob } from '@/lib/types';
import { addBillItem } from '@/services/billItemService';
import { updateJob } from '@/services/jobService';
interface MaterialsImportExportProps {
jobId: string;
billOfMaterials: IndBillitemRecordNoId[];
consumedMaterials: IndBillitemRecordNoId[];
onBillOfMaterialsUpdate: (materials: IndBillitemRecordNoId[]) => void;
onConsumedMaterialsUpdate: (materials: IndBillitemRecordNoId[]) => void;
job: IndJob;
billOfMaterials: IndBillitemRecord[];
consumedMaterials: IndBillitemRecord[];
onBillOfMaterialsUpdate: (billItems: IndBillitemRecord[]) => void;
onConsumedMaterialsUpdate: (billItems: IndBillitemRecord[]) => void;
}
const MaterialsImportExport: React.FC<MaterialsImportExportProps> = ({
jobId,
job,
billOfMaterials,
consumedMaterials,
onBillOfMaterialsUpdate,
@@ -25,9 +27,9 @@ const MaterialsImportExport: React.FC<MaterialsImportExportProps> = ({
const [bomInput, setBomInput] = useState('');
const [consumedInput, setConsumedInput] = useState('');
const parseBillOfMaterials = (text: string): IndBillitemRecordNoId[] => {
const parseBillOfMaterials = async (text: string): Promise<IndJob> => {
const lines = text.split('\n').filter(line => line.trim());
const materials: IndBillitemRecordNoId[] = [];
const materials: IndBillitemRecord[] = [];
for (const line of lines) {
const parts = line.trim().split(/\s+/);
@@ -35,16 +37,20 @@ const MaterialsImportExport: React.FC<MaterialsImportExportProps> = ({
const name = parts.slice(0, -1).join(' ');
const quantity = parseInt(parts[parts.length - 1]);
if (name && !isNaN(quantity)) {
materials.push({ name, quantity });
const newBillItem = await addBillItem(job.id, { name, quantity });
materials.push(newBillItem);
}
}
}
return materials;
job.billOfMaterials = materials;
await updateJob(job.id, { billOfMaterials: materials.map(item => item.id) });
return job;
};
const parseConsumedMaterials = (text: string): IndBillitemRecordNoId[] => {
const parseConsumedMaterials = async (text: string): Promise<IndJob> => {
const lines = text.split('\n').filter(line => line.trim());
const materials: IndBillitemRecordNoId[] = [];
const materials: IndBillitemRecord[] = [];
for (const line of lines) {
const parts = line.trim().split('\t');
@@ -52,11 +58,15 @@ const MaterialsImportExport: React.FC<MaterialsImportExportProps> = ({
const name = parts[0];
const quantity = parseInt(parts[1]);
if (name && !isNaN(quantity)) {
materials.push({ name, quantity });
const newBillItem = await addBillItem(job.id, { name, quantity });
materials.push(newBillItem);
}
}
}
return materials;
job.consumedMaterials = materials;
await updateJob(job.id, { consumedMaterials: materials.map(item => item.id) });
return job;
};
const exportBillOfMaterials = (): string => {
@@ -69,13 +79,13 @@ const MaterialsImportExport: React.FC<MaterialsImportExportProps> = ({
const handleImportBom = async () => {
const parsed = await parseBillOfMaterials(bomInput);
onBillOfMaterialsUpdate(parsed);
onBillOfMaterialsUpdate(parsed.billOfMaterials);
setBomInput('');
};
const handleImportConsumed = async () => {
const parsed = await parseConsumedMaterials(consumedInput);
onConsumedMaterialsUpdate(parsed);
onConsumedMaterialsUpdate(parsed.consumedMaterials);
setConsumedInput('');
};

View File

@@ -2,10 +2,9 @@ import { useState, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Plus, Factory, TrendingUp, Briefcase } from 'lucide-react';
import { IndTransactionResponse, IndJobRecord, IndTransactionRecord, IndTransactionRecordNoId } from '@/lib/pbtypes';
import { IndTransactionRecordNoId, IndJobRecordNoId, IndTransactionRecord } from '@/lib/pbtypes';
import * as jobService from '@/services/jobService';
import * as transactionService from '@/services/transactionService';
import * as billItemService from '@/services/billItemService';
import { formatISK } from '@/utils/priceUtils';
import JobCard from '@/components/JobCard';
import JobForm from '@/components/JobForm';
@@ -14,6 +13,7 @@ import TransactionTable from '@/components/TransactionTable';
import { IndJob } from '@/lib/types';
import { createJob } from '@/services/jobService';
// TODO: Bill of materials just does not work currently Fix this shit
// Extended job type for UI components
const Index = () => {
const [jobs, setJobs] = useState<IndJob[]>([]);
@@ -36,7 +36,7 @@ const Index = () => {
}
};
const handleCreateJob = async (jobData: Omit<IndJobRecord, 'id' | 'created' | 'updated'>) => {
const handleCreateJob = async (jobData: IndJobRecordNoId) => {
try {
const newJob = await createJob(jobData);
const jobWithRelations: IndJob = {
@@ -58,7 +58,7 @@ const Index = () => {
setShowJobForm(true);
};
const handleUpdateJob = async (jobData: Omit<IndJobRecord, 'id' | 'created' | 'updated'>) => {
const handleUpdateJob = async (jobData: IndJobRecordNoId) => {
if (!editingJob) return;
try {
@@ -114,7 +114,7 @@ const Index = () => {
}
};
const handleUpdateTransaction = async (transactionId: string, updates: Partial<IndTransactionResponse>) => {
const handleUpdateTransaction = async (transactionId: string, updates: Partial<IndTransactionRecord>) => {
if (!selectedJob) return;
try {

View File

@@ -1,21 +1,10 @@
import { IndBillitemRecord, IndBillitemRecordNoId } from "@/lib/pbtypes";
import { IndJob } from "@/lib/types";
import pb from "@/lib/pocketbase";
import { updateJob } from "./jobService";
export async function addBillItem(
job: IndJob,
billItem: IndBillitemRecordNoId,
type: 'billOfMaterials' | 'consumedMaterials'
jobId: string,
billItem: IndBillitemRecordNoId
): Promise<IndBillitemRecord> {
console.log('Adding bill item:', billItem);
// Create the bill item
const createdItem = await pb.collection<IndBillitemRecord>('ind_billItem').create(billItem);
const currentBillItems = job[type] || [];
await updateJob(job.id, {
[type]: [...currentBillItems, createdItem.id]
});
return createdItem;
return await pb.collection<IndBillitemRecord>('ind_billItem').create(billItem);
}