init
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import type { RowDataPacket } from "mysql2/promise";
|
||||
import { getPool } from "./db";
|
||||
import { normalizePhone } from "./phone";
|
||||
import { sqlDateToIso } from "./time";
|
||||
import { NO_BIKE, pickWorkshopJob, stageLabel, type BikeStatus, type StatusResult } from "./workshop";
|
||||
|
||||
export async function lookupBikes(rawPhone: string): Promise<StatusResult> {
|
||||
const phone = normalizePhone(rawPhone);
|
||||
if (!phone) return { message: NO_BIKE, error: null, bikes: [] };
|
||||
|
||||
const pool = getPool();
|
||||
const [customers] = await pool.query<RowDataPacket[]>(
|
||||
`SELECT id FROM customers WHERE phone = ? AND deleted_at IS NULL`,
|
||||
[phone],
|
||||
);
|
||||
if (customers.length === 0) return { message: NO_BIKE, error: null, bikes: [] };
|
||||
|
||||
const customerIds = customers.map((row) => String(row.id));
|
||||
const [vehicles] = await pool.query<RowDataPacket[]>(
|
||||
`SELECT id, registration, make, model_name FROM vehicles
|
||||
WHERE customer_id IN (${customerIds.map(() => "?").join(", ")}) AND deleted_at IS NULL
|
||||
ORDER BY registration ASC, id ASC`,
|
||||
customerIds,
|
||||
);
|
||||
if (vehicles.length === 0) return { message: NO_BIKE, error: null, bikes: [] };
|
||||
|
||||
const bikes: BikeStatus[] = [];
|
||||
for (const vehicle of vehicles) {
|
||||
const [jobs] = await pool.query<RowDataPacket[]>(
|
||||
`SELECT id, stage, created_at FROM job_cards WHERE vehicle_id = ? AND deleted_at IS NULL`,
|
||||
[vehicle.id],
|
||||
);
|
||||
const picked = pickWorkshopJob(
|
||||
jobs.map((job) => ({
|
||||
id: String(job.id),
|
||||
stage: String(job.stage),
|
||||
createdAt: sqlDateToIso(job.created_at) ?? "",
|
||||
})),
|
||||
);
|
||||
const registration = String(vehicle.registration ?? "");
|
||||
const make = String(vehicle.make ?? "");
|
||||
const model = String(vehicle.model_name ?? "");
|
||||
if (!picked) {
|
||||
bikes.push({
|
||||
registration,
|
||||
make,
|
||||
model,
|
||||
inWorkshop: false,
|
||||
stageLabel: null,
|
||||
stageAt: null,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
const [events] = await pool.query<RowDataPacket[]>(
|
||||
"SELECT `at` FROM job_card_events WHERE job_card_id = ? AND deleted_at IS NULL ORDER BY `at` DESC, id DESC LIMIT 1",
|
||||
[picked.id],
|
||||
);
|
||||
bikes.push({
|
||||
registration,
|
||||
make,
|
||||
model,
|
||||
inWorkshop: true,
|
||||
stageLabel: stageLabel(picked.stage),
|
||||
stageAt: events[0] ? sqlDateToIso(events[0].at) : null,
|
||||
});
|
||||
}
|
||||
|
||||
return { message: null, error: null, bikes };
|
||||
}
|
||||
Reference in New Issue
Block a user