Refactor fetching to use pocketbase expand instead of being retarded
This commit is contained in:
@@ -11,7 +11,7 @@ export class DataService {
|
||||
private jobs: IndJob[] = [];
|
||||
private listeners: Set<() => void> = new Set();
|
||||
|
||||
private constructor() {}
|
||||
private constructor() { }
|
||||
|
||||
static getInstance(): DataService {
|
||||
if (!DataService.instance) {
|
||||
@@ -39,34 +39,14 @@ export class DataService {
|
||||
|
||||
async loadJobs(): Promise<IndJob[]> {
|
||||
console.log('Loading jobs from database');
|
||||
this.jobs = await jobService.getJobsFull();
|
||||
this.jobs = await jobService.getJobs();
|
||||
this.notifyListeners();
|
||||
return this.getJobs();
|
||||
}
|
||||
|
||||
async createJob(jobData: IndJobRecordNoId): Promise<IndJob> {
|
||||
console.log('Creating job:', jobData);
|
||||
const newJobRecord = await jobService.createJob(jobData);
|
||||
const newJob: IndJob = {
|
||||
id: newJobRecord.id,
|
||||
outputItem: newJobRecord.outputItem,
|
||||
outputQuantity: newJobRecord.outputQuantity,
|
||||
status: newJobRecord.status,
|
||||
created: newJobRecord.created,
|
||||
updated: newJobRecord.updated,
|
||||
jobStart: newJobRecord.jobStart,
|
||||
jobEnd: newJobRecord.jobEnd,
|
||||
saleStart: newJobRecord.saleStart,
|
||||
saleEnd: newJobRecord.saleEnd,
|
||||
produced: newJobRecord.produced,
|
||||
projectedCost: newJobRecord.projectedCost,
|
||||
projectedRevenue: newJobRecord.projectedRevenue,
|
||||
expenditures: [],
|
||||
income: [],
|
||||
billOfMaterials: [],
|
||||
consumedMaterials: []
|
||||
};
|
||||
|
||||
const newJob = await jobService.createJob(jobData);
|
||||
this.jobs.push(newJob);
|
||||
this.notifyListeners();
|
||||
return newJob;
|
||||
@@ -75,54 +55,34 @@ export class DataService {
|
||||
async updateJob(id: string, updates: Partial<IndJobRecord>): Promise<IndJob> {
|
||||
console.log('Updating job:', id, updates);
|
||||
const updatedRecord = await jobService.updateJob(id, updates);
|
||||
|
||||
|
||||
const jobIndex = this.jobs.findIndex(job => job.id === id);
|
||||
if (jobIndex !== -1) {
|
||||
// Only update the scalar fields, preserve the relation arrays
|
||||
const existingJob = this.jobs[jobIndex];
|
||||
this.jobs[jobIndex] = {
|
||||
id: updatedRecord.id,
|
||||
outputItem: updatedRecord.outputItem,
|
||||
outputQuantity: updatedRecord.outputQuantity,
|
||||
status: updatedRecord.status,
|
||||
created: updatedRecord.created,
|
||||
updated: updatedRecord.updated,
|
||||
jobStart: updatedRecord.jobStart,
|
||||
jobEnd: updatedRecord.jobEnd,
|
||||
saleStart: updatedRecord.saleStart,
|
||||
saleEnd: updatedRecord.saleEnd,
|
||||
produced: updatedRecord.produced,
|
||||
projectedCost: updatedRecord.projectedCost,
|
||||
projectedRevenue: updatedRecord.projectedRevenue,
|
||||
expenditures: existingJob.expenditures,
|
||||
income: existingJob.income,
|
||||
billOfMaterials: existingJob.billOfMaterials,
|
||||
consumedMaterials: existingJob.consumedMaterials
|
||||
};
|
||||
this.jobs[jobIndex] = updatedRecord;
|
||||
this.notifyListeners();
|
||||
return this.jobs[jobIndex];
|
||||
}
|
||||
|
||||
|
||||
throw new Error(`Job with id ${id} not found in local state`);
|
||||
}
|
||||
|
||||
async deleteJob(id: string): Promise<void> {
|
||||
console.log('Deleting job:', id);
|
||||
await jobService.deleteJob(id);
|
||||
|
||||
|
||||
this.jobs = this.jobs.filter(job => job.id !== id);
|
||||
this.notifyListeners();
|
||||
}
|
||||
|
||||
async createTransaction(jobId: string, transaction: IndTransactionRecordNoId, type: 'expenditure' | 'income'): Promise<IndJob> {
|
||||
console.log('Creating transaction for job:', jobId, transaction, type);
|
||||
|
||||
|
||||
const job = this.getJob(jobId);
|
||||
if (!job) throw new Error(`Job with id ${jobId} not found`);
|
||||
|
||||
// Create the transaction in the database
|
||||
transaction.job = jobId;
|
||||
const createdTransaction = await transactionService.createTransaction(job, transaction, type);
|
||||
const createdTransaction = await transactionService.createTransaction(job, transaction);
|
||||
|
||||
// Update the job's transaction references in the database
|
||||
const field = type === 'expenditure' ? 'expenditures' : 'income';
|
||||
@@ -148,16 +108,16 @@ export class DataService {
|
||||
|
||||
async createMultipleTransactions(jobId: string, transactions: IndTransactionRecordNoId[], type: 'expenditure' | 'income'): Promise<IndJob> {
|
||||
console.log('Creating multiple transactions for job:', jobId, transactions.length, type);
|
||||
|
||||
|
||||
const job = this.getJob(jobId);
|
||||
if (!job) throw new Error(`Job with id ${jobId} not found`);
|
||||
|
||||
const createdTransactions: IndTransactionRecord[] = [];
|
||||
|
||||
|
||||
// Create all transactions
|
||||
for (const transaction of transactions) {
|
||||
transaction.job = jobId;
|
||||
const createdTransaction = await transactionService.createTransaction(job, transaction, type);
|
||||
const createdTransaction = await transactionService.createTransaction(job, transaction);
|
||||
createdTransactions.push(createdTransaction);
|
||||
}
|
||||
|
||||
@@ -186,7 +146,7 @@ export class DataService {
|
||||
|
||||
async updateTransaction(jobId: string, transactionId: string, updates: Partial<IndTransactionRecord>): Promise<IndJob> {
|
||||
console.log('Updating transaction:', transactionId, updates);
|
||||
|
||||
|
||||
const job = this.getJob(jobId);
|
||||
if (!job) throw new Error(`Job with id ${jobId} not found`);
|
||||
|
||||
@@ -195,10 +155,10 @@ export class DataService {
|
||||
// Update local state
|
||||
const jobIndex = this.jobs.findIndex(j => j.id === jobId);
|
||||
if (jobIndex !== -1) {
|
||||
this.jobs[jobIndex].expenditures = this.jobs[jobIndex].expenditures.map(tx =>
|
||||
this.jobs[jobIndex].expenditures = this.jobs[jobIndex].expenditures.map(tx =>
|
||||
tx.id === transactionId ? updatedTransaction : tx
|
||||
);
|
||||
this.jobs[jobIndex].income = this.jobs[jobIndex].income.map(tx =>
|
||||
this.jobs[jobIndex].income = this.jobs[jobIndex].income.map(tx =>
|
||||
tx.id === transactionId ? updatedTransaction : tx
|
||||
);
|
||||
this.notifyListeners();
|
||||
@@ -210,7 +170,7 @@ export class DataService {
|
||||
|
||||
async deleteTransaction(jobId: string, transactionId: string): Promise<IndJob> {
|
||||
console.log('Deleting transaction:', transactionId);
|
||||
|
||||
|
||||
const job = this.getJob(jobId);
|
||||
if (!job) throw new Error(`Job with id ${jobId} not found`);
|
||||
|
||||
@@ -230,7 +190,7 @@ export class DataService {
|
||||
|
||||
async createBillItem(jobId: string, billItem: IndBillitemRecordNoId, type: 'billOfMaterials' | 'consumedMaterials'): Promise<IndJob> {
|
||||
console.log('Creating bill item for job:', jobId, billItem, type);
|
||||
|
||||
|
||||
const job = this.getJob(jobId);
|
||||
if (!job) throw new Error(`Job with id ${jobId} not found`);
|
||||
|
||||
@@ -255,12 +215,12 @@ export class DataService {
|
||||
|
||||
async createMultipleBillItems(jobId: string, billItems: IndBillitemRecordNoId[], type: 'billOfMaterials' | 'consumedMaterials'): Promise<IndJob> {
|
||||
console.log('Creating multiple bill items for job:', jobId, billItems.length, type);
|
||||
|
||||
|
||||
const job = this.getJob(jobId);
|
||||
if (!job) throw new Error(`Job with id ${jobId} not found`);
|
||||
|
||||
const createdBillItems: IndBillitemRecord[] = [];
|
||||
|
||||
|
||||
// Create all bill items
|
||||
for (const billItem of billItems) {
|
||||
const createdBillItem = await billItemService.addBillItem(jobId, billItem);
|
||||
@@ -288,4 +248,3 @@ export class DataService {
|
||||
|
||||
// Export singleton instance
|
||||
export const dataService = DataService.getInstance();
|
||||
|
||||
|
@@ -1,118 +1,61 @@
|
||||
|
||||
import { IndJob } from '@/lib/types';
|
||||
import type { IndJobRecord, IndTransactionRecord, IndBillitemRecord, IndJobRecordNoId } from '../lib/pbtypes';
|
||||
import type { IndJobRecord, 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: IndJobRecordNoId): Promise<IndJobRecord> {
|
||||
export async function createJob(job: IndJobRecordNoId): Promise<IndJob> {
|
||||
console.log('Creating job:', job);
|
||||
return await pb.collection<IndJobRecord>('ind_job').create(job);
|
||||
const newJob = await pb.collection<IndJobRecord>('ind_job').create(job)
|
||||
return await getJob(newJob.id);
|
||||
}
|
||||
|
||||
export async function getJobs(): Promise<IndJobRecord[]> {
|
||||
const expand = 'billOfMaterials,consumedMaterials,expenditures,income';
|
||||
|
||||
export async function getJobs(): Promise<IndJob[]> {
|
||||
console.log('Getting jobs');
|
||||
const result = await pb.collection<IndJobRecord>('ind_job').getFullList();
|
||||
return result;
|
||||
}
|
||||
export async function getJobsFull(): Promise<IndJob[]> {
|
||||
const jobs = await getJobs();
|
||||
console.log('Jobs:', jobs);
|
||||
return await Promise.all(jobs.map(toFullJob));
|
||||
// const result = await pb.collection<IndJobRecord>('ind_job').getFullList();
|
||||
const result = await pb.collection('ind_job').getFullList(10000, { expand });
|
||||
const jobs: IndJob[] = [];
|
||||
for (const job of result) {
|
||||
jobs.push({
|
||||
...job,
|
||||
billOfMaterials: job.expand["billOfMaterials"] || [],
|
||||
consumedMaterials: job.expand["consumedMaterials"] || [],
|
||||
expenditures: job.expand["expenditures"] || [],
|
||||
income: job.expand["income"] || []
|
||||
});
|
||||
}
|
||||
return jobs;
|
||||
}
|
||||
|
||||
export async function getJob(id: string): Promise<IndJobRecord | null> {
|
||||
export async function getJob(id: string): Promise<IndJob | null> {
|
||||
console.log('Getting job:', id);
|
||||
try {
|
||||
return await pb.collection<IndJobRecord>('ind_job').getOne(id);
|
||||
const job = await pb.collection('ind_job').getOne(id, { expand });
|
||||
return {
|
||||
...job,
|
||||
billOfMaterials: job.expand["billOfMaterials"] || [],
|
||||
consumedMaterials: job.expand["consumedMaterials"] || [],
|
||||
expenditures: job.expand["expenditures"] || [],
|
||||
income: job.expand["income"] || []
|
||||
};
|
||||
} catch (e) {
|
||||
if (e.status === 404) return null;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
export async function getJobFull(id: string): Promise<IndJob | null> {
|
||||
console.log('Getting job full:', id);
|
||||
const job = await getJob(id);
|
||||
if (!job) return null;
|
||||
return await toFullJob(job);
|
||||
}
|
||||
|
||||
export async function updateJob(id: string, updates: Partial<IndJobRecord>): Promise<IndJobRecord> {
|
||||
export async function updateJob(id: string, updates: Partial<IndJobRecord>): Promise<IndJob> {
|
||||
console.log('Updating job:', id, updates);
|
||||
return await pb.collection<IndJobRecord>('ind_job').update(id, updates);
|
||||
await pb.collection<IndJobRecord>('ind_job').update(id, updates)
|
||||
return getJob(id);
|
||||
}
|
||||
|
||||
export async function deleteJob(id: string): Promise<void> {
|
||||
console.log('Deleting job:', id);
|
||||
await pb.collection<IndJobRecord>('ind_job').delete(id);
|
||||
}
|
||||
|
||||
async function toFullJob(job: IndJobRecord): Promise<IndJob> {
|
||||
// console.log('Converting job to full job:', job);
|
||||
const fullJob = {
|
||||
...job,
|
||||
expenditures: [],
|
||||
income: [],
|
||||
billOfMaterials: [],
|
||||
consumedMaterials: []
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
async function toHollowJob(job: IndJob): Promise<IndJobRecord> {
|
||||
console.log('Converting job to hollow job:', job);
|
||||
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)
|
||||
};
|
||||
}
|
@@ -7,7 +7,6 @@ import { updateJob } from './jobService';
|
||||
export async function createTransaction(
|
||||
job: IndJob,
|
||||
transaction: IndTransactionRecordNoId,
|
||||
type: 'expenditure' | 'income'
|
||||
): Promise<IndTransactionRecord> {
|
||||
console.log('Creating transaction:', transaction);
|
||||
// Create the transaction
|
||||
|
Reference in New Issue
Block a user