106 lines
4.5 KiB
TypeScript
106 lines
4.5 KiB
TypeScript
import { Injectable, NotAcceptableException } from '@nestjs/common'
|
|
import { CreateTrainDto } from './dto/create-train.dto'
|
|
import { UpdateTrainDto } from './dto/update-train.dto'
|
|
import { PrismaService } from 'src/prisma/prisma.service'
|
|
import { TrainTrip, User } from '@prisma/client'
|
|
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
|
import { paginate } from 'src/common/utils/pagination.utils'
|
|
import { ImportTrainDto } from './dto/import-train.dto'
|
|
import { InterrailJourney, InterrailLegInfo, InterrailTravelInfo } from './dto/interrail-api.dto'
|
|
import { JsonObject } from '@prisma/client/runtime/library'
|
|
import { OSMRResponse } from './dto/osmr-api.dto'
|
|
|
|
@Injectable()
|
|
export class TrainsService {
|
|
constructor(private prisma: PrismaService) { }
|
|
|
|
async create(createTrainDto: CreateTrainDto): Promise<TrainTrip> {
|
|
return await this.prisma.trainTrip.create({ data: createTrainDto })
|
|
}
|
|
|
|
async findAll(queryPagination?: QueryPaginationDto): Promise<[TrainTrip[], number]> {
|
|
return [
|
|
await this.prisma.trainTrip.findMany({
|
|
...paginate(queryPagination),
|
|
}),
|
|
await this.prisma.trainTrip.count(),
|
|
]
|
|
}
|
|
|
|
async findOne(id: string): Promise<TrainTrip> {
|
|
return await this.prisma.trainTrip.findUnique({
|
|
where: { id },
|
|
})
|
|
}
|
|
|
|
async update(id: string, updateTrainDto: UpdateTrainDto): Promise<TrainTrip> {
|
|
return await this.prisma.trainTrip.update({
|
|
where: { id },
|
|
data: updateTrainDto,
|
|
})
|
|
}
|
|
|
|
async remove(id: string): Promise<TrainTrip> {
|
|
return await this.prisma.trainTrip.delete({
|
|
where: { id },
|
|
})
|
|
}
|
|
|
|
async import(user: User, { id: trainId }: ImportTrainDto): Promise<TrainTrip> {
|
|
const interrailResult: InterrailJourney = await fetch(`https://3uiwjsimnh.execute-api.eu-central-1.amazonaws.com/Prod/journey-import?id=${trainId}`)
|
|
.then(data => data.json())
|
|
if (interrailResult.data.travels.length !== 1)
|
|
throw new NotAcceptableException(`Ce voyage contient ${interrailResult.data.travels.length} trajets. Merci d'ajouter les trajets un à un.`)
|
|
const travel = interrailResult.data.travels[0]
|
|
if (travel.legs.length !== 1)
|
|
throw new NotAcceptableException(`Ce trajet contient ${travel.legs.length} trains. Merci d'ajouter les trajets un à un.`)
|
|
const leg = travel.legs[0]
|
|
|
|
const travelInfoJson: InterrailTravelInfo = JSON.parse(travel.infoJson)
|
|
const departure = new Date(`${travelInfoJson.date.year}-${travelInfoJson.date.month.toString().padStart(2, "0")}-${travelInfoJson.date.day.toString().padStart(2, "0")}` +
|
|
`T${travelInfoJson.departureTime.hours.toString().padStart(2, "0")}:${travelInfoJson.departureTime.minutes.toString().padStart(2, "0")}:00+0100`)
|
|
departure.setDate(departure.getDate() + travelInfoJson.departureTime.offset)
|
|
const arrival = new Date(`${travelInfoJson.date.year}-${travelInfoJson.date.month.toString().padStart(2, "0")}-${travelInfoJson.date.day.toString().padStart(2, "0")}` +
|
|
`T${travelInfoJson.arrivalTime.hours.toString().padStart(2, "0")}:${travelInfoJson.arrivalTime.minutes.toString().padStart(2, "0")}:00+0100`)
|
|
arrival.setDate(arrival.getDate() + travelInfoJson.arrivalTime.offset)
|
|
|
|
const legInfoJson: InterrailLegInfo = JSON.parse(leg.infoJson)
|
|
const coordinatesString = legInfoJson.trainStopStations.map(trainStopStation => {
|
|
return `${trainStopStation.coordinates.longitude},${trainStopStation.coordinates.latitude}`
|
|
}).join(';')
|
|
const osmrResult: OSMRResponse = await fetch(`https://signal.eu.org/osm/eu/route/v1/train/${coordinatesString}?overview=full&steps=true&exclude=highspeed`).then(result => result.json())
|
|
if (osmrResult?.code === "NoRoute")
|
|
throw new NotAcceptableException("Aucune route n'a été trouvée avec https://signal.eu.org/osm/")
|
|
const route = osmrResult.routes[0]
|
|
const distance = route.distance
|
|
const geometry = route.geometry
|
|
|
|
return this.prisma.trainTrip.upsert({
|
|
where: {
|
|
id: trainId,
|
|
},
|
|
create: {
|
|
id: trainId,
|
|
userId: user.id,
|
|
distance: distance,
|
|
from: travel.from,
|
|
to: travel.to,
|
|
departureTime: departure,
|
|
arrivalTime: arrival,
|
|
infoJson: leg.infoJson,
|
|
geometry: geometry,
|
|
},
|
|
update: {
|
|
userId: user.id,
|
|
distance: distance,
|
|
from: travel.from,
|
|
to: travel.to,
|
|
departureTime: departure,
|
|
arrivalTime: arrival,
|
|
infoJson: leg.infoJson,
|
|
geometry: geometry,
|
|
}
|
|
})
|
|
}
|
|
}
|