76 lines
2.3 KiB
TypeScript
76 lines
2.3 KiB
TypeScript
|
|
import { IBooking, EntityType, IEventBus, BookingStatus } from '../../types/CalendarTypes';
|
||
|
|
import { BookingStore } from './BookingStore';
|
||
|
|
import { BaseEntityService } from '../../storage/BaseEntityService';
|
||
|
|
import { IndexedDBContext } from '../../storage/IndexedDBContext';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* BookingService - CRUD operations for bookings in IndexedDB
|
||
|
|
*/
|
||
|
|
export class BookingService extends BaseEntityService<IBooking> {
|
||
|
|
readonly storeName = BookingStore.STORE_NAME;
|
||
|
|
readonly entityType: EntityType = 'Booking';
|
||
|
|
|
||
|
|
constructor(context: IndexedDBContext, eventBus: IEventBus) {
|
||
|
|
super(context, eventBus);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected serialize(booking: IBooking): unknown {
|
||
|
|
return {
|
||
|
|
...booking,
|
||
|
|
createdAt: booking.createdAt.toISOString()
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
protected deserialize(data: unknown): IBooking {
|
||
|
|
const raw = data as Record<string, unknown>;
|
||
|
|
return {
|
||
|
|
...raw,
|
||
|
|
createdAt: new Date(raw.createdAt as string)
|
||
|
|
} as IBooking;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get bookings for a customer
|
||
|
|
*/
|
||
|
|
async getByCustomer(customerId: string): Promise<IBooking[]> {
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
const transaction = this.db.transaction([this.storeName], 'readonly');
|
||
|
|
const store = transaction.objectStore(this.storeName);
|
||
|
|
const index = store.index('customerId');
|
||
|
|
const request = index.getAll(customerId);
|
||
|
|
|
||
|
|
request.onsuccess = () => {
|
||
|
|
const data = request.result as unknown[];
|
||
|
|
const bookings = data.map(item => this.deserialize(item));
|
||
|
|
resolve(bookings);
|
||
|
|
};
|
||
|
|
|
||
|
|
request.onerror = () => {
|
||
|
|
reject(new Error(`Failed to get bookings for customer ${customerId}: ${request.error}`));
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get bookings by status
|
||
|
|
*/
|
||
|
|
async getByStatus(status: BookingStatus): Promise<IBooking[]> {
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
const transaction = this.db.transaction([this.storeName], 'readonly');
|
||
|
|
const store = transaction.objectStore(this.storeName);
|
||
|
|
const index = store.index('status');
|
||
|
|
const request = index.getAll(status);
|
||
|
|
|
||
|
|
request.onsuccess = () => {
|
||
|
|
const data = request.result as unknown[];
|
||
|
|
const bookings = data.map(item => this.deserialize(item));
|
||
|
|
resolve(bookings);
|
||
|
|
};
|
||
|
|
|
||
|
|
request.onerror = () => {
|
||
|
|
reject(new Error(`Failed to get bookings with status ${status}: ${request.error}`));
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|