import { Injectable, Logger } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { Facility } from '../modules/facilities/entities/facility.entity'; import { Warehouse } from '../modules/warehouses/entities/warehouse.entity'; import { WarehouseYard, type WarehouseYardType } from '../modules/warehouses/entities/warehouse-yard.entity'; import { WarehouseZone, type WarehouseZoneType } from '../modules/warehouses/entities/warehouse-zone.entity'; const INDODE_FACILITY = { code: 'INDODE_DRY_PORT', name: 'Indode Multipurpose Dry Port', description: 'Main facility for container and cargo handling', facilityType: 'DRY_PORT' as const, facilityStatus: 'ACTIVE' as const, locationName: 'Indode', country: 'Djibouti', city: 'Djibouti', address: 'Indode, Djibouti', latitude: 11.5447, longitude: 43.145, capacity: 50000, isActive: true, notes: 'Primary dry port for container consolidation and distribution', }; const WAREHOUSES = [ { name: 'Open Warehouse - Indode', code: 'INDODE_OPEN', type: 'OPEN_WAREHOUSE' as const, locationName: 'Indode Open', capacityWeight: 25000, capacityContainers: 500, maxWeight: 25000, maxVolume: 5000, status: 'ACTIVE' as const, isActive: true, }, { name: 'Closed Warehouse - Indode', code: 'INDODE_CLOSED', type: 'CLOSED_WAREHOUSE' as const, locationName: 'Indode Closed', capacityWeight: 20000, capacityContainers: 400, maxWeight: 20000, maxVolume: 4000, status: 'ACTIVE' as const, isActive: true, }, ]; const YARD_TYPES = [ 'CONTAINER_YARD', 'BULK_YARD', 'GENERAL_CARGO_YARD', 'HAZARDOUS_YARD', 'COLD_STORAGE_YARD', ] as const; @Injectable() export class IndodeFacilitySeeder { private readonly logger = new Logger(IndodeFacilitySeeder.name); constructor(private readonly dataSource: DataSource) {} async run(): Promise { try { await this.dataSource.transaction(async (manager) => { const facilityRepo = manager.getRepository(Facility); const warehouseRepo = manager.getRepository(Warehouse); const yardRepo = manager.getRepository(WarehouseYard); const zoneRepo = manager.getRepository(WarehouseZone); // Ensure facility exists const facility = await facilityRepo.findOne({ where: { code: INDODE_FACILITY.code }, }); if (facility) { this.logger.log('Indode facility already exists, skipping seed'); return; } const newFacility = facilityRepo.create(INDODE_FACILITY); const savedFacility = await facilityRepo.save(newFacility); this.logger.log(`Created facility: ${savedFacility.code}`); // Create warehouses for the facility for (const warehouseData of WAREHOUSES) { try { const warehouse = await warehouseRepo.findOne({ where: { code: warehouseData.code }, }); if (warehouse) { this.logger.log(`Warehouse ${warehouseData.code} already exists, skipping`); continue; } const newWarehouse = warehouseRepo.create({ ...warehouseData, facilityId: savedFacility.id, }); const savedWarehouse = await warehouseRepo.save(newWarehouse); this.logger.log(`Created warehouse: ${savedWarehouse.code} under facility ${savedFacility.code}`); // Create 11 yards per warehouse await this.createYardsForWarehouse(yardRepo, zoneRepo, savedWarehouse); } catch (warehouseError) { this.logger.warn( `Failed to create warehouse ${warehouseData.code}: ${warehouseError instanceof Error ? warehouseError.message : String(warehouseError)}`, ); } } this.logger.log( 'Indode Multipurpose Dry Port facility seeded successfully with 2 warehouses and 11 yards each', ); }); } catch (error) { this.logger.error( `IndodeFacilitySeeder error: ${error instanceof Error ? error.message : String(error)}`, ); } } private async createYardsForWarehouse( yardRepo: any, zoneRepo: any, warehouse: Warehouse, ): Promise { const baseCapacityWeight = 5000; const baseCapacityContainers = 100; const yardCount = 11; for (let i = 0; i < yardCount; i++) { const yardType: WarehouseYardType = i < YARD_TYPES.length ? YARD_TYPES[i] : 'GENERAL_CARGO_YARD'; const yardCode = `${warehouse.code}_YARD_${String(i + 1).padStart(2, '0')}`; const existingYard = await yardRepo.findOne({ where: { code: yardCode } }); if (existingYard) { this.logger.log(`Yard ${yardCode} already exists, skipping`); continue; } const yardData = { warehouseId: warehouse.id, name: `${warehouse.code} ${yardType.replace(/_/g, ' ')} ${String(i + 1).padStart(2, '0')}`, code: yardCode, type: yardType, capacityWeight: baseCapacityWeight, capacityContainers: baseCapacityContainers, maxWeight: baseCapacityWeight, maxVolume: baseCapacityWeight / 2, status: 'ACTIVE' as const, isActive: true, }; const newYard = yardRepo.create(yardData); const savedYard = (await yardRepo.save(newYard)) as WarehouseYard; this.logger.log(`Created yard: ${savedYard.code}`); // Create default zone for the yard const zoneType: WarehouseZoneType = yardType.replace('_YARD', '_ZONE') as WarehouseZoneType; const zoneCode = `${savedYard.code}_ZONE_A`; const zoneData = { yardId: savedYard.id, name: `${savedYard.name} Zone A`, code: zoneCode, type: zoneType, capacityWeight: (baseCapacityWeight ?? 1000) / 2, capacityContainers: (baseCapacityContainers ?? 100) / 2, maxWeight: (baseCapacityWeight ?? 1000) / 2, maxVolume: (baseCapacityWeight ?? 500) / 2, status: 'ACTIVE' as const, isActive: true, }; const newZone = zoneRepo.create(zoneData); await zoneRepo.save(newZone); this.logger.log(`Created zone: ${zoneCode}`); } } }