mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
Faciklity add
This commit is contained in:
@@ -42,6 +42,7 @@ import { PaymentModule } from "./modules/payment/payment.module";
|
||||
import { DemoBookingsSeeder } from "./seed/demo-bookings.seeder";
|
||||
import { PricingDataSeeder } from "./seed/pricing-data.seeder";
|
||||
import { FileUploadSettingsSeeder } from "./seed/file-upload-settings.seeder";
|
||||
import { IndodeFacilitySeeder } from "./seed/indode-facility.seeder";
|
||||
//New Trains, Wagons, Container and Cargo management modules
|
||||
import { TrainsModule } from "./modules/trains/trains.module";
|
||||
import { WagonsModule } from './modules/wagons/wagons.module';
|
||||
@@ -49,6 +50,7 @@ import { ContainersModule } from './modules/container-management/containers.modu
|
||||
import { CargoesModule } from './modules/cargoes/cargoes.module';
|
||||
import { RoutesModule } from './modules/routes/routes.module';
|
||||
import { WarehousesModule } from './modules/warehouses/warehouses.module';
|
||||
import { FacilitiesModule } from './modules/facilities/facilities.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -101,9 +103,10 @@ import { WarehousesModule } from './modules/warehouses/warehouses.module';
|
||||
ContainersModule,
|
||||
CargoesModule,
|
||||
RoutesModule,
|
||||
FacilitiesModule,
|
||||
WarehousesModule,
|
||||
],
|
||||
providers: [EdrOrgSeeder, DemoUsersSeeder,FreightStaffUsersSeeder, DemoBookingsSeeder, PricingDataSeeder, FileUploadSettingsSeeder],
|
||||
providers: [EdrOrgSeeder, DemoUsersSeeder,FreightStaffUsersSeeder, DemoBookingsSeeder, PricingDataSeeder, FileUploadSettingsSeeder, IndodeFacilitySeeder],
|
||||
})
|
||||
export class AppModule implements OnApplicationBootstrap {
|
||||
constructor(
|
||||
@@ -114,6 +117,7 @@ export class AppModule implements OnApplicationBootstrap {
|
||||
private readonly demoBookingsSeeder: DemoBookingsSeeder,
|
||||
private readonly pricingDataSeeder: PricingDataSeeder,
|
||||
private readonly fileUploadSettingsSeeder: FileUploadSettingsSeeder,
|
||||
private readonly indodeFacilitySeeder: IndodeFacilitySeeder,
|
||||
) { }
|
||||
|
||||
async onApplicationBootstrap() {
|
||||
@@ -124,5 +128,10 @@ export class AppModule implements OnApplicationBootstrap {
|
||||
await this.demoBookingsSeeder.run();
|
||||
await this.pricingDataSeeder.run();
|
||||
await this.fileUploadSettingsSeeder.run();
|
||||
try {
|
||||
await this.indodeFacilitySeeder.run();
|
||||
} catch (error) {
|
||||
console.error('IndodeFacilitySeeder failed:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
import { MigrationInterface, QueryRunner, Table, TableIndex } from 'typeorm';
|
||||
|
||||
export class CreateFacilitiesTable1750000000000 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
schema: 'freight',
|
||||
name: 'facilities',
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'uuid',
|
||||
isPrimary: true,
|
||||
generationStrategy: 'uuid',
|
||||
default: 'gen_random_uuid()',
|
||||
},
|
||||
{
|
||||
name: 'code',
|
||||
type: 'varchar',
|
||||
length: '40',
|
||||
isUnique: true,
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
type: 'varchar',
|
||||
length: '160',
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'text',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'facility_type',
|
||||
type: 'varchar',
|
||||
length: '32',
|
||||
},
|
||||
{
|
||||
name: 'facility_status',
|
||||
type: 'varchar',
|
||||
length: '32',
|
||||
default: "'ACTIVE'",
|
||||
},
|
||||
{
|
||||
name: 'location_name',
|
||||
type: 'varchar',
|
||||
length: '200',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'country',
|
||||
type: 'varchar',
|
||||
length: '100',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'city',
|
||||
type: 'varchar',
|
||||
length: '100',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'address',
|
||||
type: 'text',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'latitude',
|
||||
type: 'numeric',
|
||||
precision: 10,
|
||||
scale: 8,
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'longitude',
|
||||
type: 'numeric',
|
||||
precision: 11,
|
||||
scale: 8,
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'capacity',
|
||||
type: 'numeric',
|
||||
precision: 14,
|
||||
scale: 3,
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'is_active',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
name: 'notes',
|
||||
type: 'text',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'created_at',
|
||||
type: 'timestamp',
|
||||
default: 'CURRENT_TIMESTAMP',
|
||||
},
|
||||
{
|
||||
name: 'updated_at',
|
||||
type: 'timestamp',
|
||||
default: 'CURRENT_TIMESTAMP',
|
||||
},
|
||||
{
|
||||
name: 'deleted_at',
|
||||
type: 'timestamp',
|
||||
isNullable: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'freight.facilities',
|
||||
new TableIndex({
|
||||
name: 'idx_facilities_code',
|
||||
columnNames: ['code'],
|
||||
isUnique: true,
|
||||
}),
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'freight.facilities',
|
||||
new TableIndex({
|
||||
name: 'idx_facilities_status',
|
||||
columnNames: ['facility_status'],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.dropTable('freight.facilities');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { MigrationInterface, QueryRunner, TableColumn, TableForeignKey } from 'typeorm';
|
||||
|
||||
export class AddFacilityIdToWarehouses1750000000001 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.addColumn(
|
||||
'freight.warehouses',
|
||||
new TableColumn({
|
||||
name: 'facility_id',
|
||||
type: 'uuid',
|
||||
isNullable: true,
|
||||
}),
|
||||
);
|
||||
|
||||
await queryRunner.createForeignKey(
|
||||
'freight.warehouses',
|
||||
new TableForeignKey({
|
||||
columnNames: ['facility_id'],
|
||||
referencedColumnNames: ['id'],
|
||||
referencedTableName: 'facilities',
|
||||
referencedSchema: 'freight',
|
||||
onDelete: 'SET NULL',
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
const table = await queryRunner.getTable('freight.warehouses');
|
||||
const foreignKey = table?.foreignKeys.find((fk) => fk.columnNames.includes('facility_id'));
|
||||
if (foreignKey) {
|
||||
await queryRunner.dropForeignKey('freight.warehouses', foreignKey);
|
||||
}
|
||||
await queryRunner.dropColumn('freight.warehouses', 'facility_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { FacilityStatus, FacilityType } from '../entities/facility.entity';
|
||||
|
||||
export class CreateFacilityDto {
|
||||
code!: string;
|
||||
name!: string;
|
||||
description?: string;
|
||||
facilityType!: FacilityType;
|
||||
facilityStatus?: FacilityStatus;
|
||||
locationName?: string;
|
||||
country?: string;
|
||||
city?: string;
|
||||
address?: string;
|
||||
latitude?: number;
|
||||
longitude?: number;
|
||||
capacity?: number;
|
||||
isActive?: boolean;
|
||||
notes?: string;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { FacilityStatus, FacilityType } from '../entities/facility.entity';
|
||||
|
||||
export class UpdateFacilityDto {
|
||||
code?: string;
|
||||
name?: string;
|
||||
description?: string;
|
||||
facilityType?: FacilityType;
|
||||
facilityStatus?: FacilityStatus;
|
||||
locationName?: string;
|
||||
country?: string;
|
||||
city?: string;
|
||||
address?: string;
|
||||
latitude?: number;
|
||||
longitude?: number;
|
||||
capacity?: number;
|
||||
isActive?: boolean;
|
||||
notes?: string;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import { BaseEntity } from '@edr/api-common';
|
||||
import { Column, Entity, Index, OneToMany } from 'typeorm';
|
||||
|
||||
import { Warehouse } from '../../warehouses/entities/warehouse.entity';
|
||||
|
||||
export const FACILITY_TYPES = ['PORT', 'DRY_PORT', 'TERMINAL', 'RAIL_YARD', 'WAREHOUSE_COMPLEX'] as const;
|
||||
export type FacilityType = (typeof FACILITY_TYPES)[number];
|
||||
|
||||
export const FACILITY_STATUSES = ['ACTIVE', 'INACTIVE', 'UNDER_MAINTENANCE'] as const;
|
||||
export type FacilityStatus = (typeof FACILITY_STATUSES)[number];
|
||||
|
||||
@Entity({ schema: 'freight', name: 'facilities' })
|
||||
@Index(['code'], { unique: true })
|
||||
@Index(['facilityStatus'])
|
||||
export class Facility extends BaseEntity {
|
||||
@Column({ name: 'code', type: 'varchar', length: 40, unique: true })
|
||||
code!: string;
|
||||
|
||||
@Column({ name: 'name', type: 'varchar', length: 160 })
|
||||
name!: string;
|
||||
|
||||
@Column({ name: 'description', type: 'text', nullable: true })
|
||||
description?: string | null;
|
||||
|
||||
@Column({ name: 'facility_type', type: 'varchar', length: 32 })
|
||||
facilityType!: FacilityType;
|
||||
|
||||
@Column({ name: 'facility_status', type: 'varchar', length: 32, default: 'ACTIVE' })
|
||||
facilityStatus!: FacilityStatus;
|
||||
|
||||
@Column({ name: 'location_name', type: 'varchar', length: 200, nullable: true })
|
||||
locationName?: string | null;
|
||||
|
||||
@Column({ name: 'country', type: 'varchar', length: 100, nullable: true })
|
||||
country?: string | null;
|
||||
|
||||
@Column({ name: 'city', type: 'varchar', length: 100, nullable: true })
|
||||
city?: string | null;
|
||||
|
||||
@Column({ name: 'address', type: 'text', nullable: true })
|
||||
address?: string | null;
|
||||
|
||||
@Column({ name: 'latitude', type: 'numeric', precision: 10, scale: 8, nullable: true })
|
||||
latitude?: number | null;
|
||||
|
||||
@Column({ name: 'longitude', type: 'numeric', precision: 11, scale: 8, nullable: true })
|
||||
longitude?: number | null;
|
||||
|
||||
@Column({ name: 'capacity', type: 'numeric', precision: 14, scale: 3, nullable: true })
|
||||
capacity?: number | null;
|
||||
|
||||
@Column({ name: 'is_active', type: 'boolean', default: true })
|
||||
isActive!: boolean;
|
||||
|
||||
@Column({ name: 'notes', type: 'text', nullable: true })
|
||||
notes?: string | null;
|
||||
|
||||
@OneToMany(() => Warehouse, (warehouse) => warehouse.facility)
|
||||
warehouses?: Warehouse[];
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Body, Controller, Delete, Get, HttpCode, Param, Patch, Post } from '@nestjs/common';
|
||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
import { CreateFacilityDto } from './dto/create-facility.dto';
|
||||
import { UpdateFacilityDto } from './dto/update-facility.dto';
|
||||
import { Facility } from './entities/facility.entity';
|
||||
import { FacilitiesService } from './facilities.service';
|
||||
|
||||
@ApiTags('Facilities')
|
||||
@Controller('facilities')
|
||||
export class FacilitiesController {
|
||||
constructor(private readonly facilitiesService: FacilitiesService) {}
|
||||
|
||||
@Post()
|
||||
@ApiOperation({ summary: 'Create a new facility' })
|
||||
async create(@Body() createFacilityDto: CreateFacilityDto): Promise<Facility> {
|
||||
return this.facilitiesService.create(createFacilityDto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'List all facilities' })
|
||||
async findAll(): Promise<Facility[]> {
|
||||
return this.facilitiesService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@ApiOperation({ summary: 'Get a facility by ID' })
|
||||
async findOne(@Param('id') id: string): Promise<Facility | null> {
|
||||
return this.facilitiesService.findOne(id);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@ApiOperation({ summary: 'Update a facility' })
|
||||
async update(@Param('id') id: string, @Body() updateFacilityDto: UpdateFacilityDto): Promise<Facility | null> {
|
||||
return this.facilitiesService.update(id, updateFacilityDto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@HttpCode(204)
|
||||
@ApiOperation({ summary: 'Delete a facility (soft delete)' })
|
||||
async remove(@Param('id') id: string): Promise<void> {
|
||||
return this.facilitiesService.remove(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { Facility } from './entities/facility.entity';
|
||||
import { FacilitiesController } from './facilities.controller';
|
||||
import { FacilitiesRepository } from './facilities.repository';
|
||||
import { FacilitiesService } from './facilities.service';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Facility])],
|
||||
controllers: [FacilitiesController],
|
||||
providers: [FacilitiesService, FacilitiesRepository],
|
||||
exports: [FacilitiesService, FacilitiesRepository],
|
||||
})
|
||||
export class FacilitiesModule {}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { BaseRepository } from '@edr/api-common';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { Facility } from './entities/facility.entity';
|
||||
|
||||
@Injectable()
|
||||
export class FacilitiesRepository extends BaseRepository<Facility> {
|
||||
constructor(@InjectRepository(Facility) repository: Repository<Facility>) {
|
||||
super(repository);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { CreateFacilityDto } from './dto/create-facility.dto';
|
||||
import { UpdateFacilityDto } from './dto/update-facility.dto';
|
||||
import { Facility } from './entities/facility.entity';
|
||||
import { FacilitiesRepository } from './facilities.repository';
|
||||
|
||||
@Injectable()
|
||||
export class FacilitiesService {
|
||||
constructor(private readonly facilitiesRepository: FacilitiesRepository) {}
|
||||
|
||||
async create(createFacilityDto: CreateFacilityDto): Promise<Facility> {
|
||||
return this.facilitiesRepository.create(createFacilityDto);
|
||||
}
|
||||
|
||||
async findAll(): Promise<Facility[]> {
|
||||
return this.facilitiesRepository.findAll({ relations: ['warehouses'] });
|
||||
}
|
||||
|
||||
async findOne(id: string): Promise<Facility | null> {
|
||||
return this.facilitiesRepository.findById(id);
|
||||
}
|
||||
|
||||
async update(id: string, updateFacilityDto: UpdateFacilityDto): Promise<Facility | null> {
|
||||
return this.facilitiesRepository.update(id, updateFacilityDto);
|
||||
}
|
||||
|
||||
async remove(id: string): Promise<void> {
|
||||
return this.facilitiesRepository.softDelete(id);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { BaseEntity } from '@edr/api-common';
|
||||
import { Column, Entity, Index, OneToMany } from 'typeorm';
|
||||
import { Column, Entity, Index, ManyToOne, OneToMany } from 'typeorm';
|
||||
|
||||
import { Facility } from '../../facilities/entities/facility.entity';
|
||||
import { WarehouseYard } from './warehouse-yard.entity';
|
||||
|
||||
export const WAREHOUSE_TYPES = ['OPEN_WAREHOUSE', 'CLOSED_WAREHOUSE'] as const;
|
||||
@@ -58,6 +59,12 @@ export class Warehouse extends BaseEntity {
|
||||
@Column({ name: 'is_active', type: 'boolean', default: true })
|
||||
isActive!: boolean;
|
||||
|
||||
@Column({ name: 'facility_id', type: 'uuid', nullable: true })
|
||||
facilityId?: string | null;
|
||||
|
||||
@ManyToOne(() => Facility, (facility) => facility.warehouses, { nullable: true })
|
||||
facility?: Facility | null;
|
||||
|
||||
@OneToMany(() => WarehouseYard, (yard) => yard.warehouse)
|
||||
yards?: WarehouseYard[];
|
||||
}
|
||||
|
||||
174
apps/edr-freight-api/src/seed/indode-facility.seeder.ts
Normal file
174
apps/edr-freight-api/src/seed/indode-facility.seeder.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
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<void> {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
'Indode Multipurpose Dry Port facility seeded successfully with 2 warehouses and 11 yards each',
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private async createYardsForWarehouse(
|
||||
yardRepo: any,
|
||||
zoneRepo: any,
|
||||
warehouse: Warehouse,
|
||||
): Promise<void> {
|
||||
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}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
export type UserTypeRequest {
|
||||
export type UserTypeRequest = {
|
||||
email: string;
|
||||
username: string;
|
||||
phoneNumber: string;
|
||||
|
||||
Reference in New Issue
Block a user