mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 10:52:53 +00:00
146 lines
5.6 KiB
TypeScript
146 lines
5.6 KiB
TypeScript
import { Injectable, Logger } from '@nestjs/common';
|
|
import { DataSource } from 'typeorm';
|
|
|
|
import { Booking } from '../modules/bookings/entities/booking.entity';
|
|
import { ServiceType } from '../modules/rule-engine/entities/service-type.entity';
|
|
import { Yard } from '../modules/rule-engine/entities/yard.entity';
|
|
import { Warehouse } from '../modules/warehouses/entities/warehouse.entity';
|
|
import { WarehouseInventory } from '../modules/warehouses/entities/warehouse-inventory.entity';
|
|
import { WarehouseYard } from '../modules/warehouses/entities/warehouse-yard.entity';
|
|
import { WarehouseZone } from '../modules/warehouses/entities/warehouse-zone.entity';
|
|
|
|
const SEED_REFS = ['SEED-B5-EXP-001', 'SEED-B5-EXP-002', 'SEED-B5-EXP-003'];
|
|
|
|
const SEEDS = [
|
|
{ ref: 'SEED-B5-EXP-001', weight: 5000, notes: 'Electronics export cargo' },
|
|
{ ref: 'SEED-B5-EXP-002', weight: 8500, notes: 'Textile export cargo' },
|
|
{ ref: 'SEED-B5-EXP-003', weight: 3200, notes: 'Coffee export cargo' },
|
|
];
|
|
|
|
/**
|
|
* Seeds 3 EXPORT+PAID bookings with READY_FOR_LOADING + inspection PASSED inventory
|
|
* so the Batch 5 "Ready To Load" tab has visible rows to test against.
|
|
*
|
|
* Origin: any Ethiopian yard (route-based direction = EXPORT when dest = Djibouti)
|
|
* Destination: any Djiboutian yard
|
|
* Uses the INDODE_OPEN warehouse created by IndodeFacilitySeeder.
|
|
*/
|
|
@Injectable()
|
|
export class Batch5TestDataSeeder {
|
|
private readonly logger = new Logger(Batch5TestDataSeeder.name);
|
|
|
|
constructor(private readonly dataSource: DataSource) {}
|
|
|
|
async run(): Promise<void> {
|
|
const bookingRepo = this.dataSource.getRepository(Booking);
|
|
|
|
const existing = await bookingRepo.findOne({ where: { reference: SEED_REFS[0] } });
|
|
if (existing) {
|
|
this.logger.log('Batch 5 test data already seeded, skipping');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const yardRepo = this.dataSource.getRepository(Yard);
|
|
const serviceTypeRepo = this.dataSource.getRepository(ServiceType);
|
|
const warehouseRepo = this.dataSource.getRepository(Warehouse);
|
|
const warehouseYardRepo = this.dataSource.getRepository(WarehouseYard);
|
|
const warehouseZoneRepo = this.dataSource.getRepository(WarehouseZone);
|
|
const inventoryRepo = this.dataSource.getRepository(WarehouseInventory);
|
|
|
|
// Find Ethiopian origin yard and Djiboutian destination yard.
|
|
const originYard =
|
|
(await yardRepo.findOne({ where: { code: 'ADDIS_ABABA' } })) ??
|
|
(await yardRepo.findOne({ where: { country: 'Ethiopia' } }));
|
|
const destYard =
|
|
(await yardRepo.findOne({ where: { code: 'DJIBOUTI' } })) ??
|
|
(await yardRepo.findOne({ where: { country: 'Djibouti' } }));
|
|
|
|
if (!originYard || !destYard) {
|
|
this.logger.warn(
|
|
`Required yards not found (origin=${originYard?.code ?? 'none'}, dest=${destYard?.code ?? 'none'}); skipping Batch 5 seed`,
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Find any active service type (bookings require one).
|
|
const serviceType =
|
|
(await serviceTypeRepo.findOne({ where: { code: 'RAIL_CONTAINER' } })) ??
|
|
(await serviceTypeRepo.findOne({ where: { isActive: true } }));
|
|
if (!serviceType) {
|
|
this.logger.warn('No service type found; skipping Batch 5 seed');
|
|
return;
|
|
}
|
|
|
|
// Find INDODE warehouse.
|
|
const warehouse = await warehouseRepo.findOne({ where: { code: 'INDODE_OPEN' } });
|
|
if (!warehouse) {
|
|
this.logger.warn('INDODE_OPEN warehouse not found; skipping Batch 5 seed');
|
|
return;
|
|
}
|
|
|
|
const warehouseYard = await warehouseYardRepo.findOne({ where: { warehouseId: warehouse.id } });
|
|
if (!warehouseYard) {
|
|
this.logger.warn('No warehouse yard found for INDODE_OPEN; skipping Batch 5 seed');
|
|
return;
|
|
}
|
|
|
|
const warehouseZone = await warehouseZoneRepo.findOne({ where: { yardId: warehouseYard.id } });
|
|
if (!warehouseZone) {
|
|
this.logger.warn('No warehouse zone found; skipping Batch 5 seed');
|
|
return;
|
|
}
|
|
|
|
const now = new Date();
|
|
|
|
for (const seed of SEEDS) {
|
|
const booking = await bookingRepo.save(
|
|
bookingRepo.create({
|
|
reference: seed.ref,
|
|
originYardId: originYard.id,
|
|
destinationYardId: destYard.id,
|
|
serviceTypeId: serviceType.id,
|
|
status: 'PAID',
|
|
paymentStatus: 'PAID',
|
|
scheduledDate: now,
|
|
contractType: 'SPOT',
|
|
equipmentReturn: 'TERMINAL',
|
|
paymentCurrency: 'ETB',
|
|
totalAmount: 0,
|
|
isGovernment: false,
|
|
tradeDirection: 'EXPORT',
|
|
freightType: 'BULK',
|
|
cargoTotalWeightVgm: seed.weight,
|
|
cargoFreeText: seed.notes,
|
|
}),
|
|
);
|
|
|
|
await inventoryRepo.save(
|
|
inventoryRepo.create({
|
|
bookingId: booking.id,
|
|
warehouseId: warehouse.id,
|
|
yardId: warehouseYard.id,
|
|
zoneId: warehouseZone.id,
|
|
status: 'READY_FOR_LOADING',
|
|
inspectionStatus: 'PASSED',
|
|
inspectedAt: new Date(now.getTime() - 3600 * 1000),
|
|
quantity: 1,
|
|
weight: seed.weight,
|
|
arrivedAt: new Date(now.getTime() - 7200 * 1000),
|
|
readyForLoadingAt: new Date(now.getTime() - 1800 * 1000),
|
|
notes: `[SEED-B5] ${seed.notes}`,
|
|
}),
|
|
);
|
|
|
|
this.logger.log(`Seeded ${seed.ref} → READY_FOR_LOADING + PASSED`);
|
|
}
|
|
|
|
this.logger.log('✅ Batch 5 Ready-To-Load test data seeded successfully');
|
|
} catch (error) {
|
|
this.logger.error(
|
|
`Batch5TestDataSeeder failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
);
|
|
}
|
|
}
|
|
}
|