mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 00:52:50 +00:00
76 lines
3.4 KiB
TypeScript
76 lines
3.4 KiB
TypeScript
import { IsString, IsOptional, IsEnum, IsInt, Min } from 'class-validator';
|
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
import { Type } from 'class-transformer';
|
|
import { Currency } from '@prisma/client';
|
|
|
|
// Nationality → home currency mapping
|
|
export const NATIONALITY_CURRENCY_MAP: Record<string, Currency> = {
|
|
Ethiopian: Currency.ETB,
|
|
Djiboutian: Currency.DJF,
|
|
};
|
|
|
|
export function resolveCurrencyFromNationality(nationality?: string): Currency {
|
|
if (!nationality) return Currency.ETB;
|
|
return NATIONALITY_CURRENCY_MAP[nationality] ?? Currency.USD;
|
|
}
|
|
|
|
export class FareCalculateDto {
|
|
@ApiProperty({ example: 'route-uuid', description: 'Route UUID — used to look up stop distances' })
|
|
@IsString() routeId: string;
|
|
|
|
@ApiProperty({ example: 'station-uuid', description: 'Origin station UUID (must be a stop on the route)' })
|
|
@IsString() originStationId: string;
|
|
|
|
@ApiProperty({ example: 'station-uuid', description: 'Destination station UUID (must come after origin)' })
|
|
@IsString() destinationStationId: string;
|
|
|
|
@ApiProperty({ example: 'seat-class-uuid', description: 'SeatClass UUID — its basePrice is the per-km rate in ETB minor units' })
|
|
@IsString() seatClassId: string;
|
|
|
|
@ApiPropertyOptional({
|
|
example: 'Ethiopian',
|
|
description: 'Passenger nationality. Determines the billing currency: Ethiopian → ETB, Djiboutian → DJF, other → USD. Defaults to ETB.',
|
|
})
|
|
@IsOptional() @IsString() nationality?: string;
|
|
|
|
@ApiPropertyOptional({
|
|
example: 2,
|
|
description: 'Number of adult passengers (age ≥ 5). Defaults to 1.',
|
|
})
|
|
@IsOptional() @Type(() => Number) @IsInt() @Min(1) adultCount?: number;
|
|
|
|
@ApiPropertyOptional({
|
|
example: 1,
|
|
description: 'Number of child passengers (age < 5). First child travels free.',
|
|
})
|
|
@IsOptional() @Type(() => Number) @IsInt() @Min(0) childCount?: number;
|
|
|
|
@ApiPropertyOptional({ example: 'WEEKEND15', description: 'Promo code for discount' })
|
|
@IsOptional() @IsString() promoCode?: string;
|
|
|
|
@ApiPropertyOptional({ example: 'schedule-uuid', description: 'Schedule UUID — used to match schedule-scoped FareRules first' })
|
|
@IsOptional() @IsString() scheduleId?: string;
|
|
}
|
|
|
|
export class FareBreakdownDto {
|
|
@ApiProperty({ example: 'ADD-DJI' }) routeCode: string;
|
|
@ApiProperty({ example: 'Addis Ababa' }) originName: string;
|
|
@ApiProperty({ example: 'Djibouti' }) destinationName: string;
|
|
@ApiProperty({ example: 'Economy Regular' }) seatClassName: string;
|
|
@ApiProperty({ example: 756 }) totalDistanceKm: number;
|
|
@ApiProperty({ example: 120 }) ratePerKmMinor: number;
|
|
@ApiProperty({ example: 90720 }) baseFarePerPassengerMinor: number;
|
|
@ApiProperty({ example: 2 }) adultCount: number;
|
|
@ApiProperty({ example: 1 }) childCount: number;
|
|
@ApiProperty({ example: 1 }) freeChildrenCount: number;
|
|
@ApiProperty({ example: 0 }) paidChildrenCount: number;
|
|
@ApiProperty({ example: 181440 }) subtotalMinor: number;
|
|
@ApiProperty({ example: 0 }) discountMinor: number;
|
|
@ApiProperty({ example: 9072 }) taxMinor: number;
|
|
@ApiProperty({ example: 190512 }) totalMinor: number;
|
|
@ApiProperty({ example: 'ETB', enum: Currency }) billingCurrency: Currency;
|
|
@ApiProperty({ example: 190512 }) totalInBillingCurrency: number;
|
|
@ApiProperty({ example: 3.25 }) exchangeRate: number;
|
|
@ApiProperty({ description: 'Step-by-step calculation trace for transparency' }) calculation: string;
|
|
}
|