feat: Scheduled Maintenance feature complete
This commit is contained in:
@@ -41,6 +41,11 @@ export class MaintenanceRepository {
|
||||
nextDueMileage: row.next_due_mileage,
|
||||
isActive: row.is_active,
|
||||
emailNotifications: row.email_notifications,
|
||||
scheduleType: row.schedule_type,
|
||||
fixedDueDate: row.fixed_due_date,
|
||||
reminderDays1: row.reminder_days_1,
|
||||
reminderDays2: row.reminder_days_2,
|
||||
reminderDays3: row.reminder_days_3,
|
||||
createdAt: row.created_at,
|
||||
updatedAt: row.updated_at
|
||||
};
|
||||
@@ -192,12 +197,18 @@ export class MaintenanceRepository {
|
||||
nextDueMileage?: number | null;
|
||||
isActive: boolean;
|
||||
emailNotifications?: boolean;
|
||||
scheduleType?: string;
|
||||
fixedDueDate?: string | null;
|
||||
reminderDays1?: number | null;
|
||||
reminderDays2?: number | null;
|
||||
reminderDays3?: number | null;
|
||||
}): Promise<MaintenanceSchedule> {
|
||||
const res = await this.db.query(
|
||||
`INSERT INTO maintenance_schedules (
|
||||
id, user_id, vehicle_id, category, subtypes, interval_months, interval_miles,
|
||||
last_service_date, last_service_mileage, next_due_date, next_due_mileage, is_active, email_notifications
|
||||
) VALUES ($1, $2, $3, $4, $5::text[], $6, $7, $8, $9, $10, $11, $12, $13)
|
||||
last_service_date, last_service_mileage, next_due_date, next_due_mileage, is_active, email_notifications,
|
||||
schedule_type, fixed_due_date, reminder_days_1, reminder_days_2, reminder_days_3
|
||||
) VALUES ($1, $2, $3, $4, $5::text[], $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)
|
||||
RETURNING *`,
|
||||
[
|
||||
schedule.id,
|
||||
@@ -213,6 +224,11 @@ export class MaintenanceRepository {
|
||||
schedule.nextDueMileage ?? null,
|
||||
schedule.isActive,
|
||||
schedule.emailNotifications ?? false,
|
||||
schedule.scheduleType ?? 'interval',
|
||||
schedule.fixedDueDate ?? null,
|
||||
schedule.reminderDays1 ?? null,
|
||||
schedule.reminderDays2 ?? null,
|
||||
schedule.reminderDays3 ?? null,
|
||||
]
|
||||
);
|
||||
return this.mapMaintenanceSchedule(res.rows[0]);
|
||||
@@ -245,7 +261,7 @@ export class MaintenanceRepository {
|
||||
async updateSchedule(
|
||||
id: string,
|
||||
userId: string,
|
||||
patch: Partial<Pick<MaintenanceSchedule, 'category' | 'subtypes' | 'intervalMonths' | 'intervalMiles' | 'lastServiceDate' | 'lastServiceMileage' | 'nextDueDate' | 'nextDueMileage' | 'isActive' | 'emailNotifications'>>
|
||||
patch: Partial<Pick<MaintenanceSchedule, 'category' | 'subtypes' | 'intervalMonths' | 'intervalMiles' | 'lastServiceDate' | 'lastServiceMileage' | 'nextDueDate' | 'nextDueMileage' | 'isActive' | 'emailNotifications' | 'scheduleType' | 'fixedDueDate' | 'reminderDays1' | 'reminderDays2' | 'reminderDays3'>>
|
||||
): Promise<MaintenanceSchedule | null> {
|
||||
const fields: string[] = [];
|
||||
const params: any[] = [];
|
||||
@@ -291,6 +307,26 @@ export class MaintenanceRepository {
|
||||
fields.push(`email_notifications = $${i++}`);
|
||||
params.push(patch.emailNotifications);
|
||||
}
|
||||
if (patch.scheduleType !== undefined) {
|
||||
fields.push(`schedule_type = $${i++}`);
|
||||
params.push(patch.scheduleType);
|
||||
}
|
||||
if (patch.fixedDueDate !== undefined) {
|
||||
fields.push(`fixed_due_date = $${i++}`);
|
||||
params.push(patch.fixedDueDate);
|
||||
}
|
||||
if (patch.reminderDays1 !== undefined) {
|
||||
fields.push(`reminder_days_1 = $${i++}`);
|
||||
params.push(patch.reminderDays1);
|
||||
}
|
||||
if (patch.reminderDays2 !== undefined) {
|
||||
fields.push(`reminder_days_2 = $${i++}`);
|
||||
params.push(patch.reminderDays2);
|
||||
}
|
||||
if (patch.reminderDays3 !== undefined) {
|
||||
fields.push(`reminder_days_3 = $${i++}`);
|
||||
params.push(patch.reminderDays3);
|
||||
}
|
||||
|
||||
if (!fields.length) return this.findScheduleById(id, userId);
|
||||
|
||||
@@ -306,4 +342,46 @@ export class MaintenanceRepository {
|
||||
[id, userId]
|
||||
);
|
||||
}
|
||||
|
||||
async findMatchingSchedules(
|
||||
userId: string,
|
||||
vehicleId: string,
|
||||
category: MaintenanceCategory,
|
||||
subtypes: string[]
|
||||
): Promise<MaintenanceSchedule[]> {
|
||||
const result = await this.db.query(
|
||||
`SELECT * FROM maintenance_schedules
|
||||
WHERE user_id = $1
|
||||
AND vehicle_id = $2
|
||||
AND category = $3
|
||||
AND is_active = true
|
||||
AND schedule_type = 'time_since_last'
|
||||
AND subtypes && $4::text[]
|
||||
ORDER BY created_at DESC`,
|
||||
[userId, vehicleId, category, subtypes]
|
||||
);
|
||||
return result.rows.map(row => this.mapMaintenanceSchedule(row));
|
||||
}
|
||||
|
||||
async updateScheduleLastService(
|
||||
id: string,
|
||||
userId: string,
|
||||
lastServiceDate: string,
|
||||
lastServiceMileage?: number | null,
|
||||
nextDueDate?: string | null,
|
||||
nextDueMileage?: number | null
|
||||
): Promise<MaintenanceSchedule | null> {
|
||||
const result = await this.db.query(
|
||||
`UPDATE maintenance_schedules SET
|
||||
last_service_date = $1,
|
||||
last_service_mileage = $2,
|
||||
next_due_date = $3,
|
||||
next_due_mileage = $4,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = $5 AND user_id = $6
|
||||
RETURNING *`,
|
||||
[lastServiceDate, lastServiceMileage, nextDueDate, nextDueMileage, id, userId]
|
||||
);
|
||||
return result.rows[0] ? this.mapMaintenanceSchedule(result.rows[0]) : null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user