traintrape-moi/server/src/trains/trains.service.ts
2024-12-08 13:41:37 +01:00

106 lines
4.4 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 { Player, TrainTrip } 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 { distanceCoordinates } from 'src/common/utils/calculus.utils'
import { PlayerFilterDto } from 'src/common/dto/player_filter.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, playerFilter: PlayerFilterDto): Promise<[TrainTrip[], number]> {
return [
await this.prisma.trainTrip.findMany({
where: playerFilter,
...paginate(queryPagination),
}),
await this.prisma.trainTrip.count({
where: playerFilter,
}),
]
}
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(player: Player, { 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 distance = legInfoJson.trainStopStations
.map(trainStopStation => trainStopStation.coordinates)
.reduce((distance, coordinates, index) => {
if (index === 0)
return distance
const oldCoordinates = legInfoJson.trainStopStations.at(index - 1).coordinates
return distance + distanceCoordinates({ from: oldCoordinates, to: coordinates })
}, 0)
return this.prisma.trainTrip.upsert({
where: {
id: trainId,
},
create: {
id: trainId,
playerId: player.id,
distance: distance,
from: travel.from,
to: travel.to,
departureTime: departure,
arrivalTime: arrival,
infoJson: leg.infoJson,
},
update: {
playerId: player.id,
distance: distance,
from: travel.from,
to: travel.to,
departureTime: departure,
arrivalTime: arrival,
infoJson: leg.infoJson,
}
})
}
}