mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 16:28:12 +00:00
chore: fix script and add seed company
This commit is contained in:
@@ -12,8 +12,38 @@ import { TrainSet } from "../../modules/train-sets/entities/train-set.entity";
|
||||
import { TrainSetLocomotive } from "../../modules/train-sets/entities/train-set-locomotive.entity";
|
||||
import { TrainSetWagon } from "../../modules/train-sets/entities/train-set-wagon.entity";
|
||||
import { TrainSchedule } from "../../modules/train-schedules/entities/train-schedule.entity";
|
||||
import { TrainScheduleBooking } from "../../modules/train-schedules/entities/train-schedule-booking.entity";
|
||||
import { Booking } from "../../modules/bookings/entities/booking.entity";
|
||||
|
||||
async function nextSequence(ds: DataSource, pattern: string): Promise<number> {
|
||||
const like = pattern.replace(/\*/g, "%");
|
||||
const raw = await ds.query(
|
||||
`SELECT "train_number" FROM "freight"."train_schedules" WHERE "train_number" LIKE $1 AND "deleted_at" IS NULL ORDER BY "train_number" DESC LIMIT 1`,
|
||||
[like.replace(/%/g, "") + "%"],
|
||||
);
|
||||
if (raw.length === 0) return 1;
|
||||
const ref: string = raw[0].train_number;
|
||||
const num = parseInt(ref.replace(pattern.split("*")[0], ""), 10);
|
||||
return isNaN(num) ? 1 : num + 1;
|
||||
}
|
||||
|
||||
async function nextRouteSeq(ds: DataSource, prefix: string): Promise<number> {
|
||||
const raw = await ds.query(
|
||||
`SELECT "name" FROM "freight"."routes" WHERE "name" LIKE $1 AND "deleted_at" IS NULL ORDER BY "name" DESC LIMIT 1`,
|
||||
[prefix + "%"],
|
||||
);
|
||||
if (raw.length === 0) return 1;
|
||||
const num = parseInt(raw[0].name.replace(prefix, ""), 10);
|
||||
return isNaN(num) ? 1 : num + 1;
|
||||
}
|
||||
|
||||
async function nextWagonSeq(ds: DataSource, prefix: string): Promise<number> {
|
||||
const raw = await ds.query(
|
||||
`SELECT "wagon_number" FROM "freight"."wagons" WHERE "wagon_number" LIKE $1 AND "deleted_at" IS NULL ORDER BY "wagon_number" DESC LIMIT 1`,
|
||||
[prefix + "%"],
|
||||
);
|
||||
if (raw.length === 0) return 1;
|
||||
const num = parseInt(raw[0].wagon_number.replace(prefix, ""), 10);
|
||||
return isNaN(num) ? 1 : num + 1;
|
||||
}
|
||||
|
||||
export function registerSeedTestSchedules(
|
||||
vorpal: Vorpal,
|
||||
@@ -43,8 +73,6 @@ export function registerSeedTestSchedules(
|
||||
return;
|
||||
}
|
||||
|
||||
this.log(`Seeding ${count} schedules (direction=${directionList.join(",")}, status=${statusList.join(",")}, days_ahead=${daysAhead})...`);
|
||||
|
||||
const yards = await ds.getRepository(Yard).find({ where: { isActive: true } });
|
||||
const yardByCode = new Map(yards.map((y) => [y.code.toUpperCase(), y]));
|
||||
const djibouti = yardByCode.get("DJIBOUTI") ?? yards.find((y) => y.country === "Djibouti");
|
||||
@@ -61,50 +89,90 @@ export function registerSeedTestSchedules(
|
||||
return;
|
||||
}
|
||||
|
||||
const route = await ensureTestRoute(ds, yards, djibouti, addis, (msg) => this.log(msg));
|
||||
const wagonType = wagonTypes[0];
|
||||
const wagonCapacity = Number(wagonType.capacityTons) || 70;
|
||||
const wagonLength = Number(wagonType.lengthMeters) || 14;
|
||||
const tareWeight = Number(wagonType.tareWeightTons) || 14;
|
||||
|
||||
const locomotiveRepo = ds.getRepository(Locomotive);
|
||||
const scheduleRepo = ds.getRepository(TrainSchedule);
|
||||
const trainSetRepo = ds.getRepository(TrainSet);
|
||||
let seeded = 0;
|
||||
const wagonRepo = ds.getRepository(Wagon);
|
||||
const routeRepo = ds.getRepository(Route);
|
||||
const milestoneRepo = ds.getRepository(RouteMilestone);
|
||||
|
||||
let nextTrainNum = await nextSequence(ds, "TST-SCH-*");
|
||||
const routePrefix = "TST-RTE-";
|
||||
let nextRouteNum = await nextRouteSeq(ds, routePrefix);
|
||||
|
||||
const now = new Date();
|
||||
const travelHours = 11;
|
||||
const intermediateYards = yards.filter(
|
||||
(y) => y.id !== djibouti.id && y.id !== addis.id,
|
||||
);
|
||||
|
||||
let loco = await locomotiveRepo.findOne({ where: { code: "TST-LOCO-01" } });
|
||||
if (!loco) {
|
||||
loco = await locomotiveRepo.save(
|
||||
locomotiveRepo.create({
|
||||
code: "TST-LOCO-01",
|
||||
name: "Test Locomotive",
|
||||
locomotiveType: "DIESEL",
|
||||
maxPullWeightTons: 4200,
|
||||
maxTrainLengthMeters: 760,
|
||||
status: "AVAILABLE",
|
||||
currentYardId: djibouti.id,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const seq = nextTrainNum + i;
|
||||
const trainNumber = `TST-SCH-${String(seq).padStart(5, "0")}`;
|
||||
const dir = directionList[i % directionList.length];
|
||||
const status = statusList[i % statusList.length];
|
||||
const trainNumber = `TST-SCH-${String(i + 1).padStart(3, "0")}`;
|
||||
|
||||
const existing = await scheduleRepo.findOne({ where: { trainNumber } });
|
||||
if (existing) {
|
||||
this.log(` Schedule ${trainNumber} already exists — skipping`);
|
||||
seeded++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const isDispatched = status === "DISPATCHED";
|
||||
const originYard = dir === "IMPORT" ? djibouti : addis;
|
||||
const destYard = dir === "IMPORT" ? addis : djibouti;
|
||||
const isDispatched = status === "DISPATCHED";
|
||||
const routeName = `${routePrefix}${String(nextRouteNum + i).padStart(3, "0")}`;
|
||||
|
||||
const now = new Date();
|
||||
const departure = new Date(now);
|
||||
departure.setDate(departure.getDate() + daysAhead);
|
||||
departure.setDate(departure.getDate() + daysAhead + i);
|
||||
departure.setHours(7, 0, 0, 0);
|
||||
|
||||
const travelHours = dir === "IMPORT" ? 12 : 10;
|
||||
const arrival = new Date(departure.getTime() + travelHours * 60 * 60 * 1000);
|
||||
|
||||
const locomotive = await ensureTestLocomotive(ds, originYard.id, (msg) => this.log(msg));
|
||||
const wagonCount = 4;
|
||||
const wagonType = wagonTypes[0];
|
||||
const wagonCapacity = Number(wagonType.capacityTons) || 70;
|
||||
const wagonLength = Number(wagonType.lengthMeters) || 14;
|
||||
const tareWeight = Number(wagonType.tareWeightTons) || 14;
|
||||
const totalWagonWeight = wagonCount * (tareWeight + 20);
|
||||
const route = await routeRepo.save(
|
||||
routeRepo.create({
|
||||
name: routeName,
|
||||
originYardId: originYard.id,
|
||||
destinationYardId: destYard.id,
|
||||
isActive: true,
|
||||
}),
|
||||
);
|
||||
|
||||
await milestoneRepo.save(
|
||||
milestoneRepo.create({ routeId: route.id, yardId: originYard.id, sequenceNo: 1 }),
|
||||
);
|
||||
for (const [mi, y] of intermediateYards.entries()) {
|
||||
await milestoneRepo.save(
|
||||
milestoneRepo.create({ routeId: route.id, yardId: y.id, sequenceNo: (mi + 1) * 2 }),
|
||||
);
|
||||
}
|
||||
await milestoneRepo.save(
|
||||
milestoneRepo.create({
|
||||
routeId: route.id,
|
||||
yardId: destYard.id,
|
||||
sequenceNo: (intermediateYards.length + 1) * 2,
|
||||
}),
|
||||
);
|
||||
|
||||
const totalWagonWeight = 4 * (tareWeight + 20);
|
||||
const trainSet = await trainSetRepo.save(
|
||||
trainSetRepo.create({
|
||||
locomotiveId: locomotive.id,
|
||||
locomotiveId: loco.id,
|
||||
totalWeightTons: totalWagonWeight,
|
||||
totalLengthMeters: wagonLength * wagonCount,
|
||||
wagonCount,
|
||||
totalLengthMeters: wagonLength * 4,
|
||||
wagonCount: 4,
|
||||
status: isDispatched ? "DISPATCHED" : status === "DRAFT" ? "DRAFT" : "ASSIGNED",
|
||||
}),
|
||||
);
|
||||
@@ -112,7 +180,7 @@ export function registerSeedTestSchedules(
|
||||
await ds.getRepository(TrainSetLocomotive).save(
|
||||
ds.getRepository(TrainSetLocomotive).create({
|
||||
trainSetId: trainSet.id,
|
||||
locomotiveId: locomotive.id,
|
||||
locomotiveId: loco.id,
|
||||
sequenceNo: 0,
|
||||
}),
|
||||
);
|
||||
@@ -134,26 +202,31 @@ export function registerSeedTestSchedules(
|
||||
}),
|
||||
);
|
||||
|
||||
for (let w = 0; w < wagonCount; w++) {
|
||||
const seq = w + 1;
|
||||
const wagonNumber = `${trainNumber}-W${String(seq).padStart(2, "0")}`;
|
||||
const wagonPrefix = `${trainNumber}-W`;
|
||||
let nextWagon = await nextWagonSeq(ds, wagonPrefix);
|
||||
for (let w = 0; w < 4; w++) {
|
||||
const ws = nextWagon + w;
|
||||
const wagonNumber = `${wagonPrefix}${String(ws).padStart(2, "0")}`;
|
||||
|
||||
const physicalWagon = await ensureTestWagon(ds, {
|
||||
const wagon = wagonRepo.create({
|
||||
wagonNumber,
|
||||
wagonTypeId: wagonType.id,
|
||||
yardId: originYard.id,
|
||||
trainScheduleId: schedule.id,
|
||||
currentYardId: originYard.id,
|
||||
currentTrainScheduleId: schedule.id,
|
||||
tareWeight,
|
||||
capacityTons: wagonCapacity,
|
||||
dispatched: isDispatched,
|
||||
maxPayloadWeight: wagonCapacity,
|
||||
status: isDispatched ? WagonStatus.Assigned : WagonStatus.Available,
|
||||
notes: "Test seed wagon",
|
||||
});
|
||||
const saved = await wagonRepo.save(wagon as any);
|
||||
const physicalWagon = Array.isArray(saved) ? saved[0] : saved;
|
||||
|
||||
await ds.getRepository(TrainSetWagon).save(
|
||||
ds.getRepository(TrainSetWagon).create({
|
||||
trainSetId: trainSet.id,
|
||||
wagonTypeId: wagonType.id,
|
||||
physicalWagonId: physicalWagon.id,
|
||||
sequenceNo: seq,
|
||||
sequenceNo: w + 1,
|
||||
capacityTons: wagonCapacity,
|
||||
lengthMeters: wagonLength,
|
||||
assignedWeightTons: 20,
|
||||
@@ -162,137 +235,9 @@ export function registerSeedTestSchedules(
|
||||
);
|
||||
}
|
||||
|
||||
const scheduleBookings = await ds.getRepository(TrainScheduleBooking).find({
|
||||
where: { trainScheduleId: schedule.id },
|
||||
});
|
||||
if (scheduleBookings.length === 0) {
|
||||
const booking = await ds.getRepository(Booking).findOne({ where: {}, order: { createdAt: "DESC" } });
|
||||
if (booking) {
|
||||
await ds.getRepository(TrainScheduleBooking).save(
|
||||
ds.getRepository(TrainScheduleBooking).create({
|
||||
trainScheduleId: schedule.id,
|
||||
bookingId: booking.id,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
seeded++;
|
||||
this.log(` Created ${status} ${dir} schedule: ${trainNumber} (${originYard.label} → ${destYard.label})`);
|
||||
}
|
||||
|
||||
this.log(`Done — ${seeded} train schedules ensured`);
|
||||
this.log(`Done — ${count} new train schedules created`);
|
||||
});
|
||||
}
|
||||
|
||||
async function ensureTestRoute(
|
||||
ds: DataSource,
|
||||
yards: Yard[],
|
||||
originYard: Yard,
|
||||
destYard: Yard,
|
||||
log: (msg: string) => void,
|
||||
): Promise<Route> {
|
||||
const repo = ds.getRepository(Route);
|
||||
const name = `TST-RTE-${originYard.code}_${destYard.code}`;
|
||||
let route = await repo.findOne({ where: { name } });
|
||||
if (route) return route;
|
||||
|
||||
route = await repo.save(
|
||||
repo.create({
|
||||
name,
|
||||
originYardId: originYard.id,
|
||||
destinationYardId: destYard.id,
|
||||
isActive: true,
|
||||
}),
|
||||
);
|
||||
log(` Created route: ${name}`);
|
||||
|
||||
const milestoneRepo = ds.getRepository(RouteMilestone);
|
||||
const intermediateYards = yards.filter(
|
||||
(y) => y.id !== originYard.id && y.id !== destYard.id,
|
||||
);
|
||||
|
||||
await milestoneRepo.save(
|
||||
milestoneRepo.create({
|
||||
routeId: route.id,
|
||||
yardId: originYard.id,
|
||||
sequenceNo: 0,
|
||||
}),
|
||||
);
|
||||
|
||||
for (const [idx, y] of intermediateYards.entries()) {
|
||||
await milestoneRepo.save(
|
||||
milestoneRepo.create({
|
||||
routeId: route.id,
|
||||
yardId: y.id,
|
||||
sequenceNo: (idx + 1) * 2,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
await milestoneRepo.save(
|
||||
milestoneRepo.create({
|
||||
routeId: route.id,
|
||||
yardId: destYard.id,
|
||||
sequenceNo: (intermediateYards.length + 1) * 2,
|
||||
}),
|
||||
);
|
||||
|
||||
log(` Added ${intermediateYards.length + 2} milestones`);
|
||||
return route;
|
||||
}
|
||||
|
||||
async function ensureTestLocomotive(
|
||||
ds: DataSource,
|
||||
yardId: string,
|
||||
log: (msg: string) => void,
|
||||
): Promise<Locomotive> {
|
||||
const repo = ds.getRepository(Locomotive);
|
||||
const code = "TST-LOCO-01";
|
||||
let loco = await repo.findOne({ where: { code } });
|
||||
if (loco) return loco;
|
||||
|
||||
loco = await repo.save(
|
||||
repo.create({
|
||||
code,
|
||||
name: "Test Locomotive",
|
||||
locomotiveType: "DIESEL",
|
||||
maxPullWeightTons: 4200,
|
||||
maxTrainLengthMeters: 760,
|
||||
status: "AVAILABLE",
|
||||
currentYardId: yardId,
|
||||
}),
|
||||
);
|
||||
log(` Created locomotive: ${code}`);
|
||||
return loco;
|
||||
}
|
||||
|
||||
async function ensureTestWagon(
|
||||
ds: DataSource,
|
||||
input: {
|
||||
wagonNumber: string;
|
||||
wagonTypeId: string;
|
||||
yardId: string;
|
||||
trainScheduleId: string;
|
||||
tareWeight: number;
|
||||
capacityTons: number;
|
||||
dispatched: boolean;
|
||||
},
|
||||
): Promise<Wagon> {
|
||||
const repo = ds.getRepository(Wagon);
|
||||
const existing = await repo.findOne({ where: { wagonNumber: input.wagonNumber } });
|
||||
if (existing) return existing;
|
||||
|
||||
const wagon = repo.create({
|
||||
wagonNumber: input.wagonNumber,
|
||||
wagonTypeId: input.wagonTypeId,
|
||||
currentYardId: input.yardId,
|
||||
currentTrainScheduleId: input.trainScheduleId,
|
||||
tareWeight: input.tareWeight,
|
||||
maxPayloadWeight: input.capacityTons,
|
||||
status: input.dispatched ? WagonStatus.Assigned : WagonStatus.Available,
|
||||
notes: "Test seed wagon",
|
||||
});
|
||||
const saved = await repo.save(wagon as any);
|
||||
return Array.isArray(saved) ? saved[0] : saved;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user