@qite/tide-booking-component 1.3.4 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/build/build-cjs/booking-wizard/features/sidebar/sidebar-util.d.ts +3 -3
  2. package/build/build-cjs/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +5 -5
  3. package/build/build-cjs/booking-wizard/types.d.ts +6 -0
  4. package/build/build-cjs/index.js +223 -147
  5. package/build/build-cjs/shared/utils/localization-util.d.ts +2 -0
  6. package/build/build-esm/booking-wizard/features/sidebar/sidebar-util.d.ts +3 -3
  7. package/build/build-esm/booking-wizard/features/travelers-form/travelers-form-slice.d.ts +5 -5
  8. package/build/build-esm/booking-wizard/types.d.ts +6 -0
  9. package/build/build-esm/index.js +223 -147
  10. package/build/build-esm/shared/utils/localization-util.d.ts +2 -0
  11. package/package.json +75 -75
  12. package/src/booking-wizard/components/print-offer-button.tsx +63 -63
  13. package/src/booking-wizard/features/booking/booking-self-contained.tsx +389 -389
  14. package/src/booking-wizard/features/booking/booking-slice.ts +663 -663
  15. package/src/booking-wizard/features/booking/booking.tsx +361 -361
  16. package/src/booking-wizard/features/flight-options/flight-utils.ts +522 -522
  17. package/src/booking-wizard/features/product-options/options-form.tsx +481 -481
  18. package/src/booking-wizard/features/sidebar/sidebar-util.ts +177 -177
  19. package/src/booking-wizard/features/summary/summary-booking-option-pax.tsx +25 -25
  20. package/src/booking-wizard/features/summary/summary.tsx +674 -674
  21. package/src/booking-wizard/features/travelers-form/travelers-form-slice.ts +164 -164
  22. package/src/booking-wizard/features/travelers-form/travelers-form.tsx +888 -754
  23. package/src/booking-wizard/settings-context.ts +62 -62
  24. package/src/booking-wizard/types.ts +286 -279
  25. package/src/booking-wizard/use-offer-printer.ts +117 -117
  26. package/src/shared/translations/en-GB.json +239 -237
  27. package/src/shared/translations/fr-BE.json +239 -238
  28. package/src/shared/translations/nl-BE.json +239 -237
  29. package/src/shared/utils/tide-api-utils.ts +36 -36
  30. package/styles/booking-wizard-variables.scss +873 -873
  31. package/styles/components/_booking.scss +879 -879
  32. package/styles/components/_dropdown.scss +72 -72
  33. package/styles/components/_form.scss +1583 -1583
@@ -1,663 +1,663 @@
1
- import { PayloadAction, createAsyncThunk, createSlice } from "@reduxjs/toolkit";
2
- import {
3
- BookingAttributes,
4
- BookingOptions,
5
- GroupedFlights,
6
- ProductAttributes,
7
- } from "../../types";
8
-
9
- import {
10
- AirlineBookingPackageOption,
11
- AirportBookingPackageOption,
12
- BookingAirlineGroup,
13
- BookingAirportGroup,
14
- BookingOptionGroup,
15
- BookingOptionPax,
16
- BookingOptionUnit,
17
- BookingPackage,
18
- BookingPackageDetailsRequest,
19
- BookingPackageFlight,
20
- BookingPackagePax,
21
- BookingPackageRequest,
22
- BookingPackageRequestRoom,
23
- BookingPackageRoom,
24
- BookingTravelAgent,
25
- GenerateBookingAccommodationRequest,
26
- PerBookingPackageOption,
27
- SelectedFlight,
28
- } from "@qite/tide-client/build/types";
29
- import { first, isEmpty, isNil, range } from "lodash";
30
- import { RootState } from "../../store";
31
- import { selectAgentId } from "../travelers-form/travelers-form-slice";
32
- import packageApi from "./api";
33
- import { BookingStep, OPTIONS_FORM_STEP } from "./constants";
34
- import {
35
- selectAccommodationCodes,
36
- selectBookingAttributes,
37
- selectBookingRooms,
38
- selectLanguageCode,
39
- selectOfficeId,
40
- selectProductAttributes,
41
- selectProductCode,
42
- } from "./selectors";
43
-
44
- export interface BookingState {
45
- officeId: number;
46
- languageCode: string;
47
- productAttributes?: ProductAttributes;
48
- bookingAttributes?: BookingAttributes;
49
- calculateDeposit: boolean;
50
- bookingNumber?: string;
51
- isRetry: boolean;
52
- package?: BookingPackage;
53
- agents?: BookingTravelAgent[];
54
- isBusy: boolean;
55
- skipPaymentWithAgent: boolean;
56
- generatePaymentUrl: boolean;
57
- isUnavailable?: boolean;
58
- tagIds?: number[];
59
- agentAdressId?: number;
60
- remarks?: string;
61
- voucherCodes?: string[];
62
- bookingOptions: BookingOptions;
63
- bookingType: string;
64
- currentStep: BookingStep;
65
- translations?: {
66
- language: string;
67
- value: any;
68
- }[];
69
- accommodationViewId?: number;
70
- accommodationViews?: { [key: string]: string };
71
- }
72
-
73
- const initialState: BookingState = {
74
- officeId: 1,
75
- languageCode: "nl-BE",
76
- bookingOptions: {
77
- b2b: {
78
- tagIds: [],
79
- entryStatus: 2,
80
- customEntryStatusId: undefined,
81
- },
82
- b2b2c: {
83
- tagIds: [],
84
- entryStatus: 2,
85
- customEntryStatusId: undefined,
86
- },
87
- b2c: {
88
- tagIds: [],
89
- entryStatus: 0,
90
- customEntryStatusId: undefined,
91
- },
92
- },
93
- bookingType: "b2c",
94
- productAttributes: undefined,
95
- bookingAttributes: undefined,
96
- calculateDeposit: false,
97
- bookingNumber: undefined,
98
- isRetry: false,
99
- package: undefined,
100
- isBusy: false,
101
- skipPaymentWithAgent: false,
102
- generatePaymentUrl: false,
103
- tagIds: [],
104
- agentAdressId: undefined,
105
- currentStep: OPTIONS_FORM_STEP,
106
- translations: undefined,
107
- };
108
-
109
- export const fetchPackage = createAsyncThunk(
110
- "booking/fetchPackage",
111
- async (_, { dispatch }) => {
112
- dispatch(setFetchingPackage(true));
113
- await dispatch(fetchAgents());
114
- await dispatch(fetchPackageDetails());
115
- await dispatch(fetchAccommodationViews());
116
- dispatch(setFetchingPackage(false));
117
- }
118
- );
119
-
120
- const fetchAgents = createAsyncThunk(
121
- "booking/agents",
122
- async (_, { dispatch, getState, signal }) => {
123
- const settings = getState() as RootState;
124
- return await packageApi.fetchAgents(signal, settings.apiSettings);
125
- }
126
- );
127
-
128
- const fetchPackageDetails = createAsyncThunk(
129
- "booking/details",
130
- async (_, { dispatch, getState, signal }) => {
131
- const state = getState() as RootState;
132
-
133
- const officeId = selectOfficeId(state);
134
- const productAttributes = selectProductAttributes(state);
135
- const bookingAttributes = selectBookingAttributes(state);
136
- const agentId = selectAgentId(state);
137
- const rooms = selectBookingRooms(state);
138
- const languageCode = selectLanguageCode(state);
139
-
140
- if (isNil(productAttributes)) {
141
- throw Error("productAttributes could not be found");
142
- }
143
-
144
- if (isNil(bookingAttributes)) {
145
- throw Error("bookingAttributes could not be found");
146
- }
147
-
148
- if (!rooms?.length) {
149
- throw Error("rooms could not be found");
150
- }
151
-
152
- var requestRooms = rooms?.map((x, i) => {
153
- var room = { index: i, pax: [] } as BookingPackageRequestRoom;
154
- range(0, x.adults).forEach(() => {
155
- room.pax.push({
156
- age: 30,
157
- } as BookingPackagePax);
158
- });
159
- x.childAges.forEach((x) => {
160
- room.pax.push({
161
- age: x,
162
- } as BookingPackagePax);
163
- });
164
- return room;
165
- });
166
-
167
- const isAllotment =
168
- bookingAttributes.tourCode ||
169
- bookingAttributes.allotmentName ||
170
- (bookingAttributes.allotmentIds && bookingAttributes.allotmentIds.length);
171
-
172
- let searchType = isAllotment
173
- ? 1 // ALLOTMENT
174
- : 0; // DEFAULT;
175
-
176
- let outwardFlight: SelectedFlight | undefined;
177
- let returnFlight: SelectedFlight | undefined;
178
- if (bookingAttributes.flightRouteId && bookingAttributes.flight) {
179
- searchType = 3; // FLIGHT;
180
-
181
- outwardFlight = {
182
- flightCode: bookingAttributes.flight.outwardCode,
183
- startDateTime: bookingAttributes.flight.outwardDepartureDate,
184
- endDateTime: bookingAttributes.flight.outwardArrivalDate,
185
- } as SelectedFlight;
186
-
187
- if (bookingAttributes.flight.returnCode) {
188
- returnFlight = {
189
- flightCode: bookingAttributes.flight.returnCode,
190
- startDateTime: bookingAttributes.flight.returnDepartureDate,
191
- endDateTime: bookingAttributes.flight.returnArrivalDate,
192
- } as SelectedFlight;
193
- }
194
- }
195
-
196
- const request = {
197
- officeId: officeId,
198
- agentId: agentId,
199
- payload: {
200
- searchType: searchType,
201
- catalogueId: bookingAttributes.catalog,
202
- productCode: productAttributes.productCode,
203
- fromDate: bookingAttributes.startDate,
204
- toDate: bookingAttributes.endDate,
205
- includeFlights: bookingAttributes.includeFlights,
206
- allotmentName: bookingAttributes.allotmentName,
207
- allotmentIds: bookingAttributes.allotmentIds ?? [],
208
- tourCode: bookingAttributes.tourCode,
209
- rooms: requestRooms,
210
- routeId: bookingAttributes.flightRouteId,
211
- outwardFlight: outwardFlight,
212
- returnFlight: returnFlight,
213
- vendorConfigurationId: bookingAttributes.vendorConfigurationId,
214
- } as BookingPackageDetailsRequest,
215
- } as BookingPackageRequest<BookingPackageDetailsRequest>;
216
-
217
- return await packageApi.fetchDetails(
218
- request,
219
- signal,
220
- languageCode,
221
- state.apiSettings
222
- );
223
- }
224
- );
225
-
226
- const fetchAccommodationViews = createAsyncThunk(
227
- "booking/accommodationViews",
228
- async (_, { dispatch, getState, signal }) => {
229
- const state = getState() as RootState;
230
- if (!state.booking.accommodationViewId) return Promise.resolve();
231
-
232
- const languageCode = selectLanguageCode(state);
233
- const accommodationCodes = selectAccommodationCodes(state);
234
- const productCode = selectProductCode(state);
235
-
236
- if (!productCode) {
237
- throw Error("No product selected");
238
- }
239
-
240
- const request = {
241
- languageCode: languageCode,
242
- productCode: productCode,
243
- accommodationCodes: accommodationCodes,
244
- contentViewId: state.booking.accommodationViewId,
245
- } as GenerateBookingAccommodationRequest;
246
-
247
- return await packageApi.fetchAccommodationViews(
248
- request,
249
- signal,
250
- state.apiSettings
251
- );
252
- }
253
- );
254
-
255
- const getActiveOption = (state: BookingState) => {
256
- if (state.package) return state.package.options.find((x) => x.isSelected);
257
- return null;
258
- };
259
-
260
- const changeOutwardFlight = (
261
- state: BookingPackage,
262
- flight: BookingPackageFlight
263
- ) => {
264
- const currentOutwardFlight = state.outwardFlights.find((x) => x.isSelected)!;
265
- const currentReturnFlight = state.returnFlights.find((x) => x.isSelected)!;
266
-
267
- if (currentOutwardFlight?.entryLineGuid == flight.entryLineGuid) return;
268
-
269
- const newFlight = state.outwardFlights.find(
270
- (x) => x.entryLineGuid == flight.entryLineGuid
271
- );
272
- if (newFlight) {
273
- newFlight.isSelected = true;
274
- currentOutwardFlight.isSelected = false;
275
-
276
- if (newFlight.externalGuid) {
277
- if (currentOutwardFlight.externalGuid !== newFlight.externalGuid) {
278
- const newReturnFlight = state.returnFlights.find(
279
- (x) => x.externalGuid === newFlight.externalGuid
280
- )!;
281
-
282
- currentReturnFlight.isSelected = false;
283
- newReturnFlight.isSelected = true;
284
- }
285
- } else if (currentReturnFlight.externalGuid) {
286
- const firstInternal = state.returnFlights.find((x) => !x.externalGuid);
287
-
288
- if (firstInternal) {
289
- currentReturnFlight.isSelected = false;
290
- firstInternal.isSelected = true;
291
- }
292
- }
293
- }
294
- };
295
-
296
- const changeReturnFlight = (
297
- state: BookingPackage,
298
- flight: BookingPackageFlight
299
- ) => {
300
- const currentReturnFlight = state.returnFlights.find((x) => x.isSelected)!;
301
-
302
- if (currentReturnFlight?.entryLineGuid == flight.entryLineGuid) return;
303
-
304
- const newFlight = state.outwardFlights.find(
305
- (x) => x.entryLineGuid == flight.entryLineGuid
306
- );
307
- if (newFlight) {
308
- newFlight.isSelected = true;
309
- currentReturnFlight.isSelected = false;
310
- }
311
- };
312
-
313
- const changePackageOption = (state: BookingPackage) => {
314
- const selectedOutward = state.outwardFlights.find((x) => x.isSelected)!;
315
- const selectedReturn = state.returnFlights.find((x) => x.isSelected)!;
316
- const validOptions = selectedOutward.validOptions.filter((x) =>
317
- selectedReturn.validOptions.some((y) => x === y)
318
- );
319
-
320
- const currentOption = state.options.find((x) => x.isSelected)!;
321
- if (validOptions.some((x) => x === currentOption.id)) return;
322
-
323
- const firstOption = state.options.find((x) =>
324
- validOptions.some((y) => y === x.id)
325
- )!;
326
- currentOption.isSelected = false;
327
- firstOption.isSelected = true;
328
-
329
- const currentRooms = currentOption.rooms.map((r) => {
330
- const selectedOption = r.options.find((o) => o.isSelected)!;
331
-
332
- return {
333
- accommodation: selectedOption?.accommodationCode,
334
- regime: selectedOption?.regimeCode,
335
- };
336
- });
337
-
338
- firstOption.rooms.forEach((r, i) => {
339
- const currentRoom = currentRooms[i];
340
-
341
- const selectedOption = r.options.find((o) => o.isSelected);
342
- const selection = r.options.find(
343
- (x) =>
344
- x.accommodationCode === currentRoom.accommodation &&
345
- x.regimeCode === currentRoom.regime
346
- );
347
-
348
- if (selection) {
349
- if (selection.entryLineGuid !== selectedOption?.entryLineGuid) {
350
- if (selectedOption) selectedOption.isSelected = false;
351
- selection.isSelected = true;
352
- }
353
- } else {
354
- const accommodationSelection = r.options.find(
355
- (x) => x.accommodationCode === currentRoom.accommodation
356
- );
357
- if (accommodationSelection) {
358
- if (
359
- accommodationSelection.entryLineGuid !== selectedOption?.entryLineGuid
360
- ) {
361
- if (selectedOption) selectedOption.isSelected = false;
362
- accommodationSelection.isSelected = true;
363
- }
364
- } else {
365
- const firstOption = r.options[0];
366
- if (firstOption.entryLineGuid !== selectedOption?.entryLineGuid) {
367
- if (selectedOption) selectedOption.isSelected = false;
368
- firstOption.isSelected = true;
369
- }
370
- }
371
- }
372
- });
373
- };
374
-
375
- const bookingSlice = createSlice({
376
- name: "booking",
377
- initialState,
378
- reducers: {
379
- setOfficeId(state, action: PayloadAction<number>) {
380
- state.officeId = action.payload;
381
- },
382
- setLanguageCode(state, action: PayloadAction<string>) {
383
- state.languageCode = action.payload;
384
- },
385
- setTranslations(state, action: PayloadAction<any>) {
386
- state.translations = action.payload;
387
- },
388
- setBookingOptions(state, action: PayloadAction<BookingOptions>) {
389
- state.bookingOptions = action.payload;
390
- },
391
- setBookingType(state, action: PayloadAction<string>) {
392
- state.bookingType = action.payload;
393
- },
394
- setProductAttributes(state, action: PayloadAction<ProductAttributes>) {
395
- state.productAttributes = action.payload;
396
- },
397
- setBookingAttributes(state, action: PayloadAction<BookingAttributes>) {
398
- state.bookingAttributes = action.payload;
399
- },
400
- setCalculateDeposit(state, action: PayloadAction<boolean>) {
401
- state.calculateDeposit = action.payload;
402
- },
403
- setBookingNumber(state, action: PayloadAction<string>) {
404
- state.bookingNumber = action.payload;
405
- },
406
- setIsRetry(state, action: PayloadAction<boolean>) {
407
- state.isRetry = action.payload;
408
- },
409
- setFetchingPackage(state, action: PayloadAction<boolean>) {
410
- state.isBusy = action.payload;
411
- },
412
- setPackage(state, action: PayloadAction<BookingPackage>) {
413
- state.package = action.payload;
414
- },
415
- setPackageRooms(state, action: PayloadAction<BookingPackageRoom[]>) {
416
- const option = getActiveOption(state);
417
- if (option) option.rooms = action.payload;
418
- },
419
- setPackageOptionPax(state, action: PayloadAction<BookingOptionPax[]>) {
420
- const option = getActiveOption(state);
421
- if (option) option.optionPax = action.payload;
422
- },
423
- setPackageOptionUnits(state, action: PayloadAction<BookingOptionUnit[]>) {
424
- const option = getActiveOption(state);
425
- if (option) option.optionUnits = action.payload;
426
- },
427
- setSkipPayment(state, action: PayloadAction<boolean>) {
428
- state.skipPaymentWithAgent = action.payload;
429
- },
430
- setGeneratePaymentUrl(state, action: PayloadAction<boolean>) {
431
- state.generatePaymentUrl = action.payload;
432
- },
433
- setPackageGroups(
434
- state,
435
- action: PayloadAction<BookingOptionGroup<PerBookingPackageOption>[]>
436
- ) {
437
- const option = getActiveOption(state);
438
- if (option) option.groups = action.payload;
439
- },
440
- setPackageAirlineGroups(
441
- state,
442
- action: PayloadAction<BookingAirlineGroup<AirlineBookingPackageOption>[]>
443
- ) {
444
- const option = getActiveOption(state);
445
- if (option) option.airlineGroups = action.payload;
446
- },
447
- setPackageAirportGroups(
448
- state,
449
- action: PayloadAction<BookingAirportGroup<AirportBookingPackageOption>[]>
450
- ) {
451
- const option = getActiveOption(state);
452
- if (option) option.airportGroups = action.payload;
453
- },
454
- setTagIds(state, action: PayloadAction<number[] | undefined>) {
455
- state.tagIds = action.payload;
456
- },
457
- setAgentAdressId(state, action: PayloadAction<number | undefined>) {
458
- state.agentAdressId = action.payload;
459
- },
460
- setBookingRemarks(state, action: PayloadAction<string>) {
461
- state.remarks = action.payload;
462
- },
463
- setVoucherCodes(state, action: PayloadAction<string[]>) {
464
- state.voucherCodes = action.payload;
465
- },
466
- setCurrentStep(state, action: PayloadAction<BookingStep>) {
467
- document.body.scrollTop = 0; // For Safari
468
- document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
469
-
470
- state.currentStep = action.payload;
471
- },
472
- setFlights(state, action: PayloadAction<GroupedFlights>) {
473
- if (!state.package) return;
474
-
475
- changeOutwardFlight(state.package, action.payload.selectedOutward);
476
- changeReturnFlight(state.package, action.payload.selectedReturn);
477
- changePackageOption(state.package);
478
- },
479
- setAccommodationViewId(state, action: PayloadAction<number>) {
480
- state.accommodationViewId = action.payload;
481
- },
482
- },
483
- extraReducers: (builder) => {
484
- builder.addCase(fetchPackageDetails.fulfilled, (state, action) => {
485
- if (action.payload) {
486
- if (action.payload.errorCode) {
487
- console.error(
488
- action.payload.errorCode,
489
- action.payload.errorMessage,
490
- action.payload.errorDetails
491
- );
492
-
493
- state.isUnavailable = true;
494
- return;
495
- }
496
-
497
- if (!action.payload.payload) {
498
- state.isUnavailable = true;
499
- return;
500
- }
501
-
502
- const bookingRooms = state.bookingAttributes?.rooms;
503
- const flight = state.bookingAttributes?.flight;
504
- const packageDetails = action.payload.payload;
505
-
506
- let activeOption = packageDetails.options.find((x) => x.isSelected)!;
507
-
508
- if (flight) {
509
- const selectedOutward = packageDetails.outwardFlights.find(
510
- (x) => x.isSelected
511
- );
512
- const outwardFlights = packageDetails.outwardFlights.filter(
513
- (x) =>
514
- x.code === flight.outwardCode &&
515
- x.flightMetaData.flightLines[0]!.flightClass ===
516
- flight.outwardClass &&
517
- x.flightMetaData.flightLines.map((y) => y.number).join(",") ===
518
- flight.outwardNumbers.join(",")
519
- );
520
-
521
- // ook bij identieke vertrekvluchten eerst kijken als de returnflight kan gekoppeld worden.
522
- // op die manier moet het juiste koppel selected worden.
523
- // Enkel werkend met externe vluchten
524
- let outwardFlight: BookingPackageFlight | undefined = undefined;
525
- if (!isEmpty(outwardFlights)) {
526
- const returnExternalGuids = packageDetails.returnFlights
527
- .filter(
528
- (x) =>
529
- x.code === flight.returnCode &&
530
- x.flightMetaData.flightLines[0]!.flightClass ===
531
- flight.returnClass &&
532
- x.flightMetaData.flightLines
533
- .map((y) => y.number)
534
- .join(",") === flight.returnNumbers.join(",")
535
- )
536
- .map((f) => f.externalGuid)
537
- .filter((e) => e);
538
- outwardFlight = outwardFlights.find((o) =>
539
- returnExternalGuids.includes(o.externalGuid)
540
- );
541
- if (!outwardFlight) {
542
- outwardFlight = first(outwardFlights);
543
- }
544
- }
545
-
546
- if (selectedOutward && outwardFlight) {
547
- selectedOutward.isSelected = false;
548
- outwardFlight.isSelected = true;
549
- }
550
-
551
- const selectedReturn = packageDetails.returnFlights.find(
552
- (x) => x.isSelected
553
- );
554
- const returnFlight = outwardFlight?.externalGuid
555
- ? packageDetails.returnFlights.find(
556
- (x) => x.externalGuid === outwardFlight?.externalGuid
557
- )
558
- : packageDetails.returnFlights.find(
559
- (x) =>
560
- x.code === flight.returnCode &&
561
- x.flightMetaData.flightLines[0]!.flightClass ===
562
- flight.returnClass &&
563
- x.flightMetaData.flightLines
564
- .map((y) => y.number)
565
- .join(",") === flight.returnNumbers.join(",")
566
- );
567
-
568
- if (selectedReturn && returnFlight) {
569
- selectedReturn.isSelected = false;
570
- returnFlight.isSelected = true;
571
- }
572
-
573
- if (outwardFlight && returnFlight) {
574
- if (!outwardFlight.validOptions.some((x) => x == activeOption.id)) {
575
- activeOption.isSelected = false;
576
-
577
- activeOption = packageDetails.options.find((x) =>
578
- outwardFlight?.validOptions.some((y) => y === x.id)
579
- )!;
580
- activeOption.isSelected = true;
581
- }
582
- }
583
- }
584
-
585
- if (
586
- activeOption &&
587
- bookingRooms?.some((x) => x.accommodationCode || x.regimeCode)
588
- ) {
589
- bookingRooms.forEach((room, i) => {
590
- if (room.accommodationCode || room.regimeCode) {
591
- activeOption.rooms[i].options = activeOption.rooms[i].options.map(
592
- (ro) => ({
593
- ...ro,
594
- isSelected:
595
- ro.accommodationCode == room.accommodationCode &&
596
- ro.regimeCode == room.regimeCode,
597
- })
598
- );
599
- }
600
-
601
- // Fallback to an option that has the requested accommodation OR regime if the requested option is not available. If no fallback is available, select the first option.
602
- if (!activeOption.rooms[i].options.some((x) => x.isSelected)) {
603
- const fallbackOption = activeOption.rooms[i].options.find(
604
- (x) =>
605
- x.accommodationCode == room.accommodationCode ||
606
- x.regimeCode == room.regimeCode
607
- );
608
- if (fallbackOption) {
609
- fallbackOption.isSelected = true;
610
- } else {
611
- activeOption.rooms[i].options[0].isSelected = true;
612
- }
613
- }
614
- });
615
- }
616
-
617
- state.package = packageDetails;
618
- }
619
- });
620
- builder.addCase(fetchAgents.fulfilled, (state, action) => {
621
- if (action.payload) {
622
- state.agents = action.payload;
623
- }
624
- });
625
- builder.addCase(fetchAccommodationViews.fulfilled, (state, action) => {
626
- if (action.payload) {
627
- state.accommodationViews = action.payload;
628
- }
629
- });
630
- },
631
- });
632
-
633
- export const {
634
- setOfficeId,
635
- setLanguageCode,
636
- setTranslations,
637
- setBookingOptions,
638
- setBookingType,
639
- setProductAttributes,
640
- setBookingAttributes,
641
- setCalculateDeposit,
642
- setBookingNumber,
643
- setIsRetry,
644
- setFetchingPackage,
645
- setPackage,
646
- setPackageRooms,
647
- setPackageOptionPax,
648
- setPackageOptionUnits,
649
- setPackageGroups,
650
- setSkipPayment,
651
- setGeneratePaymentUrl,
652
- setTagIds,
653
- setAgentAdressId,
654
- setBookingRemarks,
655
- setVoucherCodes,
656
- setCurrentStep,
657
- setPackageAirlineGroups,
658
- setPackageAirportGroups,
659
- setFlights,
660
- setAccommodationViewId,
661
- } = bookingSlice.actions;
662
-
663
- export default bookingSlice.reducer;
1
+ import { PayloadAction, createAsyncThunk, createSlice } from "@reduxjs/toolkit";
2
+ import {
3
+ BookingAttributes,
4
+ BookingOptions,
5
+ GroupedFlights,
6
+ ProductAttributes,
7
+ } from "../../types";
8
+
9
+ import {
10
+ AirlineBookingPackageOption,
11
+ AirportBookingPackageOption,
12
+ BookingAirlineGroup,
13
+ BookingAirportGroup,
14
+ BookingOptionGroup,
15
+ BookingOptionPax,
16
+ BookingOptionUnit,
17
+ BookingPackage,
18
+ BookingPackageDetailsRequest,
19
+ BookingPackageFlight,
20
+ BookingPackagePax,
21
+ BookingPackageRequest,
22
+ BookingPackageRequestRoom,
23
+ BookingPackageRoom,
24
+ BookingTravelAgent,
25
+ GenerateBookingAccommodationRequest,
26
+ PerBookingPackageOption,
27
+ SelectedFlight,
28
+ } from "@qite/tide-client/build/types";
29
+ import { first, isEmpty, isNil, range } from "lodash";
30
+ import { RootState } from "../../store";
31
+ import { selectAgentId } from "../travelers-form/travelers-form-slice";
32
+ import packageApi from "./api";
33
+ import { BookingStep, OPTIONS_FORM_STEP } from "./constants";
34
+ import {
35
+ selectAccommodationCodes,
36
+ selectBookingAttributes,
37
+ selectBookingRooms,
38
+ selectLanguageCode,
39
+ selectOfficeId,
40
+ selectProductAttributes,
41
+ selectProductCode,
42
+ } from "./selectors";
43
+
44
+ export interface BookingState {
45
+ officeId: number;
46
+ languageCode: string;
47
+ productAttributes?: ProductAttributes;
48
+ bookingAttributes?: BookingAttributes;
49
+ calculateDeposit: boolean;
50
+ bookingNumber?: string;
51
+ isRetry: boolean;
52
+ package?: BookingPackage;
53
+ agents?: BookingTravelAgent[];
54
+ isBusy: boolean;
55
+ skipPaymentWithAgent: boolean;
56
+ generatePaymentUrl: boolean;
57
+ isUnavailable?: boolean;
58
+ tagIds?: number[];
59
+ agentAdressId?: number;
60
+ remarks?: string;
61
+ voucherCodes?: string[];
62
+ bookingOptions: BookingOptions;
63
+ bookingType: string;
64
+ currentStep: BookingStep;
65
+ translations?: {
66
+ language: string;
67
+ value: any;
68
+ }[];
69
+ accommodationViewId?: number;
70
+ accommodationViews?: { [key: string]: string };
71
+ }
72
+
73
+ const initialState: BookingState = {
74
+ officeId: 1,
75
+ languageCode: "nl-BE",
76
+ bookingOptions: {
77
+ b2b: {
78
+ tagIds: [],
79
+ entryStatus: 2,
80
+ customEntryStatusId: undefined,
81
+ },
82
+ b2b2c: {
83
+ tagIds: [],
84
+ entryStatus: 2,
85
+ customEntryStatusId: undefined,
86
+ },
87
+ b2c: {
88
+ tagIds: [],
89
+ entryStatus: 0,
90
+ customEntryStatusId: undefined,
91
+ },
92
+ },
93
+ bookingType: "b2c",
94
+ productAttributes: undefined,
95
+ bookingAttributes: undefined,
96
+ calculateDeposit: false,
97
+ bookingNumber: undefined,
98
+ isRetry: false,
99
+ package: undefined,
100
+ isBusy: false,
101
+ skipPaymentWithAgent: false,
102
+ generatePaymentUrl: false,
103
+ tagIds: [],
104
+ agentAdressId: undefined,
105
+ currentStep: OPTIONS_FORM_STEP,
106
+ translations: undefined,
107
+ };
108
+
109
+ export const fetchPackage = createAsyncThunk(
110
+ "booking/fetchPackage",
111
+ async (_, { dispatch }) => {
112
+ dispatch(setFetchingPackage(true));
113
+ await dispatch(fetchAgents());
114
+ await dispatch(fetchPackageDetails());
115
+ await dispatch(fetchAccommodationViews());
116
+ dispatch(setFetchingPackage(false));
117
+ }
118
+ );
119
+
120
+ const fetchAgents = createAsyncThunk(
121
+ "booking/agents",
122
+ async (_, { dispatch, getState, signal }) => {
123
+ const settings = getState() as RootState;
124
+ return await packageApi.fetchAgents(signal, settings.apiSettings);
125
+ }
126
+ );
127
+
128
+ const fetchPackageDetails = createAsyncThunk(
129
+ "booking/details",
130
+ async (_, { dispatch, getState, signal }) => {
131
+ const state = getState() as RootState;
132
+
133
+ const officeId = selectOfficeId(state);
134
+ const productAttributes = selectProductAttributes(state);
135
+ const bookingAttributes = selectBookingAttributes(state);
136
+ const agentId = selectAgentId(state);
137
+ const rooms = selectBookingRooms(state);
138
+ const languageCode = selectLanguageCode(state);
139
+
140
+ if (isNil(productAttributes)) {
141
+ throw Error("productAttributes could not be found");
142
+ }
143
+
144
+ if (isNil(bookingAttributes)) {
145
+ throw Error("bookingAttributes could not be found");
146
+ }
147
+
148
+ if (!rooms?.length) {
149
+ throw Error("rooms could not be found");
150
+ }
151
+
152
+ var requestRooms = rooms?.map((x, i) => {
153
+ var room = { index: i, pax: [] } as BookingPackageRequestRoom;
154
+ range(0, x.adults).forEach(() => {
155
+ room.pax.push({
156
+ age: 30,
157
+ } as BookingPackagePax);
158
+ });
159
+ x.childAges.forEach((x) => {
160
+ room.pax.push({
161
+ age: x,
162
+ } as BookingPackagePax);
163
+ });
164
+ return room;
165
+ });
166
+
167
+ const isAllotment =
168
+ bookingAttributes.tourCode ||
169
+ bookingAttributes.allotmentName ||
170
+ (bookingAttributes.allotmentIds && bookingAttributes.allotmentIds.length);
171
+
172
+ let searchType = isAllotment
173
+ ? 1 // ALLOTMENT
174
+ : 0; // DEFAULT;
175
+
176
+ let outwardFlight: SelectedFlight | undefined;
177
+ let returnFlight: SelectedFlight | undefined;
178
+ if (bookingAttributes.flightRouteId && bookingAttributes.flight) {
179
+ searchType = 3; // FLIGHT;
180
+
181
+ outwardFlight = {
182
+ flightCode: bookingAttributes.flight.outwardCode,
183
+ startDateTime: bookingAttributes.flight.outwardDepartureDate,
184
+ endDateTime: bookingAttributes.flight.outwardArrivalDate,
185
+ } as SelectedFlight;
186
+
187
+ if (bookingAttributes.flight.returnCode) {
188
+ returnFlight = {
189
+ flightCode: bookingAttributes.flight.returnCode,
190
+ startDateTime: bookingAttributes.flight.returnDepartureDate,
191
+ endDateTime: bookingAttributes.flight.returnArrivalDate,
192
+ } as SelectedFlight;
193
+ }
194
+ }
195
+
196
+ const request = {
197
+ officeId: officeId,
198
+ agentId: agentId,
199
+ payload: {
200
+ searchType: searchType,
201
+ catalogueId: bookingAttributes.catalog,
202
+ productCode: productAttributes.productCode,
203
+ fromDate: bookingAttributes.startDate,
204
+ toDate: bookingAttributes.endDate,
205
+ includeFlights: bookingAttributes.includeFlights,
206
+ allotmentName: bookingAttributes.allotmentName,
207
+ allotmentIds: bookingAttributes.allotmentIds ?? [],
208
+ tourCode: bookingAttributes.tourCode,
209
+ rooms: requestRooms,
210
+ routeId: bookingAttributes.flightRouteId,
211
+ outwardFlight: outwardFlight,
212
+ returnFlight: returnFlight,
213
+ vendorConfigurationId: bookingAttributes.vendorConfigurationId,
214
+ } as BookingPackageDetailsRequest,
215
+ } as BookingPackageRequest<BookingPackageDetailsRequest>;
216
+
217
+ return await packageApi.fetchDetails(
218
+ request,
219
+ signal,
220
+ languageCode,
221
+ state.apiSettings
222
+ );
223
+ }
224
+ );
225
+
226
+ const fetchAccommodationViews = createAsyncThunk(
227
+ "booking/accommodationViews",
228
+ async (_, { dispatch, getState, signal }) => {
229
+ const state = getState() as RootState;
230
+ if (!state.booking.accommodationViewId) return Promise.resolve();
231
+
232
+ const languageCode = selectLanguageCode(state);
233
+ const accommodationCodes = selectAccommodationCodes(state);
234
+ const productCode = selectProductCode(state);
235
+
236
+ if (!productCode) {
237
+ throw Error("No product selected");
238
+ }
239
+
240
+ const request = {
241
+ languageCode: languageCode,
242
+ productCode: productCode,
243
+ accommodationCodes: accommodationCodes,
244
+ contentViewId: state.booking.accommodationViewId,
245
+ } as GenerateBookingAccommodationRequest;
246
+
247
+ return await packageApi.fetchAccommodationViews(
248
+ request,
249
+ signal,
250
+ state.apiSettings
251
+ );
252
+ }
253
+ );
254
+
255
+ const getActiveOption = (state: BookingState) => {
256
+ if (state.package) return state.package.options.find((x) => x.isSelected);
257
+ return null;
258
+ };
259
+
260
+ const changeOutwardFlight = (
261
+ state: BookingPackage,
262
+ flight: BookingPackageFlight
263
+ ) => {
264
+ const currentOutwardFlight = state.outwardFlights.find((x) => x.isSelected)!;
265
+ const currentReturnFlight = state.returnFlights.find((x) => x.isSelected)!;
266
+
267
+ if (currentOutwardFlight?.entryLineGuid == flight.entryLineGuid) return;
268
+
269
+ const newFlight = state.outwardFlights.find(
270
+ (x) => x.entryLineGuid == flight.entryLineGuid
271
+ );
272
+ if (newFlight) {
273
+ newFlight.isSelected = true;
274
+ currentOutwardFlight.isSelected = false;
275
+
276
+ if (newFlight.externalGuid) {
277
+ if (currentOutwardFlight.externalGuid !== newFlight.externalGuid) {
278
+ const newReturnFlight = state.returnFlights.find(
279
+ (x) => x.externalGuid === newFlight.externalGuid
280
+ )!;
281
+
282
+ currentReturnFlight.isSelected = false;
283
+ newReturnFlight.isSelected = true;
284
+ }
285
+ } else if (currentReturnFlight.externalGuid) {
286
+ const firstInternal = state.returnFlights.find((x) => !x.externalGuid);
287
+
288
+ if (firstInternal) {
289
+ currentReturnFlight.isSelected = false;
290
+ firstInternal.isSelected = true;
291
+ }
292
+ }
293
+ }
294
+ };
295
+
296
+ const changeReturnFlight = (
297
+ state: BookingPackage,
298
+ flight: BookingPackageFlight
299
+ ) => {
300
+ const currentReturnFlight = state.returnFlights.find((x) => x.isSelected)!;
301
+
302
+ if (currentReturnFlight?.entryLineGuid == flight.entryLineGuid) return;
303
+
304
+ const newFlight = state.outwardFlights.find(
305
+ (x) => x.entryLineGuid == flight.entryLineGuid
306
+ );
307
+ if (newFlight) {
308
+ newFlight.isSelected = true;
309
+ currentReturnFlight.isSelected = false;
310
+ }
311
+ };
312
+
313
+ const changePackageOption = (state: BookingPackage) => {
314
+ const selectedOutward = state.outwardFlights.find((x) => x.isSelected)!;
315
+ const selectedReturn = state.returnFlights.find((x) => x.isSelected)!;
316
+ const validOptions = selectedOutward.validOptions.filter((x) =>
317
+ selectedReturn.validOptions.some((y) => x === y)
318
+ );
319
+
320
+ const currentOption = state.options.find((x) => x.isSelected)!;
321
+ if (validOptions.some((x) => x === currentOption.id)) return;
322
+
323
+ const firstOption = state.options.find((x) =>
324
+ validOptions.some((y) => y === x.id)
325
+ )!;
326
+ currentOption.isSelected = false;
327
+ firstOption.isSelected = true;
328
+
329
+ const currentRooms = currentOption.rooms.map((r) => {
330
+ const selectedOption = r.options.find((o) => o.isSelected)!;
331
+
332
+ return {
333
+ accommodation: selectedOption?.accommodationCode,
334
+ regime: selectedOption?.regimeCode,
335
+ };
336
+ });
337
+
338
+ firstOption.rooms.forEach((r, i) => {
339
+ const currentRoom = currentRooms[i];
340
+
341
+ const selectedOption = r.options.find((o) => o.isSelected);
342
+ const selection = r.options.find(
343
+ (x) =>
344
+ x.accommodationCode === currentRoom.accommodation &&
345
+ x.regimeCode === currentRoom.regime
346
+ );
347
+
348
+ if (selection) {
349
+ if (selection.entryLineGuid !== selectedOption?.entryLineGuid) {
350
+ if (selectedOption) selectedOption.isSelected = false;
351
+ selection.isSelected = true;
352
+ }
353
+ } else {
354
+ const accommodationSelection = r.options.find(
355
+ (x) => x.accommodationCode === currentRoom.accommodation
356
+ );
357
+ if (accommodationSelection) {
358
+ if (
359
+ accommodationSelection.entryLineGuid !== selectedOption?.entryLineGuid
360
+ ) {
361
+ if (selectedOption) selectedOption.isSelected = false;
362
+ accommodationSelection.isSelected = true;
363
+ }
364
+ } else {
365
+ const firstOption = r.options[0];
366
+ if (firstOption.entryLineGuid !== selectedOption?.entryLineGuid) {
367
+ if (selectedOption) selectedOption.isSelected = false;
368
+ firstOption.isSelected = true;
369
+ }
370
+ }
371
+ }
372
+ });
373
+ };
374
+
375
+ const bookingSlice = createSlice({
376
+ name: "booking",
377
+ initialState,
378
+ reducers: {
379
+ setOfficeId(state, action: PayloadAction<number>) {
380
+ state.officeId = action.payload;
381
+ },
382
+ setLanguageCode(state, action: PayloadAction<string>) {
383
+ state.languageCode = action.payload;
384
+ },
385
+ setTranslations(state, action: PayloadAction<any>) {
386
+ state.translations = action.payload;
387
+ },
388
+ setBookingOptions(state, action: PayloadAction<BookingOptions>) {
389
+ state.bookingOptions = action.payload;
390
+ },
391
+ setBookingType(state, action: PayloadAction<string>) {
392
+ state.bookingType = action.payload;
393
+ },
394
+ setProductAttributes(state, action: PayloadAction<ProductAttributes>) {
395
+ state.productAttributes = action.payload;
396
+ },
397
+ setBookingAttributes(state, action: PayloadAction<BookingAttributes>) {
398
+ state.bookingAttributes = action.payload;
399
+ },
400
+ setCalculateDeposit(state, action: PayloadAction<boolean>) {
401
+ state.calculateDeposit = action.payload;
402
+ },
403
+ setBookingNumber(state, action: PayloadAction<string>) {
404
+ state.bookingNumber = action.payload;
405
+ },
406
+ setIsRetry(state, action: PayloadAction<boolean>) {
407
+ state.isRetry = action.payload;
408
+ },
409
+ setFetchingPackage(state, action: PayloadAction<boolean>) {
410
+ state.isBusy = action.payload;
411
+ },
412
+ setPackage(state, action: PayloadAction<BookingPackage>) {
413
+ state.package = action.payload;
414
+ },
415
+ setPackageRooms(state, action: PayloadAction<BookingPackageRoom[]>) {
416
+ const option = getActiveOption(state);
417
+ if (option) option.rooms = action.payload;
418
+ },
419
+ setPackageOptionPax(state, action: PayloadAction<BookingOptionPax[]>) {
420
+ const option = getActiveOption(state);
421
+ if (option) option.optionPax = action.payload;
422
+ },
423
+ setPackageOptionUnits(state, action: PayloadAction<BookingOptionUnit[]>) {
424
+ const option = getActiveOption(state);
425
+ if (option) option.optionUnits = action.payload;
426
+ },
427
+ setSkipPayment(state, action: PayloadAction<boolean>) {
428
+ state.skipPaymentWithAgent = action.payload;
429
+ },
430
+ setGeneratePaymentUrl(state, action: PayloadAction<boolean>) {
431
+ state.generatePaymentUrl = action.payload;
432
+ },
433
+ setPackageGroups(
434
+ state,
435
+ action: PayloadAction<BookingOptionGroup<PerBookingPackageOption>[]>
436
+ ) {
437
+ const option = getActiveOption(state);
438
+ if (option) option.groups = action.payload;
439
+ },
440
+ setPackageAirlineGroups(
441
+ state,
442
+ action: PayloadAction<BookingAirlineGroup<AirlineBookingPackageOption>[]>
443
+ ) {
444
+ const option = getActiveOption(state);
445
+ if (option) option.airlineGroups = action.payload;
446
+ },
447
+ setPackageAirportGroups(
448
+ state,
449
+ action: PayloadAction<BookingAirportGroup<AirportBookingPackageOption>[]>
450
+ ) {
451
+ const option = getActiveOption(state);
452
+ if (option) option.airportGroups = action.payload;
453
+ },
454
+ setTagIds(state, action: PayloadAction<number[] | undefined>) {
455
+ state.tagIds = action.payload;
456
+ },
457
+ setAgentAdressId(state, action: PayloadAction<number | undefined>) {
458
+ state.agentAdressId = action.payload;
459
+ },
460
+ setBookingRemarks(state, action: PayloadAction<string>) {
461
+ state.remarks = action.payload;
462
+ },
463
+ setVoucherCodes(state, action: PayloadAction<string[]>) {
464
+ state.voucherCodes = action.payload;
465
+ },
466
+ setCurrentStep(state, action: PayloadAction<BookingStep>) {
467
+ document.body.scrollTop = 0; // For Safari
468
+ document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
469
+
470
+ state.currentStep = action.payload;
471
+ },
472
+ setFlights(state, action: PayloadAction<GroupedFlights>) {
473
+ if (!state.package) return;
474
+
475
+ changeOutwardFlight(state.package, action.payload.selectedOutward);
476
+ changeReturnFlight(state.package, action.payload.selectedReturn);
477
+ changePackageOption(state.package);
478
+ },
479
+ setAccommodationViewId(state, action: PayloadAction<number>) {
480
+ state.accommodationViewId = action.payload;
481
+ },
482
+ },
483
+ extraReducers: (builder) => {
484
+ builder.addCase(fetchPackageDetails.fulfilled, (state, action) => {
485
+ if (action.payload) {
486
+ if (action.payload.errorCode) {
487
+ console.error(
488
+ action.payload.errorCode,
489
+ action.payload.errorMessage,
490
+ action.payload.errorDetails
491
+ );
492
+
493
+ state.isUnavailable = true;
494
+ return;
495
+ }
496
+
497
+ if (!action.payload.payload) {
498
+ state.isUnavailable = true;
499
+ return;
500
+ }
501
+
502
+ const bookingRooms = state.bookingAttributes?.rooms;
503
+ const flight = state.bookingAttributes?.flight;
504
+ const packageDetails = action.payload.payload;
505
+
506
+ let activeOption = packageDetails.options.find((x) => x.isSelected)!;
507
+
508
+ if (flight) {
509
+ const selectedOutward = packageDetails.outwardFlights.find(
510
+ (x) => x.isSelected
511
+ );
512
+ const outwardFlights = packageDetails.outwardFlights.filter(
513
+ (x) =>
514
+ x.code === flight.outwardCode &&
515
+ x.flightMetaData.flightLines[0]!.flightClass ===
516
+ flight.outwardClass &&
517
+ x.flightMetaData.flightLines.map((y) => y.number).join(",") ===
518
+ flight.outwardNumbers.join(",")
519
+ );
520
+
521
+ // ook bij identieke vertrekvluchten eerst kijken als de returnflight kan gekoppeld worden.
522
+ // op die manier moet het juiste koppel selected worden.
523
+ // Enkel werkend met externe vluchten
524
+ let outwardFlight: BookingPackageFlight | undefined = undefined;
525
+ if (!isEmpty(outwardFlights)) {
526
+ const returnExternalGuids = packageDetails.returnFlights
527
+ .filter(
528
+ (x) =>
529
+ x.code === flight.returnCode &&
530
+ x.flightMetaData.flightLines[0]!.flightClass ===
531
+ flight.returnClass &&
532
+ x.flightMetaData.flightLines
533
+ .map((y) => y.number)
534
+ .join(",") === flight.returnNumbers.join(",")
535
+ )
536
+ .map((f) => f.externalGuid)
537
+ .filter((e) => e);
538
+ outwardFlight = outwardFlights.find((o) =>
539
+ returnExternalGuids.includes(o.externalGuid)
540
+ );
541
+ if (!outwardFlight) {
542
+ outwardFlight = first(outwardFlights);
543
+ }
544
+ }
545
+
546
+ if (selectedOutward && outwardFlight) {
547
+ selectedOutward.isSelected = false;
548
+ outwardFlight.isSelected = true;
549
+ }
550
+
551
+ const selectedReturn = packageDetails.returnFlights.find(
552
+ (x) => x.isSelected
553
+ );
554
+ const returnFlight = outwardFlight?.externalGuid
555
+ ? packageDetails.returnFlights.find(
556
+ (x) => x.externalGuid === outwardFlight?.externalGuid
557
+ )
558
+ : packageDetails.returnFlights.find(
559
+ (x) =>
560
+ x.code === flight.returnCode &&
561
+ x.flightMetaData.flightLines[0]!.flightClass ===
562
+ flight.returnClass &&
563
+ x.flightMetaData.flightLines
564
+ .map((y) => y.number)
565
+ .join(",") === flight.returnNumbers.join(",")
566
+ );
567
+
568
+ if (selectedReturn && returnFlight) {
569
+ selectedReturn.isSelected = false;
570
+ returnFlight.isSelected = true;
571
+ }
572
+
573
+ if (outwardFlight && returnFlight) {
574
+ if (!outwardFlight.validOptions.some((x) => x == activeOption.id)) {
575
+ activeOption.isSelected = false;
576
+
577
+ activeOption = packageDetails.options.find((x) =>
578
+ outwardFlight?.validOptions.some((y) => y === x.id)
579
+ )!;
580
+ activeOption.isSelected = true;
581
+ }
582
+ }
583
+ }
584
+
585
+ if (
586
+ activeOption &&
587
+ bookingRooms?.some((x) => x.accommodationCode || x.regimeCode)
588
+ ) {
589
+ bookingRooms.forEach((room, i) => {
590
+ if (room.accommodationCode || room.regimeCode) {
591
+ activeOption.rooms[i].options = activeOption.rooms[i].options.map(
592
+ (ro) => ({
593
+ ...ro,
594
+ isSelected:
595
+ ro.accommodationCode == room.accommodationCode &&
596
+ ro.regimeCode == room.regimeCode,
597
+ })
598
+ );
599
+ }
600
+
601
+ // Fallback to an option that has the requested accommodation OR regime if the requested option is not available. If no fallback is available, select the first option.
602
+ if (!activeOption.rooms[i].options.some((x) => x.isSelected)) {
603
+ const fallbackOption = activeOption.rooms[i].options.find(
604
+ (x) =>
605
+ x.accommodationCode == room.accommodationCode ||
606
+ x.regimeCode == room.regimeCode
607
+ );
608
+ if (fallbackOption) {
609
+ fallbackOption.isSelected = true;
610
+ } else {
611
+ activeOption.rooms[i].options[0].isSelected = true;
612
+ }
613
+ }
614
+ });
615
+ }
616
+
617
+ state.package = packageDetails;
618
+ }
619
+ });
620
+ builder.addCase(fetchAgents.fulfilled, (state, action) => {
621
+ if (action.payload) {
622
+ state.agents = action.payload;
623
+ }
624
+ });
625
+ builder.addCase(fetchAccommodationViews.fulfilled, (state, action) => {
626
+ if (action.payload) {
627
+ state.accommodationViews = action.payload;
628
+ }
629
+ });
630
+ },
631
+ });
632
+
633
+ export const {
634
+ setOfficeId,
635
+ setLanguageCode,
636
+ setTranslations,
637
+ setBookingOptions,
638
+ setBookingType,
639
+ setProductAttributes,
640
+ setBookingAttributes,
641
+ setCalculateDeposit,
642
+ setBookingNumber,
643
+ setIsRetry,
644
+ setFetchingPackage,
645
+ setPackage,
646
+ setPackageRooms,
647
+ setPackageOptionPax,
648
+ setPackageOptionUnits,
649
+ setPackageGroups,
650
+ setSkipPayment,
651
+ setGeneratePaymentUrl,
652
+ setTagIds,
653
+ setAgentAdressId,
654
+ setBookingRemarks,
655
+ setVoucherCodes,
656
+ setCurrentStep,
657
+ setPackageAirlineGroups,
658
+ setPackageAirportGroups,
659
+ setFlights,
660
+ setAccommodationViewId,
661
+ } = bookingSlice.actions;
662
+
663
+ export default bookingSlice.reducer;