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 { Module } from '@nestjs/common';
|
||||||
import { AppController } from './app.controller';
|
import { AppController } from './app.controller';
|
||||||
import { AppService } from './app.service';
|
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({
|
@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],
|
controllers: [AppController],
|
||||||
providers: [AppService],
|
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