Files
edr-platform/apps/edr-freight-api/src/seed/batch5-test-data.seeder.ts
2026-06-24 09:56:12 +03:00

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)}`,
);
}
}
}