diff --git a/.env b/.env index 1901128f9..badc10d66 100644 --- a/.env +++ b/.env @@ -17,6 +17,6 @@ EMAIL_SENDER=nicht-antworten@zvon.de FIREBASE_PROJECT_ID=* FIREBASE_PRIVATE_KEY=* FIREBASE_CLIENT_EMAIL=* -PUBLIC_FIXED_PRICE=300 - +PUBLIC_FIXED_PRICE=500 +PUBLIC_FIXED_REDUCED_PRICE=300 SECRET_KEY=* \ No newline at end of file diff --git a/src/lib/i18n/de.ts b/src/lib/i18n/de.ts index 18d9ae204..ad6ee27b1 100644 --- a/src/lib/i18n/de.ts +++ b/src/lib/i18n/de.ts @@ -246,6 +246,7 @@ const translations: Translations = { kidsZeroToTwo: '0 - 2 Jahre', kidsThreeToFour: '3 - 4 Jahre', kidsFiveToSix: '5 - 6 Jahre', + kidsSevenToFourteen: '7 - 14 Jahre', foldableWheelchair: 'Faltbarer Rollstuhl', withFoldableWheelchair: 'Mit faltbarem Rollstuhl', passengerNumber: 'Anzahl Personen', @@ -259,6 +260,7 @@ const translations: Translations = { }, totalPrice: 'Gesamtpreis', cashOnly: 'Nur Barzahlung im Taxi', + ptTicketNeeded: 'Zusätzlich ist ein entsprechendes ÖPNV-Ticket erforderlich.', cancel: 'Stornieren', loginToBook: 'Einloggen zum Buchen', connection: 'Verbindung', diff --git a/src/lib/i18n/en.ts b/src/lib/i18n/en.ts index a2bcbb962..151c4cba4 100644 --- a/src/lib/i18n/en.ts +++ b/src/lib/i18n/en.ts @@ -239,6 +239,7 @@ const translations: Translations = { kidsZeroToTwo: '0 - 2 years', kidsThreeToFour: '3 - 4 years', kidsFiveToSix: '5 - 6 years', + kidsSevenToFourteen: '7 - 14 years', foldableWheelchair: 'Foldable wheelchair', withFoldableWheelchair: 'With foldable wheelchair', passengerNumber: 'Number of people', @@ -252,6 +253,7 @@ const translations: Translations = { }, totalPrice: 'Total price', cashOnly: 'Cash payment only', + ptTicketNeeded: 'In addition, a valid public transport ticket is required.', cancel: 'Cancel', loginToBook: 'Login to book', connection: 'Connection', diff --git a/src/lib/i18n/translation.ts b/src/lib/i18n/translation.ts index f1f5f42d4..0fce63623 100644 --- a/src/lib/i18n/translation.ts +++ b/src/lib/i18n/translation.ts @@ -216,8 +216,10 @@ export type Translations = { kidsZeroToTwo: string; kidsThreeToFour: string; kidsFiveToSix: string; + kidsSevenToFourteen: string; totalPrice: string; cashOnly: string; + ptTicketNeeded: string; foldableWheelchair: string; withFoldableWheelchair: string; passengerNumber: string; diff --git a/src/lib/server/booking/bookingApi.ts b/src/lib/server/booking/bookingApi.ts index e3dbc7c8d..0e1c5b910 100644 --- a/src/lib/server/booking/bookingApi.ts +++ b/src/lib/server/booking/bookingApi.ts @@ -68,6 +68,7 @@ export async function bookingApi( kidsZeroToTwo: number, kidsThreeToFour: number, kidsFiveToSix: number, + kidsSevenToFourteen: number, skipPromiseCheck?: boolean ): Promise<{ message?: string; @@ -88,6 +89,7 @@ export async function bookingApi( JSON.stringify(kidsZeroToTwo, null, 2), JSON.stringify(kidsThreeToFour, null, 2), JSON.stringify(kidsFiveToSix, null, 2), + JSON.stringify(kidsSevenToFourteen, null, 2), JSON.stringify(skipPromiseCheck, null, 2) ); if (p.connection1 == null && p.connection2 == null) { @@ -200,6 +202,7 @@ export async function bookingApi( kidsZeroToTwo, kidsThreeToFour, kidsFiveToSix, + kidsSevenToFourteen, trx )) ?? null; } @@ -213,6 +216,7 @@ export async function bookingApi( kidsZeroToTwo, kidsThreeToFour, kidsFiveToSix, + kidsSevenToFourteen, trx )) ?? null; } diff --git a/src/lib/server/booking/insertRequest.ts b/src/lib/server/booking/insertRequest.ts index ec443bc0e..3db8abc25 100644 --- a/src/lib/server/booking/insertRequest.ts +++ b/src/lib/server/booking/insertRequest.ts @@ -4,7 +4,7 @@ import { type Database } from '$lib/server/db'; import { sql, Transaction } from 'kysely'; import { sendNotifications } from '$lib/server/firebase/notifications'; import { TourChange } from '$lib/server/firebase/firebase'; -import { env } from '$env/dynamic/public'; +import { legOdmPrice } from '$lib/util/odmPrice'; export async function insertRequest( r: BookRideResponse, @@ -14,6 +14,7 @@ export async function insertRequest( kidsZeroToTwo: number, kidsThreeToFour: number, kidsFiveToSix: number, + kidsSevenToFourteen: number, trx: Transaction ): Promise { r.mergeTourList = r.mergeTourList.filter((id) => id != r.best.tour); @@ -24,9 +25,11 @@ export async function insertRequest( sql`,` )}]::INTEGER[]` : sql`ARRAY[]::INTEGER[]`; - const ticketPrice = - (capacities.passengers - kidsZeroToTwo - kidsThreeToFour - kidsFiveToSix) * - parseInt(env.PUBLIC_FIXED_PRICE); + const ticketPrice = legOdmPrice( + capacities.passengers, + kidsZeroToTwo + kidsThreeToFour + kidsFiveToSix, + kidsSevenToFourteen + ); const requestId = ( await sql<{ request: number }>` SELECT create_and_merge_tours( diff --git a/src/lib/server/booking/tests/concatenations/append.test.ts b/src/lib/server/booking/tests/concatenations/append.test.ts index 022887964..eab4b472f 100644 --- a/src/lib/server/booking/tests/concatenations/append.test.ts +++ b/src/lib/server/booking/tests/concatenations/append.test.ts @@ -47,7 +47,7 @@ describe('Concatenation tests', () => { capacities }; - await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, 0, true); const tours = await getTours(); expect(tours.length).toBe(1); expect(tours[0].requests.length).toBe(1); @@ -76,7 +76,7 @@ describe('Concatenation tests', () => { connection2: null, capacities }; - await bookingApi(bookingBodyAppend, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBodyAppend, mockUserId, true, 0, 0, 0, 0, true); const tours2 = await getTours(); expect(tours2.length).toBe(1); expect(tours2[0].requests.length).toBe(2); diff --git a/src/lib/server/booking/tests/concatenations/connect.test.ts b/src/lib/server/booking/tests/concatenations/connect.test.ts index 2b883cbd8..aaaa43177 100644 --- a/src/lib/server/booking/tests/concatenations/connect.test.ts +++ b/src/lib/server/booking/tests/concatenations/connect.test.ts @@ -57,7 +57,7 @@ describe('Concatenation tests', () => { capacities }; - await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, false); + await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, 0, false); const tours = await getTours(); expect(tours.length).toBe(1); expect(tours[0].requests.length).toBe(1); @@ -94,7 +94,7 @@ describe('Concatenation tests', () => { connection2: null, capacities }; - await bookingApi(bookingBody2, mockUserId, true, 0, 0, 0, false); + await bookingApi(bookingBody2, mockUserId, true, 0, 0, 0, 0, false); const tours2 = await getTours(); expect(tours2.length).toBe(2); expect(tours2[0].requests.length).toBe(1); @@ -132,7 +132,7 @@ describe('Concatenation tests', () => { connection2: null, capacities }; - await bookingApi(bookingBodyConnect, mockUserId, true, 0, 0, 0, false); + await bookingApi(bookingBodyConnect, mockUserId, true, 0, 0, 0, 0, false); const tours3 = await getTours(); expect(tours3.length).toBe(1); expect(tours3[0].requests.length).toBe(3); diff --git a/src/lib/server/booking/tests/concatenations/inBetween2detour.test.ts b/src/lib/server/booking/tests/concatenations/inBetween2detour.test.ts index 3c76b3356..64eef2c7f 100644 --- a/src/lib/server/booking/tests/concatenations/inBetween2detour.test.ts +++ b/src/lib/server/booking/tests/concatenations/inBetween2detour.test.ts @@ -50,7 +50,7 @@ describe('Concatenation tests', () => { capacities }; - await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, 0, true); const tours = await getTours(); expect(tours.length).toBe(1); expect(tours[0].requests.length).toBe(1); @@ -78,7 +78,7 @@ describe('Concatenation tests', () => { connection2: null, capacities }; - await bookingApi(bookingBodyAppend, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBodyAppend, mockUserId, true, 0, 0, 0, 0, true); const tours2 = await getTours(); expect(tours2.length).toBe(1); expect(tours2[0].requests.length).toBe(2); diff --git a/src/lib/server/booking/tests/concatenations/prepend1.test.ts b/src/lib/server/booking/tests/concatenations/prepend1.test.ts index 20b02bbb0..19d3b727e 100644 --- a/src/lib/server/booking/tests/concatenations/prepend1.test.ts +++ b/src/lib/server/booking/tests/concatenations/prepend1.test.ts @@ -47,7 +47,7 @@ describe('Concatenation tests', () => { capacities }; - await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, 0, true); const tours = await getTours(); expect(tours.length).toBe(1); expect(tours[0].requests.length).toBe(1); @@ -76,7 +76,7 @@ describe('Concatenation tests', () => { connection2: null, capacities }; - await bookingApi(bookingBodyAppend, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBodyAppend, mockUserId, true, 0, 0, 0, 0, true); const tours2 = await getTours(); expect(tours2.length).toBe(1); expect(tours2[0].requests.length).toBe(2); diff --git a/src/lib/server/booking/tests/concatenations/prepend2.test.ts b/src/lib/server/booking/tests/concatenations/prepend2.test.ts index 94d1cdc1d..a284f34f5 100644 --- a/src/lib/server/booking/tests/concatenations/prepend2.test.ts +++ b/src/lib/server/booking/tests/concatenations/prepend2.test.ts @@ -48,7 +48,7 @@ describe('Concatenation tests', () => { capacities }; - await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, 0, true); const tours = await getTours(); expect(tours.length).toBe(1); expect(tours[0].requests.length).toBe(1); @@ -77,7 +77,7 @@ describe('Concatenation tests', () => { connection2: null, capacities }; - await bookingApi(bookingBodyAppend, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBodyAppend, mockUserId, true, 0, 0, 0, 0, true); const tours2 = await getTours(); expect(tours2.length).toBe(1); expect(tours2[0].requests.length).toBe(2); diff --git a/src/lib/server/booking/tests/concatenations/sameLocation.test.ts b/src/lib/server/booking/tests/concatenations/sameLocation.test.ts index b3dc0dfef..ce50de6ac 100644 --- a/src/lib/server/booking/tests/concatenations/sameLocation.test.ts +++ b/src/lib/server/booking/tests/concatenations/sameLocation.test.ts @@ -45,7 +45,7 @@ describe('Concatenation tests', () => { capacities }; - await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, 0, true); const tours = await getTours(); expect(tours.length).toBe(1); expect(tours[0].requests.length).toBe(1); @@ -74,7 +74,7 @@ describe('Concatenation tests', () => { connection2: null, capacities }; - await bookingApi(bookingBodyAppend, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBodyAppend, mockUserId, true, 0, 0, 0, 0, true); const tours2 = await getTours(); expect(tours2.length).toBe(1); expect(tours2[0].requests.length).toBe(2); @@ -103,7 +103,7 @@ describe('Concatenation tests', () => { connection2: null, capacities }; - await bookingApi(bookingBodyAppend2, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBodyAppend2, mockUserId, true, 0, 0, 0, 0, true); const tours3 = await getTours(); expect(tours3.length).toBe(1); expect(tours3[0].requests.length).toBe(3); diff --git a/src/lib/server/booking/tests/concatenations/threeSameLocations.test.ts b/src/lib/server/booking/tests/concatenations/threeSameLocations.test.ts index a291d47cf..7aae67029 100644 --- a/src/lib/server/booking/tests/concatenations/threeSameLocations.test.ts +++ b/src/lib/server/booking/tests/concatenations/threeSameLocations.test.ts @@ -45,7 +45,7 @@ describe('Concatenation tests', () => { connection2: null, capacities }; - await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, 0, true); const tours = await getTours(); expect(tours.length).toBe(1); expect(tours[0].requests.length).toBe(1); @@ -74,7 +74,7 @@ describe('Concatenation tests', () => { connection2: null, capacities }; - await bookingApi(bookingBodyAppend, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBodyAppend, mockUserId, true, 0, 0, 0, 0, true); const tours2 = await getTours(); expect(tours2.length).toBe(1); expect(tours2[0].requests.length).toBe(2); @@ -103,7 +103,7 @@ describe('Concatenation tests', () => { connection2: null, capacities }; - await bookingApi(bookingBodyAppend2, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBodyAppend2, mockUserId, true, 0, 0, 0, 0, true); const tours3 = await getTours(); expect(tours3.length).toBe(1); expect(tours3[0].requests.length).toBe(3); diff --git a/src/lib/server/booking/tests/generatedTests/gen.test.ts b/src/lib/server/booking/tests/generatedTests/gen.test.ts index 57531cbd8..20214928f 100644 --- a/src/lib/server/booking/tests/generatedTests/gen.test.ts +++ b/src/lib/server/booking/tests/generatedTests/gen.test.ts @@ -75,7 +75,7 @@ describe('Concatenation tests', () => { connection2: null, capacities: { passengers: 1, luggage: 0, wheelchairs: 0, bikes: 0 } }; - await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, true); + await bookingApi(bookingBody, mockUserId, true, 0, 0, 0, 0, true); const tours = await getTours(); for (const condition of test.conditions.filter((c) => c.evalAfterStep === requestIdx)) { try { diff --git a/src/lib/server/booking/tests/singleRequest/api.test.ts b/src/lib/server/booking/tests/singleRequest/api.test.ts index 11f08a5d3..9b4ba3a62 100644 --- a/src/lib/server/booking/tests/singleRequest/api.test.ts +++ b/src/lib/server/booking/tests/singleRequest/api.test.ts @@ -289,7 +289,7 @@ describe('Whitelist and Booking API Tests', () => { capacities }; - const bookingResponse = await bookingApi(bookingBody, mockUserId, false, 0, 0, 0); + const bookingResponse = await bookingApi(bookingBody, mockUserId, false, 0, 0, 0, 0); const tours = await getTours(); expect(tours.length).toBe(1); expect(tours[0].requests.length).toBe(1); @@ -358,7 +358,7 @@ describe('Whitelist and Booking API Tests', () => { capacities }; - await bookingApi(bookingBody, mockUserId, false, 0, 0, 0); + await bookingApi(bookingBody, mockUserId, false, 0, 0, 0, 0); const tours = await getTours(); expect(tours.length).toBe(1); }, 30000); @@ -405,7 +405,7 @@ describe('Whitelist and Booking API Tests', () => { connection2: null, capacities }; - const response = await bookingApi(bookingBody, mockUserId, false, 0, 0, 0); + const response = await bookingApi(bookingBody, mockUserId, false, 0, 0, 0, 0); const tours = await getTours(); expect(response.status === 403); expect(tours.length).toBe(0); diff --git a/src/lib/ui/BookingSummary.svelte b/src/lib/ui/BookingSummary.svelte index aeb13f7ed..44abbd09d 100644 --- a/src/lib/ui/BookingSummary.svelte +++ b/src/lib/ui/BookingSummary.svelte @@ -24,6 +24,8 @@ {getEuroString(price)} +
  • {t.booking.ptTicketNeeded}
  • +
  • {t.booking.bookingFor(passengers)}
  • {#if wheelchair} diff --git a/src/lib/util/odmPrice.ts b/src/lib/util/odmPrice.ts index 3f1c65a40..13bbcd141 100644 --- a/src/lib/util/odmPrice.ts +++ b/src/lib/util/odmPrice.ts @@ -3,10 +3,26 @@ import { env } from '$env/dynamic/public'; import type { Itinerary, Leg } from '$lib/openapi'; -export const odmPrice = (it: Itinerary, passengers: number, kids: number) => +export const legOdmPrice = ( + totalPassengers: number, + freePassengers: number, + reducedPassengers: number +) => + Math.abs( + (totalPassengers - freePassengers - reducedPassengers) * parseInt(env.PUBLIC_FIXED_PRICE) + + reducedPassengers * parseInt(env.PUBLIC_FIXED_REDUCED_PRICE) + ); + +export const odmPrice = ( + it: Itinerary, + totalPassengers: number, + freePassengers: number, + reducedPassengers: number +) => it.legs.reduce( (acc: number, l: Leg) => - acc + (l.mode === 'ODM' ? (passengers - kids) * parseInt(env.PUBLIC_FIXED_PRICE) : 0), + acc + + (l.mode === 'ODM' ? legOdmPrice(totalPassengers, freePassengers, reducedPassengers) : 0), 0 ); diff --git a/src/routes/(customer)/routing/+page.server.ts b/src/routes/(customer)/routing/+page.server.ts index df4bc16d9..4543c7790 100644 --- a/src/routes/(customer)/routing/+page.server.ts +++ b/src/routes/(customer)/routing/+page.server.ts @@ -47,6 +47,7 @@ export const actions = { const kidsZeroToTwoString = formData.get('kidsZeroToTwo'); const kidsThreeToFourString = formData.get('kidsThreeToFour'); const kidsFiveToSixString = formData.get('kidsFiveToSix'); + const kidsSevenToFourteenString = formData.get('kidsSevenToFourteen'); const startFixedString = formData.get('startFixed'); const json = formData.get('json'); @@ -58,6 +59,7 @@ export const actions = { typeof kidsZeroToTwoString !== 'string' || typeof kidsThreeToFourString !== 'string' || typeof kidsFiveToSixString !== 'string' || + typeof kidsSevenToFourteenString !== 'string' || typeof startFixedString !== 'string' ) { booking_errors?.inc(); @@ -69,6 +71,7 @@ export const actions = { const kidsZeroToTwo = readInt(kidsZeroToTwoString); const kidsThreeToFour = readInt(kidsThreeToFourString); const kidsFiveToSix = readInt(kidsFiveToSixString); + const kidsSevenToFourteen = readInt(kidsSevenToFourteenString); const startFixed = startFixedString === '1'; if ( @@ -78,6 +81,7 @@ export const actions = { isNaN(kidsZeroToTwo) || isNaN(kidsThreeToFour) || isNaN(kidsFiveToSix) || + isNaN(kidsSevenToFourteen) || (startFixedString !== '1' && startFixedString !== '0') ) { throw 'invalid booking params'; @@ -101,7 +105,8 @@ export const actions = { { capacities }, { kidsZeroToTwo }, { kidsThreeToFour }, - { kidsFiveToSix } + { kidsFiveToSix }, + { kidsSevenToFourteen } ); booking_errors?.inc(); return { msg: msg('unknownError') }; @@ -117,7 +122,8 @@ export const actions = { { capacities }, { kidsZeroToTwo }, { kidsThreeToFour }, - { kidsFiveToSix } + { kidsFiveToSix }, + { kidsSevenToFourteen } ); booking_errors?.inc(); return { msg: msg('unknownError') }; @@ -133,7 +139,8 @@ export const actions = { { capacities }, { kidsZeroToTwo }, { kidsThreeToFour }, - { kidsFiveToSix } + { kidsFiveToSix }, + { kidsSevenToFourteen } ); return { msg: msg('unknownError') }; } @@ -174,7 +181,8 @@ export const actions = { false, kidsZeroToTwo, kidsThreeToFour, - kidsFiveToSix + kidsFiveToSix, + kidsSevenToFourteen ); if (bookingResult.status !== 200) { console.log( diff --git a/src/routes/(customer)/routing/+page.svelte b/src/routes/(customer)/routing/+page.svelte index c1c455bab..b2f7b53ad 100644 --- a/src/routes/(customer)/routing/+page.svelte +++ b/src/routes/(customer)/routing/+page.svelte @@ -34,7 +34,7 @@ import Switch from '$lib/shadcn/switch/switch.svelte'; import { cn } from '$lib/shadcn/utils'; import { updateStartDest } from '$lib/util/updateStartDest'; - import { odmPrice } from '$lib/util/odmPrice'; + import { getEuroString, legOdmPrice, odmPrice } from '$lib/util/odmPrice'; import BookingSummary from '$lib/ui/BookingSummary.svelte'; import { HelpCircleIcon, LocateFixed, MapIcon } from 'lucide-svelte'; import { posToLocation } from '$lib/map/Location'; @@ -54,11 +54,23 @@ let kidsZeroToTwo = $state(0); let kidsThreeToFour = $state(0); let kidsFiveToSix = $state(0); - let maxKidsZeroToTwo = $derived(passengers - 1 - kidsThreeToFour - kidsFiveToSix); - let maxKidsThreeToFour = $derived(passengers - 1 - kidsZeroToTwo - kidsFiveToSix); - let maxKidsFiveToSix = $derived(passengers - 1 - kidsZeroToTwo - kidsThreeToFour); - let minimumPassengers = $derived(1 + kidsZeroToTwo + kidsThreeToFour + kidsFiveToSix); - let kids = $derived(kidsZeroToTwo + kidsThreeToFour + kidsFiveToSix); + let kidsSevenToFourteen = $state(0); + let maxKidsZeroToTwo = $derived( + Math.max(0, passengers - 1 - kidsThreeToFour - kidsFiveToSix - kidsSevenToFourteen) + ); + let maxKidsThreeToFour = $derived( + Math.max(0, passengers - 1 - kidsZeroToTwo - kidsFiveToSix - kidsSevenToFourteen) + ); + let maxKidsFiveToSix = $derived( + Math.max(0, passengers - 1 - kidsZeroToTwo - kidsThreeToFour - kidsSevenToFourteen) + ); + let maxKidsSevenToFourteen = $derived( + Math.max(0, passengers - kidsZeroToTwo - kidsThreeToFour - kidsFiveToSix) + ); + let minimumPassengers = $derived( + 1 + kidsZeroToTwo + kidsThreeToFour + kidsFiveToSix + Math.max(0, kidsSevenToFourteen - 1) + ); + let freeKids = $derived(kidsZeroToTwo + kidsThreeToFour + kidsFiveToSix); let wheelchair = $state(false); let luggage = $state('none'); let time = $state(new Date(urlParams?.get('time') || Date.now())); @@ -203,6 +215,11 @@ from = posToLocation({ lat: position.coords.latitude, lon: position.coords.longitude }, 0); }; + /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ + const reportValidity = (e: any) => { + e.target.reportValidity(); + }; + let loading = $state(false); @@ -250,7 +267,12 @@ {passengers} {wheelchair} luggage={luggageToInt(luggage)} - price={odmPrice(page.state.selectedItinerary, passengers, kids)} + price={odmPrice( + page.state.selectedItinerary, + passengers, + freeKids, + kidsSevenToFourteen + )} />

    {t.booking.disclaimer}

    @@ -278,6 +300,7 @@ + -
    - - - +
    + + + - + - + - + + + -
    @@ -498,7 +554,8 @@ {baseResponse} {routingResponses} {passengers} - {kids} + freePassengers={freeKids} + reducedPassengers={kidsSevenToFourteen} selectItinerary={(selectedItinerary) => { goto('?detail', { state: { selectedItinerary } }); }} @@ -506,7 +563,11 @@ />
    -

    {t.fare}
    3€ {t.perPerson} {t.perRide}

    +

    + {t.fare}
    {getEuroString(legOdmPrice(1, 0, 0))} + {t.perPerson} + {t.perRide} +

    {t.bookingDeadline}
    {t.bookingDeadlineContent}