{"version":3,"names":["ADJACENT_MINI_CABIN_PLACE_ALIGNMENT","OPEN_PLAN_COACH_PREFIX","WHEELCHAIR_COUCHETTE_DANI","PRIORITY_SEAT_SEVERELY_DISABLED_PASSENGER","journeyData","reservationMode","JourneyStore","getInstance","instances","has","set","get","constructor","mode","this","njOffer","njAccommodation","njProduct","additionalRequest","additionalOffer","additionalProduct","readFromSession","isEmpty","replaceData","dataStore","getSessionData","_b","_a","connection","departure","asOffsetTime","_d","_c","arrival","_f","_e","_h","_g","storeInSession","removeSessionData","setSessionData","triggerPrebookPrepare","preparePrebookRequestBody","triggerEvent","name","window","dispatchEvent","CustomEvent","detail","data","clearAll","setNjOffer","offer","accommodation","setNjProduct","product","setAdditionalRequest","request","clearAdditionalRequest","setFinalOffer","clearFinalOffer","isChosenNjConnection","from","dep_dt","train","isChosenAdditionalConnection","sectionsListEqual","sections","hasSelectedOffer","hasSelectedProduct","getNjOffer","getNjAccommodation","getNjProduct","getAdditionalRequest","getAdditionalOffer","getFinalOffer","getFinalProduct","price","Map","ProductKey","ProductType","DayProductType","njProductTitles","nonFlexibleProductNames","semiFlexibleProductNames","flexibleProductNames","isNJProduct","find","title","toLowerCase","includes","getProductKey","type","NonFlexible","Sparschiene","SemiFlexible","Komfortticket","Flexible","Standardticket","getProductType","getProductTypeForName","de","split","map","nameLower","item","getDayProductType","prodGroupLabels","Unknown","NonRefundable","Refundable","Standard","console","warn","getCombinedProductType","njIndex","resultType","resultIndex","productDetails","isSectionInScopes","scope","productType","productIndex","getDayProductTypeIndex","getProductNameKey","replace","translateProductDetailName","i18n","getMessage","translateProductName","key","getProductInfo","translateAccommodationType","accommodationType","getProductCancellation","departureDate","getCancellationForType","SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_FULL_REFUND","SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_PARTIAL_REFUND","SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_NO_REFUND","today","now","daysUntilDeparture","diff","getCancellationDate","getCancellationLabelForType","daysBeforeDeparture","formatNumericDate","subtract","ADDITIONAL_INFORMATION_DIALOGUES","AccommodationType","Se","rootUrl","getLang","Le","Be","ADDITIONAL_INFORMATION_DIALOGUE_EURO_NIGHT","SelectedClasses","isSupportedOffer","offerName","offerNameLowerCased","isSupportedCompartment","compartment","special","externalIdentifier","calculateSelectableCompartmentPricesForOffer","reservationKey","compartmentPrices","reservationSegement","reservation","reservationSegments","compartments","basePrice","privateVariations","privateVariation","surchargePrice","push","calculateSelectableCompartmentPricesForOffers","offers","offerPrices","i","length","selectCompartment","selectedInternalProduct","JSON","parse","stringify","selected","ticket","reservationSegementsLoop","id","compartmentId","accommodationClass","class2","selectedReservationKey","charAt","toUpperCase","slice","count","privateVariationCount","spotLocations","spotLocation","spotLocationSelected","spotLocationsSelected","value","param","placeAlignment","orders","paymentInformationPrice","ReservationMode","Outward","Return","store","finalProduct","offerData","prebookOffers","filter","buildPrebookData","maxTrainChanges","objects","rfpIndex","Math","round","requestBody","paymentInformation","amount","paymentMethod","email","DATA_STORE_KEY_PREBOOK","Event","removeJourney","returnData","returnDataValue","DATA_STORE_KEY_RETURN_VALUE","DATA_STORE_KEY_OUTWARD_VALUE","mapThirdGender","prebookData","order","object","gender","isBusinessClass","priceClass","hasPriceClass","getLowerPriceClass","getPriceClassKey","getCompartmentsForClass","segment","lowerPriceClass","getPriceForClass","priceKey","undefined","getMatchingPriceClass","translatePriceClassName","getStopsForScopes","scopes","getStopsForScope","getStopAtIndex","sectionIndex","stopIndex","passlist","getTrainsForScopes","trains","getSectionTrainName","category","getSectionTrainCategory","some","isSectionInScope","getOfferParts","excludedIndex","details","sort","a","b","min","obj","index","getOfferName","val","self","indexOf","join","getAttribute","section","attributes","att","attributeType","toString","trim","svalue","getTrainCategoryForName","match","getSectionTrainDirection","sectionsEqual","departureTimestamp","arrivalTimestamp","getCompartmentById","identifier","getCompartmentPrice","variation","reduce","getOfferPrice","priceClassKey","translateCompartmentName","buildAdditionalOptions","minPrice","segments","segmentIndex","entries","surcharge","minSurcharge","localeCompare","result","selectedClass","forEach","compartmentData","groupTicketDetailsByScope","tickets","groupedTickets","ticketDetails","flat","passengerType","passenger","isReservation","createInitialGroup","updateGroup","ticketsCount","sum","passangerType","passengers","passengerIndex","ticketPrice","groupedTicketDetails","getTicketDetailsFromPrebook","globallyPriced","productPriceClass","allocations","allocation","getProductDetailsForScope","freeFollowupReservationApplied","productScope","doesPassengerRequireWheelchair","DATA_STORE_KEY_PASSENGERS","accessibilityOptions","njChallengedOptions","wheelchair","hasWheelchairCompartment"],"sources":["src/components/nj-offer-list/OfferListConstants.ts","src/global/JourneyStore.ts","src/utils/products.ts","src/components/nj-reservation/nj-reservation-utils.ts","src/utils/price-class.ts","src/utils/offers.ts"],"sourcesContent":["export const ADJACENT_MINI_CABIN_PLACE_ALIGNMENT = \"SIDE_BY_SIDE\";\n\nexport const OPEN_PLAN_COACH_PREFIX = \"centralGangwayCoach\";\nexport const WHEELCHAIR_COUCHETTE_DANI = \"wheelchairCouchette\";\nexport const PRIORITY_SEAT_SEVERELY_DISABLED_PASSENGER = \"serverlyDisabledPerson\";\n","import {Dayjs} from \"dayjs\";\n\nimport {ApiProduct, ConnectionWithOffersV6, ReservationCompartment} from \"../api/Ticketshop\";\nimport {AccommodationType} from \"../components/nj-connection/AccommodationType\";\nimport {preparePrebookRequestBody} from \"../components/nj-reservation/nj-reservation-utils\";\nimport {ReservationMode} from \"../components/nj-reservation/ReservationMode\";\n\nimport {asOffsetTime} from \"../utils/date\";\nimport {sectionsListEqual} from \"../utils/offers\";\nimport {PriceClass} from \"../utils/price-class\";\nimport {ProductType} from \"../utils/products\";\nimport {dataStore} from \"./DataStore\";\n\nexport interface NjOfferData {\n connection: NjConnectionData;\n offer: ConnectionWithOffersV6;\n}\n\nexport interface NjConnectionData {\n train: string;\n\ttrainCount?: number;\n\n from: NjFromStationData;\n to: NjToStationData;\n\n dani?: boolean;\n seatAsIC?: boolean;\n\tseatAsICText?: string;\n\n departure: Dayjs;\n arrival: Dayjs;\n duration_fmt?: string;\n}\n\nexport interface NjStationData {\n name: string;\n number: string;\n}\n\nexport interface NjToStationData extends NjStationData {\n arr_date: string;\n arr_dt: number;\n arr_time: string;\n}\n\nexport interface NjFromStationData extends NjStationData {\n dep_date: string;\n dep_dt: number;\n dep_time: string;\n}\n\nexport interface NjProductData {\n ticket: string,\n id: string,\n offer: any,\n reservationMode: ReservationMode,\n price: number,\n spotLocationsSelected: any[],\n spotLocationsAll: any,\n productType: ProductType,\n apiProduct: ApiProduct,\n compartment: ReservationCompartment,\n privateVariationCount: number,\n}\n\nexport interface AdditionalProductData {\n njIndex: number;\n price: number;\n priceClass: PriceClass;\n offer: ApiProduct,\n compartments: ProductCompartmentData[];\n}\n\nexport interface FinalProductData {\n njProduct: NjProductData;\n additionalProduct?: AdditionalProductData;\n price: number;\n}\n\nexport interface ProductCompartmentData {\n segmentIndex: number;\n identifier: string;\n spotLocation?: string;\n privateVariationCount?: number;\n}\n\nexport interface AdditionalRequest {\n finalFrom: any;\n finalTo: any;\n}\n\nexport interface JourneyStoreEvent extends CustomEvent<JourneyStoreEventData> {\n}\n\nexport interface JourneyStoreEventData {\n reservationMode: ReservationMode;\n}\n\n\nexport function journeyData(reservationMode: ReservationMode): JourneyStore {\n return JourneyStore.getInstance(reservationMode);\n}\n\nexport class JourneyStore {\n\n private static readonly instances = new Map<ReservationMode, JourneyStore>();\n\n static getInstance(reservationMode: ReservationMode): JourneyStore {\n if (!JourneyStore.instances.has(reservationMode)) {\n JourneyStore.instances.set(reservationMode, new JourneyStore(reservationMode));\n }\n return JourneyStore.instances.get(reservationMode);\n }\n\n private readonly reservationMode: ReservationMode;\n\n private njOffer: NjOfferData | null = null;\n private njAccommodation: AccommodationType | null = null;\n private njProduct: NjProductData | null = null;\n\n private additionalRequest: AdditionalRequest | null = null;\n private additionalOffer: NjOfferData | null = null;\n private additionalProduct: AdditionalProductData | null = null;\n\n private constructor(mode: ReservationMode) {\n this.reservationMode = mode;\n this.readFromSession();\n }\n\n private isEmpty(): boolean {\n return !this.njOffer && !this.njAccommodation && !this.njProduct\n && !this.additionalRequest && !this.additionalOffer && !this.additionalProduct;\n }\n\n private readFromSession() {\n this.replaceData(dataStore().getSessionData(this.reservationMode));\n\t\tif (this.njOffer?.connection?.departure) {\n\t\t\tthis.njOffer.connection.departure = asOffsetTime(this.njOffer.connection.departure);\n\t\t}\n\t\tif (this.njOffer?.connection?.arrival) {\n\t\t\tthis.njOffer.connection.arrival = asOffsetTime(this.njOffer.connection.arrival);\n\t\t}\n\t\tif (this.additionalOffer?.connection?.departure) {\n\t\t\tthis.additionalOffer.connection.departure = asOffsetTime(this.additionalOffer.connection.departure);\n\t\t}\n\t\tif (this.additionalOffer?.connection?.arrival) {\n\t\t\tthis.additionalOffer.connection.arrival = asOffsetTime(this.additionalOffer.connection.arrival);\n\t\t}\n }\n\n private storeInSession() {\n if (this.isEmpty()) {\n dataStore().removeSessionData(this.reservationMode);\n } else {\n dataStore().setSessionData(this.reservationMode, this);\n }\n }\n\n private triggerPrebookPrepare() {\n preparePrebookRequestBody();\n }\n\n private triggerEvent(name: string) {\n window.dispatchEvent(new CustomEvent<JourneyStoreEventData>(name, {detail: {reservationMode: this.reservationMode}}));\n }\n\n replaceData(data: JourneyStore) {\n this.njOffer = data?.njOffer || null;\n this.njAccommodation = data?.njAccommodation || null;\n this.njProduct = data?.njProduct || null;\n\n this.additionalRequest = data?.additionalRequest || null;\n this.additionalOffer = data?.additionalOffer || null;\n this.additionalProduct = data?.additionalProduct || null;\n\n this.storeInSession();\n }\n\n clearAll() {\n this.njOffer = null;\n this.njAccommodation = null;\n this.njProduct = null;\n\n this.additionalRequest = null;\n this.additionalOffer = null;\n this.additionalProduct = null;\n\n this.storeInSession();\n }\n\n setNjOffer(connection: NjConnectionData, offer: ConnectionWithOffersV6, accommodation: AccommodationType) {\n // Update the connection\n this.njOffer = {connection, offer};\n this.njAccommodation = accommodation;\n\n // Invalidate the product and additional connection\n this.njProduct = null;\n this.additionalOffer = null;\n this.additionalProduct = null;\n\n // Store and trigger events\n this.storeInSession();\n this.triggerPrebookPrepare();\n this.triggerEvent('njConnectionSelected');\n }\n\n setNjProduct(product: NjProductData, accommodation?: AccommodationType) {\n // Update the data and optionally the accommodation\n this.njProduct = product;\n if (accommodation) {\n this.njAccommodation = accommodation;\n }\n\n // Invalidate the additional product\n this.additionalProduct = null;\n\n // Store and trigger events\n this.triggerPrebookPrepare();\n this.triggerEvent('productSelected');\n this.storeInSession();\n }\n\n setAdditionalRequest(request: AdditionalRequest) {\n this.additionalRequest = request;\n\n // Store and trigger events\n this.storeInSession();\n this.triggerEvent('njAdditionalRequestUpdated');\n }\n\n clearAdditionalRequest() {\n // Remove the request data and all selections\n this.additionalRequest = null;\n this.additionalOffer = null;\n this.additionalProduct = null;\n\n // Store and trigger events\n this.storeInSession();\n this.triggerPrebookPrepare();\n this.triggerEvent('njAdditionalRequestUpdated');\n }\n\n setFinalOffer(connection: NjConnectionData, offer: ConnectionWithOffersV6, product: AdditionalProductData) {\n this.additionalOffer = {connection, offer};\n this.additionalProduct = product;\n\n // Store and trigger events\n this.storeInSession();\n this.triggerPrebookPrepare();\n this.triggerEvent('njAdditionalSelected');\n }\n\n clearFinalOffer() {\n this.additionalOffer = null;\n this.additionalProduct = null;\n\n // Store and trigger events\n this.storeInSession();\n this.triggerPrebookPrepare();\n this.triggerEvent('njAdditionalSelected');\n }\n\n isChosenNjConnection(data: NjConnectionData): boolean {\n return this.njOffer && this.njOffer.connection.from.dep_dt === data.from.dep_dt && this.njOffer.connection.train === data.train;\n }\n\n isChosenAdditionalConnection(data: ConnectionWithOffersV6): boolean {\n // TODO Should we also consider offer prices here?\n return this.additionalOffer && sectionsListEqual(this.additionalOffer.offer.sections, data.sections);\n }\n\n hasSelectedOffer(): boolean {\n return !!this.njOffer;\n }\n\n hasSelectedProduct(): boolean {\n return !!this.njProduct;\n }\n\n getNjOffer(): NjOfferData | null {\n return this.njOffer;\n }\n\n getNjAccommodation(): AccommodationType | null {\n return this.njAccommodation;\n }\n\n getNjProduct(): NjProductData | null {\n return this.njProduct;\n }\n\n getAdditionalRequest(): AdditionalRequest | null {\n return this.additionalRequest;\n }\n\n getAdditionalOffer(): NjOfferData | null {\n // The final offer is the additional offer if an additional product was selected, otherwise the direct NJ offer only\n return this.additionalOffer;\n }\n\n getFinalOffer(): NjOfferData | null {\n // The final offer is the additional offer if an additional product was selected, otherwise the direct NJ offer only\n return this.additionalProduct ? this.additionalOffer : this.njOffer;\n }\n\n getFinalProduct(): FinalProductData | null {\n if (!this.njProduct) {\n // No NJ product means no product at all\n return null;\n }\n\n return {\n njProduct: this.njProduct,\n additionalProduct: this.additionalProduct,\n price: this.additionalProduct ? this.additionalProduct.price : this.njProduct.price,\n };\n }\n}\n","import {Dayjs} from \"dayjs\";\n\nimport {ApiProduct, MultilangText, ProductDetail} from \"../api/Ticketshop\";\nimport {formatNumericDate, now} from \"./date\";\nimport {i18n} from \"./I18n\";\nimport {isSectionInScopes} from \"./offers\";\n\nexport enum ProductKey {\n\tSparschiene = 'Sparschiene',\n\tKomfortticket = 'Komfortticket',\n\tStandardticket = 'Standardticket',\n}\n\nexport enum ProductType {\n NonFlexible = 'NonFlexible',\n SemiFlexible = 'SemiFlexible',\n Flexible = 'Flexible',\n Bike = 'Bike',\n}\n\nexport enum DayProductType {\n Standard = 'Standard',\n Refundable = 'Refundable',\n NonRefundable = 'NonRefundable',\n Unknown = 'Unknown',\n}\n\nconst njProductTitles = ['nachtverkehr']\nconst nonFlexibleProductNames = ['sparschiene', 'non flexible ticket', 'super saver ticket'];\nconst semiFlexibleProductNames = ['komfortticket', 'sparschiene komfort', 'reservierung/zuschlag'];\nconst flexibleProductNames = ['standardticket', 'standard-ticket', 'flexible ticket', 'standard ticket'];\n// const bikeProductNames = ['fahrradticket'];\n\nexport function isNJProduct(product: ProductDetail): boolean {\n return !!njProductTitles.find(title => product.title.toLowerCase().includes(title));\n}\n\nexport function getProductKey(type: ProductType): ProductKey {\n\tswitch (type) {\n\t\tcase ProductType.NonFlexible:\n\t\t\treturn ProductKey.Sparschiene;\n\t\tcase ProductType.SemiFlexible:\n\t\t\treturn ProductKey.Komfortticket;\n\t\tcase ProductType.Flexible:\n\t\t\treturn ProductKey.Standardticket;\n\t}\n}\n\nexport function getProductType(product: ProductDetail): ProductType | null {\n return isNJProduct(product) ? getProductTypeForName(product.name.de) : null;\n}\n\nexport function getProductTypeForName(name: string): ProductType {\n if (!name) {\n return null;\n }\n\n\tif (name.includes(' + ')) {\n\t\treturn name.split(' + ').map(getProductTypeForName).find(type => !!type);\n\t}\n\n const nameLower = name.toLowerCase();\n\n // if (bikeProductNames.find(item => nameLower.includes(item))) {\n // return ProductType.Bike;\n // }\n\n if (semiFlexibleProductNames.find(item => nameLower.includes(item))) {\n return ProductType.SemiFlexible;\n }\n\n if (nonFlexibleProductNames.find(item => nameLower.includes(item))) {\n return ProductType.NonFlexible;\n }\n\n if (flexibleProductNames.find(item => nameLower.includes(item))) {\n return ProductType.Flexible;\n }\n}\n\nexport function getDayProductType(product: ProductDetail): DayProductType {\n if (!product.prodGroupLabels) {\n return DayProductType.Unknown;\n }\n\n if (product.prodGroupLabels.includes('Kein Storno')) {\n return DayProductType.NonRefundable;\n }\n\n if (product.prodGroupLabels.includes('Zugbindung')) {\n return DayProductType.Refundable;\n }\n\n if (product.prodGroupLabels.includes('Vollstorno') &&\n (product.prodGroupLabels.includes('Keine Bindung') || product.prodGroupLabels.includes('Zeitbindung'))) {\n return DayProductType.Standard;\n }\n\n console.warn('Unknown product type for labels ' + product.prodGroupLabels);\n return DayProductType.Unknown;\n}\n\nexport function getCombinedProductType(offer: ApiProduct, njIndex: number): DayProductType {\n let resultType = null;\n let resultIndex = 0;\n\n for (const product of offer.productDetails) {\n if (isSectionInScopes(product.scope, njIndex)) {\n // Ignore ticket for the NJ\n continue;\n }\n\n const productType = getDayProductType(product);\n const productIndex = getDayProductTypeIndex(productType);\n if (productIndex > resultIndex) {\n resultType = productType;\n resultIndex = productIndex;\n }\n }\n\n return resultType;\n}\n\nexport function getDayProductTypeIndex(productType?: DayProductType): number {\n switch (productType) {\n case DayProductType.Unknown:\n return 1;\n case DayProductType.Standard:\n return 2;\n case DayProductType.Refundable:\n return 3;\n case DayProductType.NonRefundable:\n return 4;\n default:\n return 0;\n }\n}\n\nexport function getProductNameKey(name: MultilangText): string | null {\n // Product key is just the german name without whitespace and punctuation\n return name.de?.replace(/[^a-z\\d]/gi, '');\n}\n\nexport function translateProductDetailName(product: ProductDetail): string {\n const type = getProductType(product);\n if (type) {\n return i18n.getMessage(`ticket-type.${type}`);\n }\n\n return translateProductName(product.name);\n}\n\nexport function translateProductName(name: MultilangText): string {\n const key = getProductNameKey(name);\n return i18n.getMessage(`ts.product.name.${key}`, '', null, name);\n}\n\nexport function getProductInfo(product: ProductDetail) {\n const key = getProductNameKey(product.name);\n return i18n.getMessage(`ts.product.info.${key}`);\n}\n\nexport function translateAccommodationType(accommodationType: string): string | null {\n return ['SE', 'LE', 'BE'].includes(accommodationType)\n ? i18n.getMessage(`ts.accommodation.${accommodationType}`)\n : null;\n}\n\nexport function getProductCancellation(product: ProductDetail, departureDate: Dayjs): string | null {\n const type = getProductType(product);\n return getCancellationForType(type, departureDate) || getProductInfo(product);\n}\n\nconst SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_FULL_REFUND = 15;\nconst SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_PARTIAL_REFUND = 14;\nconst SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_NO_REFUND = 1;\n\nexport function getCancellationForType(type: ProductType, departureDate: Dayjs): string | null {\n switch (type) {\n case ProductType.NonFlexible:\n return i18n.getMessage(\"ticket-type.NonFlexible.cancellation\");\n case ProductType.SemiFlexible:\n\t\t\tconst today = now();\n\t\t\tconst daysUntilDeparture = departureDate.diff(today, \"days\");\n\t\t\tif (daysUntilDeparture >= SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_FULL_REFUND) {\n\t\t\t\treturn i18n.getMessage(\"ticket-type.SemiFlexible.cancellation\", \"\", [\n\t\t\t\t\tgetCancellationDate(SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_FULL_REFUND, departureDate),\n\t\t\t\t\tgetCancellationDate(SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_PARTIAL_REFUND, departureDate),\n\t\t\t\t\tgetCancellationDate(SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_NO_REFUND, departureDate),\n\t\t\t\t]);\n\t\t\t} else if (daysUntilDeparture === SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_NO_REFUND) {\n\t\t\t\treturn i18n.getMessage(\"ticket-type.SemiFlexible.cancellation.partial-only-last-day\", \"\", [\n\t\t\t\t\tgetCancellationDate(daysUntilDeparture, departureDate)\n\t\t\t\t]);\n\t\t\t} else if (daysUntilDeparture >= SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_NO_REFUND) {\n\t\t\t\treturn i18n.getMessage(\"ticket-type.SemiFlexible.cancellation.partial-only\", \"\", [\n\t\t\t\t\tgetCancellationDate(daysUntilDeparture, departureDate),\n\t\t\t\t\tgetCancellationDate(SEMI_FLEXIBLE_TICKET_DATE_DIFFERENCE_NO_REFUND, departureDate),\n\t\t\t\t]);\n\t\t\t} else {\n\t\t\t\treturn i18n.getMessage(\"ticket-type.SemiFlexible.cancellation.cancellation-deadline-expired\");\n\t\t\t}\n case ProductType.Flexible:\n return i18n.getMessage(\"ticket-type.Flexible.cancellation\");\n }\n}\n\nexport function getCancellationLabelForType(type: ProductType): string | null {\n switch (type) {\n case ProductType.NonFlexible:\n return i18n.getMessage('ticket-type.NonFlexible.cancellation.label');\n case ProductType.SemiFlexible:\n return i18n.getMessage('ticket-type.SemiFlexible.cancellation.label');\n case ProductType.Flexible:\n return i18n.getMessage('ticket-type.Flexible.cancellation.label');\n }\n}\n\nfunction getCancellationDate(daysBeforeDeparture: number, departureDate: Dayjs) {\n return formatNumericDate(departureDate.subtract(daysBeforeDeparture, \"days\"));\n}\n","import {\n\tApiProduct,\n\tConnectionFilter,\n\tPrebookApiProduct,\n\tPrebookOrderV4,\n\tPrebookReservationCompartmentV3,\n\tPrebookV4Request,\n\tReservationCompartment\n} from '../../api/Ticketshop';\nimport {DATA_STORE_KEY_OUTWARD_VALUE, DATA_STORE_KEY_PREBOOK, DATA_STORE_KEY_RETURN_VALUE, dataStore} from '../../global/DataStore';\nimport {journeyData} from \"../../global/JourneyStore\";\nimport {buildPrebookData} from \"../../utils/offers\";\nimport { AccommodationType } from '../nj-connection/AccommodationType';\nimport { ReservationMode } from './ReservationMode';\nimport {rootUrl} from \"../../helpers/utils\";\nimport {i18n} from \"../../utils/I18n\";\nimport {getProductKey, getProductTypeForName} from \"../../utils/products\";\n\nexport const ADDITIONAL_INFORMATION_DIALOGUES = {\n\t[AccommodationType.Se]: `${rootUrl()}/${i18n.getLang()}/komfortkategorien/sitzwagen-buchungstool`,\n\t[AccommodationType.Le]: `${rootUrl()}/${i18n.getLang()}/komfortkategorien/liegewagen-buchungstool`,\n\t[AccommodationType.Be]: `${rootUrl()}/${i18n.getLang()}/komfortkategorien/schlafwagen-buchungstool`,\n};\nexport const ADDITIONAL_INFORMATION_DIALOGUE_EURO_NIGHT = `${rootUrl()}/${i18n.getLang()}/komfortkategorien/euronight-buchungstool`;\n\nenum SelectedClasses {\n class1 = 'class1',\n class2 = 'class2',\n classBusiness = 'classBusiness',\n // noclass = 'noclass',\n}\n\n/**\n * Check if the offer is a combined offer which we do not support.\n *\n * A combined offer can arise, if two adults and two children travel\n * and the cheapest price whould be two Sparschiene and two Komforttickets.\n * However a combined offer with Bikes is ok for us.\n * Is there a better way to filter combined offers?\n */\nexport function isSupportedOffer(offerName: string) {\n const offerNameLowerCased = offerName.toLowerCase();\n\n // Unsupported offers by name\n if (offerNameLowerCased.includes('super ticket')) return false;\n if (offerNameLowerCased.includes('sparschiene') && offerNameLowerCased.includes('komfortticket')) return false;\n\n // If the offer is not skipped by the name, check if it is not a combined offer, should mean, we support it.\n if (!offerNameLowerCased.includes(' + ')) return true;\n\n // \"Fahrradticket\" may include \" + \" in name, but we support it\n if (offerNameLowerCased.includes('Fahrradticket')) return true;\n\n return true;\n}\n\nexport function isSupportedCompartment(compartment: ReservationCompartment|PrebookReservationCompartmentV3) {\n if (!compartment.special) return true;\n\n // Skip compartments only for bikes, we have them in the other offers included\n if (compartment.externalIdentifier === 'bicycle') return false;\n\n return true;\n}\n\n/**\n * Price calculation for compartments.\n * For nightjets there is always a reservation necessary and always class2.\n *\n * Based on \"OEBB_External_API_-_Service_Booking_ohne_Finalize.pdf\" (p. 7, 2020-06-05):\n * 3.1.3 How to calculate the price\n *\n * Ticket without reservation\n * Take the price from the attributes priceClass1 or priceClass2 from the node\n * productSummary.\n *\n * Ticket with reservation business class\n * It is important to select the compartment with the attribute isBusinessClass = true.\n * Take the price from the attributes priceClass1 in the node productSummary and the\n * price for the reservation for business class \"priceBusinessClass\" from the node\n * reservation.\n *\n * Ticket with reservation 1st or 2nd classes\n * It is important to select the compartment with a same class as the ticket for each\n * scope.\n * (accommodationClasses in the node compartments)\n * Take the price from the attributes priceClass1 or priceClass2 from the node\n * productSummary and the price for the reservation for the same class \"priceClass1\" or\n * \"priceClass2\" from the node reservation. The surchargePrice for every selected\n * compartment has to be added.\n *\n * Tickets with reservation privateVariations\n * Additional to the rules before the surchargePrice in the privateVariation must be added\n */\nexport function calculateSelectableCompartmentPricesForOffer(offer: ApiProduct, reservationKey: string = 'priceClass2'): number[] {\n const compartmentPrices: number[] = [];\n\n reservationSegementsLoop: for (const reservationSegement of offer.reservation.reservationSegments) {\n compartmentsLoop: for (const compartment of reservationSegement.compartments) {\n if (!isSupportedCompartment(compartment)) continue;\n\n let basePrice: number = offer[reservationKey];\n if (offer.reservation[reservationKey]) basePrice += offer.reservation[reservationKey]; // Should always be 0 for nightjet trains, anyways we use it.\n\n if (compartment.privateVariations) {\n for (const privateVariation of compartment.privateVariations) {\n if (privateVariation.surchargePrice) {\n compartmentPrices.push(basePrice + privateVariation.surchargePrice);\n } else {\n compartmentPrices.push(basePrice);\n }\n }\n } else {\n if (compartment.surchargePrice) {\n compartmentPrices.push(basePrice + compartment.surchargePrice);\n } else {\n compartmentPrices.push(basePrice);\n }\n }\n }\n }\n\n return compartmentPrices;\n}\n\nexport function calculateSelectableCompartmentPricesForOffers(offers: ApiProduct[]) {\n const offerPrices: number[][] = [];\n\n for (let i = 0; i < offers.length; i++) {\n const offer = offers[i];\n const compartmentPrices: number[] = calculateSelectableCompartmentPricesForOffer(offer);\n\n offerPrices[i] = compartmentPrices;\n }\n\n return offerPrices;\n}\n\n/**\n * Select compartment and calculate price again for cross check\n */\nexport function selectCompartment(\n offers: PrebookApiProduct[],\n selectedInternalProduct: any,\n accommodationType: AccommodationType,\n): [PrebookApiProduct[], number] {\n let price: number = 0;\n offers = JSON.parse(JSON.stringify(offers));\n\n for (const offer of offers) {\n let selected: SelectedClasses;\n\n // Skip if not supported offer or offer not matching selected offer name\n if (\n !selectedInternalProduct\n || !isSupportedOffer(offer.name)\n || getProductKey(getProductTypeForName(offer.name)) !== selectedInternalProduct.ticket\n ) continue;\n\n reservationSegementsLoop: for (const reservationSegement of offer.reservation.reservationSegments) {\n compartmentsLoop: for (const compartment of reservationSegement.compartments) {\n if (!isSupportedCompartment(compartment)) continue;\n\n if (\n compartment.id == selectedInternalProduct.offer.compartmentId\n && compartment.externalIdentifier == selectedInternalProduct.offer.externalIdentifier\n && compartment.accommodationType == accommodationType\n ) {\n selected = (compartment.accommodationClass[0] as SelectedClasses) ?? SelectedClasses.class2;\n const selectedReservationKey: string = 'price' + selected.charAt(0).toUpperCase() + selected.slice(1);\n compartment.selected = true;\n\n price += offer[selectedReservationKey];\n if (offer.reservation[selectedReservationKey]) price += offer.reservation[selectedReservationKey];\n\n if (compartment.privateVariations) {\n for (const privateVariation of compartment.privateVariations) {\n if (privateVariation.count === selectedInternalProduct.offer.privateVariationCount) {\n privateVariation.selected = true;\n\n if (privateVariation.surchargePrice) price += privateVariation.surchargePrice;\n }\n }\n } else {\n if (compartment.surchargePrice) price += compartment.surchargePrice;\n\n // Select spot location, only one is allowed\n if (compartment.spotLocations) {\n for (const spotLocation of compartment.spotLocations) {\n for (const spotLocationSelected of selectedInternalProduct.spotLocationsSelected) {\n\t\t\t\t\tif (spotLocationSelected.value === spotLocation.param || (\"placeAlignment\" in spotLocation && spotLocationSelected.value === (spotLocation as any).placeAlignment)) {\n\t\t\t\t\t\tspotLocation.selected = true;\n\t\t\t\t\t}\n }\n }\n }\n }\n\n break reservationSegementsLoop;\n }\n }\n }\n\n if (selected) {\n offer.selected = selected;\n offer.reservation.selected = selected;\n }\n }\n\n return [\n offers,\n price,\n ];\n}\n\nexport function preparePrebookRequestBody() {\n const orders: PrebookOrderV4[] = [];\n let paymentInformationPrice: number = 0;\n\n for (const mode of [ReservationMode.Outward, ReservationMode.Return]) {\n const store = journeyData(mode);\n\n const finalProduct = store.getFinalProduct();\n const offerData = store.getFinalOffer();\n\n if (offerData) {\n let prebookOffers: PrebookApiProduct[], price: number, filter: ConnectionFilter;\n if (finalProduct?.additionalProduct) {\n price = finalProduct.price;\n prebookOffers = [buildPrebookData(finalProduct)];\n\t\t filter = {};\n } else {\n // TODO This can probably be handled with the same logic as additional trains\n [prebookOffers, price] = selectCompartment(offerData.offer.offers, store.getNjProduct(), store.getNjAccommodation());\n\t\t filter = {maxTrainChanges: 0};\n }\n\n orders.push({\n objects: [],\n offers: prebookOffers,\n sections: offerData.offer.sections,\n filter,\n rfpIndex: 0,\n });\n paymentInformationPrice += price;\n }\n }\n\n\tpaymentInformationPrice = Math.round(paymentInformationPrice * 100) / 100;\n const requestBody = {\n paymentInformation: {\n amount: paymentInformationPrice,\n paymentMethod: \"EXTERNAL\",\n email: null,\n },\n orders,\n };\n\n dataStore().setSessionData(DATA_STORE_KEY_PREBOOK, requestBody);\n\n window.dispatchEvent(new Event('prebookRequestPrepared'));\n}\n\nexport function removeJourney(reservationMode: ReservationMode) {\n // Set return journey as outward journey if outward journey is removed\n if (reservationMode === ReservationMode.Outward) {\n const returnData = journeyData(ReservationMode.Return);\n let returnDataValue = dataStore().getSessionData(DATA_STORE_KEY_RETURN_VALUE, null);\n\n if (returnDataValue) returnDataValue = returnDataValue.replace(ReservationMode.Return, ReservationMode.Outward);\n\n journeyData(ReservationMode.Outward).replaceData(returnData);\n dataStore().setSessionData(DATA_STORE_KEY_OUTWARD_VALUE, returnDataValue);\n }\n\n // Always remove return journey, because if needed we switched it before\n journeyData(ReservationMode.Return).clearAll();\n dataStore().removeSessionData(DATA_STORE_KEY_RETURN_VALUE);\n preparePrebookRequestBody();\n\n window.dispatchEvent(new Event('journeyRemoved'));\n}\n\nexport function mapThirdGender(prebookData: PrebookV4Request): void {\n\t// warning: this function modifies the parameter and is therefore stateless\n\tfor (const order of prebookData.orders) {\n\t\tfor (const object of order.objects) {\n\t\t\tif (object.gender === \"diverse\") {\n\t\t\t\tobject.gender = \"male\";\n\t\t\t}\n\t\t}\n\t}\n}\n","import {ProductDetailObject, ReservationCompartment, ReservationSegment} from \"../api/Ticketshop\";\nimport {i18n} from \"./I18n\";\n\nexport type PriceClass = 'class1' | 'class2' | 'businessClass' | 'classBusiness' | 'noclass';\n\nexport function isBusinessClass(priceClass: PriceClass): boolean {\n return priceClass === 'businessClass' || priceClass === 'classBusiness';\n}\n\nexport function hasPriceClass(compartment: ReservationCompartment, priceClass: PriceClass): boolean {\n if (compartment.isBusinessClass) {\n return isBusinessClass(priceClass);\n }\n return (compartment.accommodationClass as any).includes(priceClass);\n}\n\nexport function getLowerPriceClass(priceClass: PriceClass): PriceClass | null {\n switch (priceClass) {\n case 'classBusiness':\n case 'businessClass':\n return 'class1';\n case 'class1':\n return 'class2';\n default:\n return null;\n }\n}\n\nexport function getPriceClassKey(priceClass: PriceClass): 'priceClass1' | 'priceClass2' | 'priceBusinessClass' | 'priceNoClass' {\n switch (priceClass) {\n case 'class1':\n return 'priceClass1';\n case 'class2':\n return 'priceClass2';\n case 'businessClass':\n case 'classBusiness':\n return 'priceBusinessClass';\n case \"noclass\":\n return 'priceNoClass';\n }\n}\n\n\n/**\n * Filters the list of compartments by price class\n * @param segment The reservation segment\n * @param priceClass The preferred price class\n * @return A list of compartments in the highest available price class based on the requested one\n */\nexport function getCompartmentsForClass(segment: ReservationSegment, priceClass: PriceClass): ReservationCompartment[] {\n if (!segment.compartments) {\n return [];\n }\n\n // Filter by available classes\n const compartments = segment.compartments?.filter(compartment => !compartment.special && hasPriceClass(compartment, priceClass));\n if (compartments.length) {\n // Found something, use it\n return compartments;\n }\n\n // Move down to second class\n const lowerPriceClass = getLowerPriceClass(priceClass);\n if (lowerPriceClass) {\n return getCompartmentsForClass(segment, getLowerPriceClass(priceClass));\n }\n\n // Nothing found (does this ever happen?)\n return [];\n}\n\nexport function getPriceForClass(product: ProductDetailObject, priceClass: PriceClass): number {\n const priceKey = getPriceClassKey(priceClass);\n if (product[priceKey] !== undefined) {\n // Price for the requested class exists, use it\n return product[priceKey];\n }\n\n // Move down to lower class\n const lowerPriceClass = getLowerPriceClass(priceClass);\n if (lowerPriceClass) {\n return getPriceForClass(product, lowerPriceClass);\n }\n\n // No price at all, use 0\n return 0;\n}\n\nexport function getMatchingPriceClass(product: ProductDetailObject, priceClass: PriceClass): PriceClass | null {\n const priceKey = getPriceClassKey(priceClass);\n if (product[priceKey] !== undefined) {\n // Price class exists, use it\n return priceClass;\n }\n\n // Move down to lower class\n const lowerPriceClass = getLowerPriceClass(priceClass);\n if (lowerPriceClass) {\n return getMatchingPriceClass(product, lowerPriceClass);\n }\n\n // No price at all, do not use any class\n return null;\n}\n\nexport function translatePriceClassName(priceClass: PriceClass): string {\n return i18n.getMessage(isBusinessClass(priceClass) ? 'ts.class.business' : `ts.class.${priceClass}`);\n}\n","import {\n ApiProduct,\n ConnectionSection,\n ConnectionWithOffersV6,\n PrebookApiProduct,\n PrebookObjectV4,\n PrebookReservationCompartmentV3,\n PrivateVariation,\n ProductDetail,\n ReservationCompartment,\n ReservationSegment,\n SectionAttribute,\n SectionStop\n} from \"../api/Ticketshop\";\nimport {WHEELCHAIR_COUCHETTE_DANI} from \"../components/nj-offer-list/OfferListConstants\";\nimport {isSupportedCompartment} from \"../components/nj-reservation/nj-reservation-utils\";\nimport {FinalProductData, NjProductData} from \"../global/JourneyStore\";\nimport {i18n} from \"./I18n\";\nimport {getCompartmentsForClass, getMatchingPriceClass, getPriceClassKey, getPriceForClass, PriceClass} from \"./price-class\";\nimport {translateProductDetailName} from \"./products\";\nimport {DATA_STORE_KEY_PASSENGERS, dataStore} from \"../global/DataStore\";\n\ntype NullableSectionStop = SectionStop | null;\n\n/**\n * Loads station information for scopes (e.g. first class availability)\n * @param sections The connection sections list\n * @param scopes An array of scopes\n * @return An array of station pairs\n */\nexport function getStopsForScopes(sections: ConnectionSection[] | undefined, scopes?: number[][]): [NullableSectionStop, NullableSectionStop][] | null {\n return scopes?.map(scope => getStopsForScope(sections, scope));\n}\n\n/**\n * Loads the station information for a single scope (e.g. first class availability)\n * @param sections The connection sections list\n * @param scope A four-element array containing the section and stop indices of the station\n * @return A pair of stations\n */\nexport function getStopsForScope(sections: ConnectionSection[] | undefined, scope: number[]): [NullableSectionStop, NullableSectionStop] {\n return [getStopAtIndex(sections, scope[0], scope[1]), getStopAtIndex(sections, scope[2], scope[3])];\n}\n\n/**\n * Loads the station information by index\n * @param sections The connection sections list\n * @param sectionIndex The index of the section\n * @param stopIndex The index of the stop\n * @return A single station iff the indices were valid\n */\nexport function getStopAtIndex(sections: ConnectionSection[] | undefined, sectionIndex: number, stopIndex: number): NullableSectionStop {\n return sections?.[sectionIndex]?.passlist?.[stopIndex] ?? null;\n}\n\n/**\n * Gets the train names for the sections within the given scopes\n * @param sections The sections of the offer\n * @param scopes The requested scopes\n * @return A list of train names and categories\n */\nexport function getTrainsForScopes(sections: ConnectionSection[] | undefined, scopes?: number[][]): { name: string, category: string }[] {\n const trains = [];\n if (!scopes || !sections) {\n return trains;\n }\n\n for (const scope of scopes) {\n for (let i = scope[0]; i <= scope[2]; i++) {\n const name = getSectionTrainName(sections[i]);\n const category = getSectionTrainCategory(sections[i]);\n if (name && (!trains.length || trains[trains.length - 1].name !== name)) {\n trains.push({name, category});\n }\n }\n }\n\n return trains;\n}\n\nexport function isSectionInScopes(scopes: number[][], sectionIndex: number) {\n return scopes.some(scope => isSectionInScope(scope, sectionIndex));\n}\n\nexport function isSectionInScope(scope: number[], sectionIndex: number) {\n return sectionIndex >= scope[0] && sectionIndex <= scope[2];\n}\n\nexport function getOfferParts(offer: ApiProduct, excludedIndex?: number): ProductDetail[] {\n return offer.productDetails\n .filter(details => excludedIndex === undefined || !isSectionInScopes(details.scope, excludedIndex))\n .sort((a, b) =>\n // First sort by scope, then by associated passengers\n a.scope[0][0] !== b.scope[0][0]\n ? a.scope[0][0] - b.scope[0][0]\n : Math.min(...a.objects.map(obj => obj.index)) - Math.min(...b.objects.map(obj => obj.index))\n );\n}\n\nexport function getOfferName(offer: ApiProduct, excludedIndex?: number) {\n return getOfferParts(offer, excludedIndex)\n .map(details => translateProductDetailName(details))\n .filter((val, index, self) => self.indexOf(val) === index)\n .join(' + ');\n}\n\n/**\n * Gets a section attribute by attribute type\n * @param section The section data\n * @param type The attribute type\n * @return The attribute if it exists\n */\nexport function getAttribute(section: ConnectionSection | undefined, type: string): SectionAttribute | null {\n return section?.attributes?.find(att => att.attributeType === type) ?? null;\n}\n\n/**\n * Gets the train name of a section\n * @param section The section data\n * @return The train name iff it is set\n */\nexport function getSectionTrainName(section?: ConnectionSection): string | null {\n return getAttribute(section, 'name')?.value?.toString().trim() ?? null;\n}\n\n/**\n * Gets the train category of a section\n * @param section The section data\n * @return The train category iff it is set\n */\nexport function getSectionTrainCategory(section?: ConnectionSection): string | null {\n return getAttribute(section, 'cat')?.svalue?.trim() ?? null;\n}\n\n/**\n * Gets the train category from a train name\n * @param name The train name\n * @return The train category iff it is present in the train name\n */\nexport function getTrainCategoryForName(name?: string): string | null {\n return name?.match(/^[a-z]+/i)?.[0] ?? null;\n}\n\n/**\n * Gets the train direction of a section\n * @param section The section data\n * @return The train direction iff it is set\n */\nexport function getSectionTrainDirection(section?: ConnectionSection): string | null {\n return getAttribute(section, 'dir')?.value.toString().trim() ?? null;\n}\n\nexport function sectionsListEqual(a: ConnectionSection[], b: ConnectionSection[]): boolean {\n if (a.length !== b.length) {\n // Fail fast: Not the same number of sections\n return false;\n }\n\n for (let i = 0; i < a.length; i++) {\n // Compare each pair of sections, fail if they are different\n if (!sectionsEqual(a[i], b[i])) {\n return false;\n }\n }\n\n // Nothing failed, so we have a match\n return true;\n}\n\nexport function sectionsEqual(a: ConnectionSection, b: ConnectionSection): boolean {\n // Consider sections to be equal if the times and the train name matches\n return a.departureTimestamp === b.departureTimestamp && a.arrivalTimestamp === b.arrivalTimestamp\n && getSectionTrainName(a) === getSectionTrainName(b);\n}\n\n/**\n * Loads the compartment in a reservation segment based on the compartment identifier\n * @param segment The reservation segment\n * @param identifier The compartment identifier\n * @return The compartment iff it was found\n */\nexport function getCompartmentById(segment: ReservationSegment, identifier: string): ReservationCompartment | null {\n return segment.compartments?.find(compartment =>\n // TODO Do we need more than the externalIdentifier here?\n isSupportedCompartment(compartment) && compartment.externalIdentifier === identifier\n ) ?? null;\n}\n\n/**\n * Calculates the surcharge of compartment\n * @param compartment The compartment\n * @param privateVariationCount The number of private compartments\n * @return The surcharge with the given product (which might be zero)\n */\nexport function getCompartmentPrice(compartment: ReservationCompartment, privateVariationCount?: number): number {\n if (compartment.privateVariations) {\n return compartment.privateVariations\n .filter(variation => variation.count === privateVariationCount)\n .map(variation => variation.surchargePrice || 0)\n .reduce((a, b) => a + b, 0);\n } else {\n return compartment.surchargePrice || 0;\n }\n}\n\n/**\n * Calculates the total price for a given compartment\n * @param offer The base offer\n * @param compartment The chosen compartment\n * @param priceClass The price class to calculate the price for\n * @return A price or null if the given price class is not available\n */\nexport function getOfferPrice(offer: ApiProduct, compartment: ReservationCompartment | PrivateVariation, priceClass: PriceClass = 'class2'): number | null {\n const priceClassKey = getPriceClassKey(priceClass);\n\n let basePrice = offer[priceClassKey];\n if (basePrice === undefined) {\n // No base price for the chosen price class: Do no show as offer\n return null;\n }\n\n if (offer.reservation && offer.reservation[priceClassKey]) {\n // Add the general reservation fee\n basePrice += offer.reservation[priceClassKey];\n }\n\n if (compartment && compartment.surchargePrice) {\n basePrice += compartment.surchargePrice;\n }\n\n return basePrice;\n}\n\nexport function translateCompartmentName(compartment: ReservationCompartment): string {\n return i18n.getMessage(\n `ts.reservation.compartment.${compartment.externalIdentifier}`, '', null, compartment.name\n );\n}\n\n/**\n * Builds the available product options and calculates the prices for a combination of NJ and additional trains\n * @param offer The offer data\n * @param njProduct The NJ product data\n * @param njIndex The section index of the NJ part\n * @param priceClass The requested price class for the product\n * @return The price or null iff the requested options are not available\n */\nexport function buildAdditionalOptions(offer: ApiProduct, njProduct: NjProductData, njIndex: number, priceClass: PriceClass): AdditionalProductOptions | null {\n const priceClassKey = getPriceClassKey(priceClass);\n\n let basePrice = offer[priceClassKey];\n if (basePrice === undefined) {\n // No base price for the chosen price class: Do not show any offers\n return null;\n }\n\n if (offer.reservation && offer.reservation[priceClassKey]) {\n // Add the general reservation fee\n basePrice += offer.reservation[priceClassKey];\n }\n\n // We use two prices here: The base price is necessary to calculate the total base on the selected compartments\n // The minimum price is used for displaying the best price based on the cheapest matching compartments\n let minPrice = basePrice;\n\n // Load all reservable segments and group them by journey section index\n const segments = new Map<number, AdditionalProductSegment>();\n for (const [segmentIndex, segment] of offer.reservation?.reservationSegments.entries()) {\n const sectionIndex = segment.scope[0];\n if (sectionIndex === njIndex) {\n // We are in the section of the NJ train: Use the previous compartment choice\n const compartment = getCompartmentById(segment, njProduct.compartment.externalIdentifier);\n if (!compartment) {\n // The offer does not contain the chosen NJ compartment, so the user should not book it at all\n return null;\n }\n\n // The price of the NJ compartment must be paid in any case\n const surcharge = getCompartmentPrice(compartment, njProduct.privateVariationCount);\n minPrice += surcharge;\n\n segments.set(sectionIndex, {\n minSurcharge: surcharge,\n compartments: [\n {\n segmentIndex, compartment, surcharge,\n privateVariationCount: njProduct.privateVariationCount,\n spotLocation: njProduct.spotLocationsSelected[0],\n }\n ],\n });\n } else {\n const compartments = getCompartmentsForClass(segment, priceClass)\n .sort((a, b) => a.externalIdentifier.localeCompare(b.externalIdentifier))\n .map(compartment => ({\n segmentIndex, compartment,\n surcharge: getCompartmentPrice(compartment),\n // TODO Choose default private variation count if necessary\n }));\n\n if (compartments.length) {\n const minSurcharge = compartments\n .map(compartment => compartment.surcharge)\n .reduce((a, b) => Math.min(a, b));\n minPrice += minSurcharge;\n\n segments.set(sectionIndex, {minSurcharge, compartments});\n }\n }\n }\n\n const surcharge = minPrice - njProduct.price;\n return {offer, priceClass, basePrice, minPrice, surcharge, segments};\n}\n\n/**\n * Builds prebook data for an offer\n * @param finalProduct The NJ and additional product data\n * @return The prebook object with the selected options marked\n */\nexport function buildPrebookData(finalProduct: FinalProductData): PrebookApiProduct {\n const additionalProduct = finalProduct.additionalProduct;\n\n // Work on a deep copy of the offer object\n const result = JSON.parse(JSON.stringify(additionalProduct.offer)) as PrebookApiProduct;\n\n // Fix the price class name, it differs on different parts of the API :(\n const selectedClass = additionalProduct.priceClass === 'businessClass' ? 'classBusiness' : additionalProduct.priceClass;\n\n // Select the requested price class\n result.selected = selectedClass;\n\n if (!result.reservation) {\n // No reservation - nothing else to do (should never happen with NJ)\n return result;\n }\n\n if (selectedClass !== 'noclass') {\n result.reservation.selected = selectedClass;\n }\n\n additionalProduct.compartments.forEach(compartmentData => {\n const segment = result.reservation.reservationSegments[compartmentData.segmentIndex];\n const compartment = getCompartmentById(segment, compartmentData.identifier) as PrebookReservationCompartmentV3;\n if (!compartment) {\n // This should never happen, only existing compartments can be selected\n // TODO Do we need to handle this?\n return;\n }\n\n // Mark the compartment itself as selected\n compartment.selected = true;\n if (compartment.privateVariations) {\n // Select the correct private variation\n compartment.privateVariations\n .filter(privateVariation => privateVariation.count === compartmentData.privateVariationCount)\n .forEach(privateVariation => privateVariation.selected = true);\n } else if (compartment.spotLocations) {\n // Select spot locations in the compartment\n compartment.spotLocations\n .filter(spotLocation => spotLocation.param === compartmentData.spotLocation)\n .forEach(spotLocation => spotLocation.selected = true);\n }\n });\n\n\n return result;\n}\n\n/**\n * Groups the ticket details by scope from the prebook data\n * @param tickets The ticket data\n * @return A list of ticket details\n */\nexport function groupTicketDetailsByScope(tickets: Ticket[]): TicketsGroupedByScope {\n\n return tickets.reduce((groupedTickets: TicketsGroupedByScope, ticket: Ticket) => {\n const scope = ticket.ticketDetails.scopes.flat().join('-');\n const passengerType = ticket.passenger.type + (ticket.ticketDetails.isReservation ? '-reservation' : '');\n\n if (!groupedTickets[scope]) {\n groupedTickets[scope] = {};\n }\n\n if (!groupedTickets[scope][passengerType]) {\n groupedTickets[scope][passengerType] = createInitialGroup(ticket);\n } else {\n updateGroup(groupedTickets[scope][passengerType], ticket);\n }\n\n return groupedTickets;\n\n }, {} );\n}\n\nfunction createInitialGroup(ticket: Ticket) {\n return {\n ticketsCount: 1,\n sum: ticket.ticketDetails.price,\n ticketDetails: ticket.ticketDetails,\n passangerType: ticket.passenger.type,\n passengers: [{\n passenger: ticket.passenger,\n passengerIndex: ticket.passengerIndex,\n ticketPrice: ticket.ticketDetails.price\n }]\n };\n}\n\nfunction updateGroup(groupedTicketDetails: GroupedTicketDetails, ticket: Ticket) {\n if (ticket.ticketDetails.price !== 0) {\n groupedTicketDetails.ticketsCount++;\n groupedTicketDetails.sum += ticket.ticketDetails.price;\n }\n groupedTicketDetails.passengers.push({\n passenger: ticket.passenger,\n passengerIndex: ticket.passengerIndex,\n ticketPrice: ticket.ticketDetails.price\n });\n}\n\n/**\n * Loads the ticket details for each passenger from the prebook data\n * @param product The product data with selected flags set\n * @param passengers The passenger data\n * @return A list of ticket details\n */\nexport function getTicketDetailsFromPrebook(product: PrebookApiProduct, passengers: PrebookObjectV4[]): Ticket[] {\n const result: Ticket[] = []\n\n const priceClass = product.selected;\n\n // Add product based prices\n product.productDetails\n // Ignore globally priced items, they are included in the reservation price\n .filter(product => !product.globallyPriced)\n .forEach(product => product.objects\n .forEach(passenger => {\n result.push({\n ticketDetails: {\n scopes: product.scope,\n price: getPriceForClass(passenger, priceClass),\n productDetails: product,\n productPriceClass: getMatchingPriceClass(passenger, priceClass),\n isReservation: false,\n },\n passenger: passengers[passenger.index],\n passengerIndex: passenger.index\n })\n })\n );\n\n // Add reservation based prices\n product.reservation?.reservationSegments.forEach(segment =>\n segment.compartments\n ?.filter(item => item.selected || item.special)\n .forEach(compartment => {\n if (compartment.privateVariations) {\n // Find the selected private allocation\n const variation = compartment.privateVariations.find(item => item.selected);\n if (!variation) {\n // TODO This should never happen, should we handle it somehow?\n return;\n }\n\n variation.allocations.forEach(allocation =>\n allocation.objects.forEach(object =>\n result.push({\n ticketDetails: {\n scopes: [segment.scope],\n price: object.price,\n productDetails: getProductDetailsForScope(product, segment.scope, object.index),\n compartment: compartment,\n isReservation: true,\n },\n passenger: passengers[object.index],\n passengerIndex: object.index\n })\n )\n );\n } else if (compartment.objects) {\n\n // Regular reservations\n compartment.objects.forEach(object => {\n\t\t\t\t\t\tlet price = object.price;\n\t\t\t\t\t\tif (compartment.freeFollowupReservationApplied === true) {\n\t\t\t\t\t\t\tprice = 0;\n\t\t\t\t\t\t}\n\n result.push({\n ticketDetails: {\n scopes: [segment.scope],\n price,\n productDetails: getProductDetailsForScope(product, segment.scope, object.index),\n compartment: compartment,\n isReservation: true,\n },\n passenger: passengers[object.index],\n passengerIndex: object.index\n })\n\t\t\t\t\t});\n } else {\n // TODO This should never happen, should we handle it somehow?\n }\n })\n );\n\n result.sort((a, b) => a.passengerIndex - b.passengerIndex);\n\n result.sort((a, b) => {\n if (a.ticketDetails.scopes[0][0] !== b.ticketDetails.scopes[0][0]) {\n return a.ticketDetails.scopes[0][0] - b.ticketDetails.scopes[0][0];\n }\n if (a.ticketDetails.isReservation !== b.ticketDetails.isReservation) {\n return a.ticketDetails.isReservation ? 1 : -1;\n }\n return 0;\n })\n\n return result;\n}\n\nfunction getProductDetailsForScope(product: PrebookApiProduct, scope: number[], passengerIndex: number): ProductDetail | null {\n return product.productDetails.find(item =>\n // Only consider globally priced tickets\n item.globallyPriced &&\n // Only consider products for the requested passenger\n item.objects.find(object => object.index === passengerIndex) &&\n // Only consider products in the requested scope\n item.scope.find(productScope => productScope[0] <= scope[0] && productScope[2] >= scope[2])\n ) ?? null;\n}\n\nexport interface GroupedTicketDetails {\n ticketsCount: number,\n sum: number,\n ticketDetails: TicketDetails,\n passangerType: string,\n passengers: Passenger[];\n}\n\nexport interface TicketsGroupedByScope {\n [keyScope: string]: {\n [keyType: string]: GroupedTicketDetails\n }\n}\n\nexport interface Ticket {\n passengerIndex: number;\n passenger: PrebookObjectV4;\n ticketDetails: TicketDetails;\n}\n\nexport interface Passenger {\n passengerIndex: number;\n passenger: PrebookObjectV4;\n ticketPrice: number;\n}\n\nexport interface TicketDetails {\n scopes: number[][];\n price: number;\n productDetails?: ProductDetail;\n productPriceClass?: PriceClass;\n compartment?: ReservationCompartment;\n isReservation: boolean;\n}\n\nexport interface AdditionalConnectionWithOffers extends ConnectionWithOffersV6 {\n njIndex: number;\n}\n\nexport interface AdditionalProductOptions {\n offer: ApiProduct;\n priceClass: PriceClass;\n basePrice: number;\n minPrice: number;\n surcharge: number;\n segments: Map<number, AdditionalProductSegment>;\n}\n\nexport interface AdditionalProductSegment {\n minSurcharge: number;\n compartments: AdditionalProductCompartment[];\n}\n\nexport interface AdditionalProductCompartment {\n segmentIndex: number;\n surcharge: number;\n privateVariationCount?: number;\n spotLocation?: string;\n compartment: ReservationCompartment;\n}\n\nexport function doesPassengerRequireWheelchair(): boolean {\n\tconst passengers = dataStore().getSessionData(DATA_STORE_KEY_PASSENGERS);\n\tfor (const passenger of passengers) {\n\t\tconst accessibilityOptions = passenger.njChallengedOptions;\n\t\tif (accessibilityOptions !== undefined && accessibilityOptions !== null && accessibilityOptions.wheelchair === true) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nexport function hasWheelchairCompartment(compartments: any[]): boolean {\n\treturn compartments.find(compartment => compartment.externalIdentifier === WHEELCHAIR_COUCHETTE_DANI);\n}\n"],"mappings":"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"}