Added modules for tracking & shipment info
This commit is contained in:
parent
500f4a88c9
commit
9279438c20
|
|
@ -1,9 +1,34 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { AppController } from './app.controller';
|
||||
import { AppService } from './app.service';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { ContainerEntity } from '@/entities/container.entity';
|
||||
import { LiveTrackingEntity } from '@/entities/liveTracking.entity';
|
||||
import { ShipmentEntity } from '@/entities/shipment.entity';
|
||||
import { TrackingModule } from './tracking/tracking.module';
|
||||
import { ShipmentsModule } from './shipments/shipments.module';
|
||||
|
||||
@Module({
|
||||
imports: [],
|
||||
imports: [
|
||||
TypeOrmModule.forRoot({
|
||||
type: 'mysql',
|
||||
host: 'localhost',
|
||||
port: 13306,
|
||||
username: 'root',
|
||||
password: 'myfreight',
|
||||
database: 'myfreight',
|
||||
entities: [ContainerEntity, LiveTrackingEntity, ShipmentEntity],
|
||||
synchronize: true,
|
||||
logging: false,
|
||||
}),
|
||||
TypeOrmModule.forFeature([
|
||||
ContainerEntity,
|
||||
LiveTrackingEntity,
|
||||
ShipmentEntity,
|
||||
]),
|
||||
TrackingModule,
|
||||
ShipmentsModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { ContainerEntity } from '@/entities/container.entity';
|
||||
import { instanceToPlain, plainToClass } from 'class-transformer';
|
||||
|
||||
export class ContainerDto {
|
||||
@ApiProperty()
|
||||
id: string;
|
||||
|
||||
@ApiProperty()
|
||||
containerNumber: string;
|
||||
|
||||
@ApiProperty()
|
||||
shipmentId: string;
|
||||
|
||||
constructor(entity: ContainerEntity) {
|
||||
this.id = entity.id;
|
||||
this.containerNumber = entity.containerNumber;
|
||||
this.shipmentId = entity.shipmentId;
|
||||
}
|
||||
|
||||
static fromEntity(entity: ContainerEntity): ContainerDto {
|
||||
const data = instanceToPlain(entity);
|
||||
return plainToClass(ContainerDto, data);
|
||||
}
|
||||
|
||||
toEntity(): ContainerEntity {
|
||||
const data = instanceToPlain(this);
|
||||
return plainToClass(ContainerEntity, data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
import { ShipmentEntity } from '@/entities/shipment.entity';
|
||||
import { ContainerEntity } from '@/entities/container.entity';
|
||||
import { LiveTrackingEntity } from '@/entities/liveTracking.entity';
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
|
||||
export class ShipmentContainerDto {
|
||||
@ApiProperty()
|
||||
id: string;
|
||||
@ApiProperty()
|
||||
containerNumber: string;
|
||||
|
||||
constructor(entity: ContainerEntity) {
|
||||
this.id = entity.id;
|
||||
this.containerNumber = entity.containerNumber;
|
||||
}
|
||||
static bulk(entities: ContainerEntity[]) {
|
||||
return entities.map((entity) => new ShipmentContainerDto(entity));
|
||||
}
|
||||
}
|
||||
|
||||
export class ShipmentLiveTrackingDto {
|
||||
@ApiProperty({
|
||||
format: 'date-time',
|
||||
})
|
||||
createdAt: string;
|
||||
@ApiProperty()
|
||||
latitude: number;
|
||||
@ApiProperty()
|
||||
longitude: number;
|
||||
|
||||
constructor(entity: LiveTrackingEntity) {
|
||||
this.createdAt = entity.createdAt.toISOString();
|
||||
this.latitude = entity.latitude;
|
||||
this.longitude = entity.longitude;
|
||||
}
|
||||
}
|
||||
export class ShipmentDto {
|
||||
@ApiProperty()
|
||||
id: string;
|
||||
@ApiProperty({
|
||||
format: 'date-time',
|
||||
})
|
||||
createdAt: string;
|
||||
@ApiProperty()
|
||||
carrierName: string;
|
||||
@ApiProperty()
|
||||
originPort: string;
|
||||
@ApiProperty()
|
||||
destinationPort: string;
|
||||
@ApiProperty({
|
||||
format: 'date-time',
|
||||
})
|
||||
departureDate: string;
|
||||
@ApiProperty({
|
||||
format: 'date-time',
|
||||
})
|
||||
arrivalDateOriginal: string;
|
||||
@ApiProperty({
|
||||
format: 'date-time',
|
||||
})
|
||||
arrivalDateEstimate: string;
|
||||
@ApiPropertyOptional({
|
||||
isArray: true,
|
||||
type: ShipmentContainerDto,
|
||||
})
|
||||
containers: ShipmentContainerDto[] | null;
|
||||
@ApiPropertyOptional({
|
||||
type: ShipmentLiveTrackingDto,
|
||||
})
|
||||
liveTracking: ShipmentLiveTrackingDto | null;
|
||||
|
||||
constructor(entity: ShipmentEntity) {
|
||||
this.id = entity.id;
|
||||
this.createdAt = entity.createdAt.toISOString();
|
||||
this.carrierName = entity.carrierName;
|
||||
this.originPort = entity.originPort;
|
||||
this.destinationPort = entity.destinationPort;
|
||||
this.departureDate = entity.departureDate.toISOString();
|
||||
this.arrivalDateOriginal = entity.arrivalDateOriginal.toISOString();
|
||||
this.arrivalDateEstimate = entity.arrivalDateEstimate.toISOString();
|
||||
|
||||
this.containers = Array.isArray(entity.containers)
|
||||
? ShipmentContainerDto.bulk(entity.containers)
|
||||
: null;
|
||||
this.liveTracking = null;
|
||||
}
|
||||
|
||||
static bulk(entities: ShipmentEntity[]) {
|
||||
return entities.map((entity) => new ShipmentDto(entity));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsDate, IsNotEmpty } from 'class-validator';
|
||||
|
||||
export class TrackingDto {
|
||||
@ApiProperty()
|
||||
@IsNotEmpty()
|
||||
carrierName!: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsNotEmpty()
|
||||
destinationUnLoCode!: string;
|
||||
|
||||
@ApiProperty({
|
||||
type: 'string',
|
||||
format: 'date-time',
|
||||
})
|
||||
@Type(() => Date)
|
||||
@IsDate()
|
||||
@IsNotEmpty()
|
||||
departureDate!: Date;
|
||||
|
||||
@ApiProperty({
|
||||
type: 'string',
|
||||
format: 'date-time',
|
||||
})
|
||||
@IsDate()
|
||||
@IsNotEmpty()
|
||||
@Type(() => Date)
|
||||
arrivalDateEstimate!: Date;
|
||||
|
||||
@ApiProperty()
|
||||
@IsNotEmpty()
|
||||
containerNumber!: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ShipmentsController } from './shipments.controller';
|
||||
|
||||
describe('ShipmentsController', () => {
|
||||
let controller: ShipmentsController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [ShipmentsController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<ShipmentsController>(ShipmentsController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import { Controller, Get } from '@nestjs/common';
|
||||
import { ShipmentsService } from '@/shipments/shipments.service';
|
||||
import { ApiExtraModels, ApiOkResponse, getSchemaPath } from '@nestjs/swagger';
|
||||
import {
|
||||
ShipmentContainerDto,
|
||||
ShipmentDto,
|
||||
ShipmentLiveTrackingDto,
|
||||
} from '@/dtos/shipment.dto';
|
||||
|
||||
@Controller('shipments')
|
||||
@ApiExtraModels(ShipmentDto, ShipmentContainerDto, ShipmentLiveTrackingDto)
|
||||
export class ShipmentsController {
|
||||
constructor(private readonly shipmentsService: ShipmentsService) {}
|
||||
|
||||
@Get()
|
||||
@ApiOkResponse({
|
||||
description: 'Returns a list of shipments',
|
||||
schema: {
|
||||
items: {
|
||||
$ref: getSchemaPath(ShipmentDto),
|
||||
},
|
||||
},
|
||||
})
|
||||
getShipments() {
|
||||
return this.shipmentsService.getShipments();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { ShipmentsController } from './shipments.controller';
|
||||
import { ShipmentsService } from './shipments.service';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { ContainerEntity } from '@/entities/container.entity';
|
||||
import { LiveTrackingEntity } from '@/entities/liveTracking.entity';
|
||||
import { ShipmentEntity } from '@/entities/shipment.entity';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([
|
||||
ContainerEntity,
|
||||
LiveTrackingEntity,
|
||||
ShipmentEntity,
|
||||
]),
|
||||
],
|
||||
controllers: [ShipmentsController],
|
||||
providers: [ShipmentsService],
|
||||
})
|
||||
export class ShipmentsModule {}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ShipmentsService } from './shipments.service';
|
||||
|
||||
describe('ShipmentsService', () => {
|
||||
let service: ShipmentsService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [ShipmentsService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<ShipmentsService>(ShipmentsService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { ShipmentEntity } from '@/entities/shipment.entity';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
@Injectable()
|
||||
export class ShipmentsService {
|
||||
constructor(
|
||||
@InjectRepository(ShipmentEntity)
|
||||
private readonly shipmentRepository: Repository<ShipmentEntity>,
|
||||
) {}
|
||||
|
||||
// @todo add pagination
|
||||
getShipments() {
|
||||
return this.shipmentRepository.find({
|
||||
relations: ['liveTracking', 'containers'],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { TrackingController } from './tracking.controller';
|
||||
|
||||
describe('TrackingController', () => {
|
||||
let controller: TrackingController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [TrackingController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<TrackingController>(TrackingController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { Controller } from '@nestjs/common';
|
||||
|
||||
@Controller('tracking')
|
||||
export class TrackingController {}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { TrackingController } from './tracking.controller';
|
||||
import { TrackingService } from './tracking.service';
|
||||
|
||||
@Module({
|
||||
controllers: [TrackingController],
|
||||
providers: [TrackingService],
|
||||
})
|
||||
export class TrackingModule {}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { TrackingService } from './tracking.service';
|
||||
|
||||
describe('TrackingService', () => {
|
||||
let service: TrackingService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [TrackingService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<TrackingService>(TrackingService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class TrackingService {}
|
||||
Loading…
Reference in New Issue