import { PackagingEntryLine, PackagingEntryPax, BookingPackagePax, PackagingEntry, BookingPackageRequestRoom, PackagingRoom, PackagingTraveller } from '@qite/tide-client'; import { range } from 'lodash'; export const GROUP_TOUR_SERVICE_TYPE = 1; export const ACCOMMODATION_SERVICE_TYPE = 3; export const EXCURSION_SERVICE_TYPE = 4; export const FLIGHT_SERVICE_TYPE = 7; export const toDateOnlyString = (value: string | Date): string => { const date = value instanceof Date ? value : new Date(value); return date.toISOString().split('T')[0]; }; const getAgeAtReferenceDate = (dateOfBirth: string | Date, referenceDate: string | Date): number => { const dob = dateOfBirth instanceof Date ? dateOfBirth : new Date(dateOfBirth); const ref = referenceDate instanceof Date ? referenceDate : new Date(referenceDate); let age = ref.getFullYear() - dob.getFullYear(); const monthDiff = ref.getMonth() - dob.getMonth(); if (monthDiff < 0 || (monthDiff === 0 && ref.getDate() < dob.getDate())) { age--; } return age; }; export const getPrimaryAccommodationLine = (lines: PackagingEntryLine[]): PackagingEntryLine | undefined => { return [...lines] .filter((line) => line.serviceType === ACCOMMODATION_SERVICE_TYPE) .sort((a, b) => new Date(a.from).getTime() - new Date(b.from).getTime())[0]; }; const getFlightLines = (lines: PackagingEntryLine[]): PackagingEntryLine[] => { return [...lines].filter((line) => line.serviceType === FLIGHT_SERVICE_TYPE).sort((a, b) => new Date(a.from).getTime() - new Date(b.from).getTime()); }; export const getDepartureAirportFromEntry = (lines: PackagingEntryLine[]): string | null => { const firstFlight = getFlightLines(lines)[0]; const firstSegment = firstFlight?.flightInformation?.flightLines?.[0]; return firstSegment?.departureAirportCode ?? null; }; export const getDestinationAirportFromEntry = (lines: PackagingEntryLine[]): string | null => { const outboundFlight = getFlightLines(lines)[0]; const flightSegments = outboundFlight?.flightInformation?.flightLines; if (!flightSegments?.length) return null; return flightSegments[flightSegments.length - 1]?.arrivalAirportCode ?? null; }; const mapPackagingPaxToBookingPax = (pax: PackagingEntryPax | undefined, fallbackId: number, referenceDate: string): BookingPackagePax => ({ id: pax?.id ?? fallbackId, guid: pax?.id?.toString() ?? fallbackId.toString(), firstName: pax?.firstName ?? '', lastName: pax?.lastName ?? '', dateOfBirth: pax?.dateOfBirth ?? undefined, age: pax?.dateOfBirth ? getAgeAtReferenceDate(pax.dateOfBirth, referenceDate) : undefined, isMainBooker: pax?.isMainBooker, email: '' }); export const getRequestRoomsFromPackagingEntry = (entry: PackagingEntry): BookingPackageRequestRoom[] => { const accommodationLines = (entry.lines ?? []).filter((line) => line.serviceType === ACCOMMODATION_SERVICE_TYPE && line.pax?.length > 0); const paxById = new Map((entry.pax ?? []).map((p) => [p.id, p])); if (!accommodationLines.length) { return [ { index: 0, pax: (entry.pax ?? []).map((p) => mapPackagingPaxToBookingPax(p, p.id, new Date().toISOString())) } ]; } const roomGroups: BookingPackagePax[][] = []; accommodationLines.forEach((line) => { const groupedByRoom = new Map(); line.pax.forEach((linePax) => { const roomIndexWithinLine = Number(linePax.room ?? 0); const paxId = Number(linePax.paxId); const pax = mapPackagingPaxToBookingPax(paxById.get(paxId), paxId, line.from); if (!groupedByRoom.has(roomIndexWithinLine)) { groupedByRoom.set(roomIndexWithinLine, []); } groupedByRoom.get(roomIndexWithinLine)!.push(pax); }); const sortedGroups = Array.from(groupedByRoom.entries()) .sort(([a], [b]) => a - b) .map(([, pax]) => pax); roomGroups.push(...sortedGroups); }); if (!roomGroups.length) { return [ { index: 0, pax: (entry.pax ?? []).map((p) => mapPackagingPaxToBookingPax(p, p.id, accommodationLines[0].from)) } ]; } return roomGroups.map((pax, index) => ({ index, pax })); }; export const parseHotelId = (line?: PackagingEntryLine): number | null => { if (!line?.productCode) return null; const parsed = Number(line.productCode); return Number.isNaN(parsed) ? null : parsed; }; export const getPackagingRequestRoomsFromBookingRooms = (rooms: BookingPackageRequestRoom[] | null) => { if (!rooms?.length) { const room = { index: 0, travellers: [] } as PackagingRoom; range(0, 2).forEach(() => { room.travellers.push({ age: 30 } as PackagingTraveller); }); return [room]; } return rooms.map((x, i) => { const room = { index: x.index ?? i, travellers: [] } as PackagingRoom; x.pax.forEach((p) => { room.travellers.push({ age: p.age ?? 30 } as PackagingTraveller); }); return room; }); };