mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 09:58:12 +00:00
Boarding, payment methods, journey direction on seat hold, and more updates
This commit is contained in:
@@ -28,14 +28,16 @@ export class FareEngineService {
|
||||
if (originStop.sequence >= destStop.sequence)
|
||||
throw new BadRequestException('Origin must come before destination in the route sequence');
|
||||
|
||||
const legStops = route.stops.filter(
|
||||
s => s.sequence > originStop.sequence && s.sequence <= destStop.sequence,
|
||||
);
|
||||
|
||||
const seatClass = await this.prisma.seatClass.findUnique({ where: { id: dto.seatClassId } });
|
||||
if (!seatClass) throw new NotFoundException('Seat class not found');
|
||||
if (!seatClass.isActive) throw new BadRequestException('Seat class is not active');
|
||||
|
||||
// Calculate distance: distanceKm represents cumulative distance from route origin
|
||||
// For a segment, distance = destination.distanceKm - origin.distanceKm
|
||||
const totalDistanceKm = destStop.distanceKm! - originStop.distanceKm!;
|
||||
if (totalDistanceKm < 0 || isNaN(totalDistanceKm))
|
||||
throw new BadRequestException('Invalid distance calculation - check route stop distances');
|
||||
|
||||
// Resolve fare: FareRule (schedule-scoped → route-scoped) takes precedence over distance×rate
|
||||
const now = new Date();
|
||||
const [originStation, destStation] = await Promise.all([
|
||||
@@ -64,23 +66,15 @@ export class FareEngineService {
|
||||
|
||||
let baseFarePerPassengerMinor: number;
|
||||
let ratePerKmMinor: number;
|
||||
let totalDistanceKm: number;
|
||||
let fareSource: string;
|
||||
|
||||
if (fareRule) {
|
||||
// Flat fare from FareRule — distance is informational only
|
||||
baseFarePerPassengerMinor = fareRule.baseFareMinor;
|
||||
totalDistanceKm = legStops.reduce((sum, s) => sum + (s.distanceKm ?? 0), 0);
|
||||
ratePerKmMinor = totalDistanceKm > 0 ? Math.round(baseFarePerPassengerMinor / totalDistanceKm) : 0;
|
||||
fareSource = fareRule.tripId ? 'SCHEDULE_FARE_RULE' : 'ROUTE_FARE_RULE';
|
||||
} else {
|
||||
// Distance × rate fallback
|
||||
const missingDistance = legStops.filter(s => s.distanceKm === null || s.distanceKm === undefined);
|
||||
if (missingDistance.length > 0)
|
||||
throw new BadRequestException(
|
||||
`Missing distanceKm on route stops at sequences: ${missingDistance.map(s => s.sequence).join(', ')}`,
|
||||
);
|
||||
totalDistanceKm = legStops.reduce((sum, s) => sum + (s.distanceKm ?? 0), 0);
|
||||
ratePerKmMinor = seatClass.baseFareMinor;
|
||||
baseFarePerPassengerMinor = totalDistanceKm * ratePerKmMinor;
|
||||
fareSource = 'DISTANCE_RATE';
|
||||
|
||||
Reference in New Issue
Block a user