Entirely rework job service
This commit is contained in:
@@ -1,99 +1,109 @@
|
||||
|
||||
import type { IndJobRecord, IndJobResponse, IndTransactionRecord, IndTransactionResponse, IndBillitemRecord, IndBillitemResponse } from '../lib/pbtypes';
|
||||
import { IndJob } from '@/lib/types';
|
||||
import type { IndJobRecord, IndTransactionRecord, IndBillitemRecord, IndJobRecordNoId } from '../lib/pbtypes';
|
||||
import pb from '../lib/pocketbase';
|
||||
|
||||
export type { IndJobRecord as Job } from '../lib/pbtypes';
|
||||
export type { IndTransactionRecord as Transaction } from '../lib/pbtypes';
|
||||
export type { IndBillitemRecord as BillItem } from '../lib/pbtypes';
|
||||
|
||||
export async function createJob(job: Omit<IndJobRecord, 'id' | 'created' | 'updated'>): Promise<IndJobResponse> {
|
||||
return await pb.collection('ind_job').create(job) as IndJobResponse;
|
||||
export async function createJob(job: IndJobRecordNoId): Promise<IndJobRecord> {
|
||||
return await pb.collection<IndJobRecord>('ind_job').create(job);
|
||||
}
|
||||
|
||||
export async function getJobs(): Promise<IndJobResponse[]> {
|
||||
const result = await pb.collection('ind_job').getFullList();
|
||||
return result as IndJobResponse[];
|
||||
export async function getJobs(): Promise<IndJobRecord[]> {
|
||||
const result = await pb.collection<IndJobRecord>('ind_job').getFullList();
|
||||
return result;
|
||||
}
|
||||
export async function getJobsFull(): Promise<IndJob[]> {
|
||||
const jobs = await getJobs();
|
||||
return await Promise.all(jobs.map(toFullJob));
|
||||
}
|
||||
|
||||
export async function getJob(id: string): Promise<IndJobResponse | null> {
|
||||
export async function getJob(id: string): Promise<IndJobRecord | null> {
|
||||
try {
|
||||
return await pb.collection('ind_job').getOne(id) as IndJobResponse;
|
||||
return await pb.collection<IndJobRecord>('ind_job').getOne(id);
|
||||
} catch (e) {
|
||||
if (e.status === 404) return null;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
export async function getJobFull(id: string): Promise<IndJob | null> {
|
||||
const job = await getJob(id);
|
||||
if (!job) return null;
|
||||
return await toFullJob(job);
|
||||
}
|
||||
|
||||
export async function updateJob(id: string, updates: Partial<IndJobRecord>): Promise<IndJobResponse> {
|
||||
return await pb.collection('ind_job').update(id, updates) as IndJobResponse;
|
||||
export async function updateJob(id: string, updates: Partial<IndJobRecord>): Promise<IndJobRecord> {
|
||||
return await pb.collection<IndJobRecord>('ind_job').update(id, updates);
|
||||
}
|
||||
|
||||
export async function deleteJob(id: string): Promise<void> {
|
||||
await pb.collection('ind_job').delete(id);
|
||||
await pb.collection<IndJobRecord>('ind_job').delete(id);
|
||||
}
|
||||
|
||||
export async function addTransaction(
|
||||
jobId: string,
|
||||
transaction: Omit<IndTransactionRecord, 'id' | 'created' | 'updated'>,
|
||||
type: 'expenditure' | 'income'
|
||||
): Promise<void> {
|
||||
// Create the transaction
|
||||
const createdTransaction = await pb.collection('ind_transaction').create({
|
||||
...transaction,
|
||||
job: jobId
|
||||
}) as IndTransactionResponse;
|
||||
async function toFullJob(job: IndJobRecord): Promise<IndJob> {
|
||||
const fullJob = {
|
||||
...job,
|
||||
expenditures: [],
|
||||
income: [],
|
||||
billOfMaterials: [],
|
||||
consumedMaterials: []
|
||||
};
|
||||
|
||||
// Update the job to include the new transaction
|
||||
const job = await getJob(jobId);
|
||||
if (!job) throw new Error('Job not found');
|
||||
if (job.expenditures) {
|
||||
for (const txId of job.expenditures) {
|
||||
try {
|
||||
const tx = await pb.collection('ind_transaction').getOne(txId);
|
||||
fullJob.expenditures.push(tx as IndTransactionRecord);
|
||||
} catch (e) {
|
||||
console.warn('Failed to fetch expenditure transaction:', txId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const field = type === 'expenditure' ? 'expenditures' : 'income';
|
||||
const currentIds = job[field] || [];
|
||||
if (job.income) {
|
||||
for (const txId of job.income) {
|
||||
try {
|
||||
const tx = await pb.collection('ind_transaction').getOne(txId);
|
||||
fullJob.income.push(tx as IndTransactionRecord);
|
||||
} catch (e) {
|
||||
console.warn('Failed to fetch income transaction:', txId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await updateJob(jobId, {
|
||||
[field]: [...currentIds, createdTransaction.id]
|
||||
});
|
||||
if (job.billOfMaterials) {
|
||||
for (const itemId of job.billOfMaterials) {
|
||||
try {
|
||||
const item = await pb.collection('ind_billItem').getOne(itemId);
|
||||
fullJob.billOfMaterials.push(item as IndBillitemRecord);
|
||||
} catch (e) {
|
||||
console.warn('Failed to fetch bill item:', itemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (job.consumedMaterials) {
|
||||
for (const itemId of job.consumedMaterials) {
|
||||
try {
|
||||
const item = await pb.collection('ind_billItem').getOne(itemId);
|
||||
fullJob.consumedMaterials.push(item as IndBillitemRecord);
|
||||
} catch (e) {
|
||||
console.warn('Failed to fetch consumed material:', itemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fullJob;
|
||||
}
|
||||
|
||||
export async function updateTransaction(
|
||||
jobId: string,
|
||||
transactionId: string,
|
||||
updates: Partial<IndTransactionRecord>
|
||||
): Promise<void> {
|
||||
await pb.collection('ind_transaction').update(transactionId, updates);
|
||||
}
|
||||
|
||||
export async function deleteTransaction(jobId: string, transactionId: string): Promise<void> {
|
||||
// Delete the transaction
|
||||
await pb.collection('ind_transaction').delete(transactionId);
|
||||
|
||||
// Update the job to remove the transaction reference
|
||||
const job = await getJob(jobId);
|
||||
if (!job) return;
|
||||
|
||||
// Remove from both expenditures and income arrays
|
||||
const expenditures = (job.expenditures || []).filter(id => id !== transactionId);
|
||||
const income = (job.income || []).filter(id => id !== transactionId);
|
||||
|
||||
await updateJob(jobId, {
|
||||
expenditures,
|
||||
income
|
||||
});
|
||||
}
|
||||
|
||||
export async function addBillItem(
|
||||
jobId: string,
|
||||
billItem: Omit<IndBillitemRecord, 'id' | 'created' | 'updated'>
|
||||
): Promise<void> {
|
||||
// Create the bill item
|
||||
const createdItem = await pb.collection('ind_billItem').create(billItem) as IndBillitemResponse;
|
||||
|
||||
// Update the job to include the new bill item
|
||||
const job = await getJob(jobId);
|
||||
if (!job) throw new Error('Job not found');
|
||||
|
||||
const currentBillItems = job.billOfMaterials || [];
|
||||
await updateJob(jobId, {
|
||||
billOfMaterials: [...currentBillItems, createdItem.id]
|
||||
});
|
||||
async function toHollowJob(job: IndJob): Promise<IndJobRecord> {
|
||||
return {
|
||||
...job,
|
||||
expenditures: job.expenditures.map(tx => tx.id),
|
||||
income: job.income.map(tx => tx.id),
|
||||
billOfMaterials: job.billOfMaterials.map(item => item.id),
|
||||
consumedMaterials: job.consumedMaterials.map(item => item.id)
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user