101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
|
|
import { IScheduleOverride } from '../../types/ScheduleTypes';
|
||
|
|
import { IndexedDBContext } from '../IndexedDBContext';
|
||
|
|
import { ScheduleOverrideStore } from './ScheduleOverrideStore';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* ScheduleOverrideService - CRUD for schedule overrides
|
||
|
|
*
|
||
|
|
* Provides access to date-specific schedule overrides for resources.
|
||
|
|
*/
|
||
|
|
export class ScheduleOverrideService {
|
||
|
|
private context: IndexedDBContext;
|
||
|
|
|
||
|
|
constructor(context: IndexedDBContext) {
|
||
|
|
this.context = context;
|
||
|
|
}
|
||
|
|
|
||
|
|
private get db(): IDBDatabase {
|
||
|
|
return this.context.getDatabase();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get override for a specific resource and date
|
||
|
|
*/
|
||
|
|
async getOverride(resourceId: string, date: string): Promise<IScheduleOverride | null> {
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], 'readonly');
|
||
|
|
const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME);
|
||
|
|
const index = store.index('resourceId_date');
|
||
|
|
const request = index.get([resourceId, date]);
|
||
|
|
|
||
|
|
request.onsuccess = () => {
|
||
|
|
resolve(request.result || null);
|
||
|
|
};
|
||
|
|
|
||
|
|
request.onerror = () => {
|
||
|
|
reject(new Error(`Failed to get override for ${resourceId} on ${date}: ${request.error}`));
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get all overrides for a resource
|
||
|
|
*/
|
||
|
|
async getByResource(resourceId: string): Promise<IScheduleOverride[]> {
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], 'readonly');
|
||
|
|
const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME);
|
||
|
|
const index = store.index('resourceId');
|
||
|
|
const request = index.getAll(resourceId);
|
||
|
|
|
||
|
|
request.onsuccess = () => {
|
||
|
|
resolve(request.result || []);
|
||
|
|
};
|
||
|
|
|
||
|
|
request.onerror = () => {
|
||
|
|
reject(new Error(`Failed to get overrides for ${resourceId}: ${request.error}`));
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get overrides for a date range
|
||
|
|
*/
|
||
|
|
async getByDateRange(resourceId: string, startDate: string, endDate: string): Promise<IScheduleOverride[]> {
|
||
|
|
const all = await this.getByResource(resourceId);
|
||
|
|
return all.filter(o => o.date >= startDate && o.date <= endDate);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Save an override
|
||
|
|
*/
|
||
|
|
async save(override: IScheduleOverride): Promise<void> {
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], 'readwrite');
|
||
|
|
const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME);
|
||
|
|
const request = store.put(override);
|
||
|
|
|
||
|
|
request.onsuccess = () => resolve();
|
||
|
|
request.onerror = () => {
|
||
|
|
reject(new Error(`Failed to save override ${override.id}: ${request.error}`));
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Delete an override
|
||
|
|
*/
|
||
|
|
async delete(id: string): Promise<void> {
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], 'readwrite');
|
||
|
|
const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME);
|
||
|
|
const request = store.delete(id);
|
||
|
|
|
||
|
|
request.onsuccess = () => resolve();
|
||
|
|
request.onerror = () => {
|
||
|
|
reject(new Error(`Failed to delete override ${id}: ${request.error}`));
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|