ti2-tourplan 1.0.59 → 1.0.61

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.
@@ -0,0 +1 @@
1
+ <?xml version="1.0" encoding="utf-8"?><!DOCTYPE Reply SYSTEM "hostConnect_5_05_000.dtd"><Reply><OptionInfoReply><Option><Opt>AKLACAKLSOFDYNAMC</Opt><OptionNumber>46052</OptionNumber><OptAvail>3</OptAvail></Option></OptionInfoReply></Reply>
@@ -0,0 +1 @@
1
+ <?xml version="1.0" encoding="utf-8"?><!DOCTYPE Reply SYSTEM "hostConnect_5_05_000.dtd"><Reply><OptionInfoReply /></Reply>
@@ -0,0 +1 @@
1
+ <?xml version="1.0" encoding="utf-8"?><!DOCTYPE Reply SYSTEM "hostConnect_5_05_000.dtd"><Reply><OptionInfoReply><Option><Opt>LONTRDAVIDSHDWBVC</Opt><OptionNumber>46051</OptionNumber><OptAvail>-1</OptAvail></Option></OptionInfoReply></Reply>
@@ -0,0 +1 @@
1
+ <?xml version="1.0" encoding="utf-8"?><!DOCTYPE Reply SYSTEM "hostConnect_5_05_000.dtd"><Reply><OptionInfoReply><Option><Opt>FWMACINVCASFBSB</Opt><OptionNumber>4138</OptionNumber><OptAvail>-3 </OptAvail></Option></OptionInfoReply></Reply>
@@ -0,0 +1,54 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE Reply SYSTEM "http://localhost:8080/iCom/hostConnect_4_06_009.dtd">
3
+ <Reply>
4
+ <AgentInfoReply>
5
+ <Currency>GBP</Currency>
6
+ <Email></Email>
7
+ <Name>Audley Travel</Name>
8
+ <PriceCodes>2AU2152GS2CO</PriceCodes>
9
+ <IsSubLogin>N</IsSubLogin>
10
+ <HasBookingRights>N</HasBookingRights>
11
+ <AgentCurrencies>
12
+ <AgentCurrencyInfo>
13
+ <Currency>EUR</Currency>
14
+ <CreditLimit>0</CreditLimit>
15
+ </AgentCurrencyInfo>
16
+ <AgentCurrencyInfo>
17
+ <Currency>GBP</Currency>
18
+ <CreditLimit>0</CreditLimit>
19
+ </AgentCurrencyInfo>
20
+ <AgentCurrencyInfo>
21
+ <Currency>USD</Currency>
22
+ <CreditLimit>0</CreditLimit>
23
+ </AgentCurrencyInfo>
24
+ </AgentCurrencies>
25
+ <Balances>
26
+ <Balance>
27
+ <Currency>GBP</Currency>
28
+ <CurrentBalance>449392</CurrentBalance>
29
+ <Overdue1>0</Overdue1>
30
+ <Overdue2>0</Overdue2>
31
+ <Overdue3>0</Overdue3>
32
+ <Overdue4>14557</Overdue4>
33
+ <FutureEntered>169171190</FutureEntered>
34
+ <Future1>0</Future1>
35
+ <Future2>0</Future2>
36
+ <Future3>0</Future3>
37
+ <Future4>0</Future4>
38
+ </Balance>
39
+ <Balance>
40
+ <Currency>BC</Currency>
41
+ <CurrentBalance>0</CurrentBalance>
42
+ <Overdue1>0</Overdue1>
43
+ <Overdue2>0</Overdue2>
44
+ <Overdue3>0</Overdue3>
45
+ <Overdue4>0</Overdue4>
46
+ <FutureEntered>0</FutureEntered>
47
+ <Future1>0</Future1>
48
+ <Future2>0</Future2>
49
+ <Future3>0</Future3>
50
+ <Future4>0</Future4>
51
+ </Balance>
52
+ </Balances>
53
+ </AgentInfoReply>
54
+ </Reply>
@@ -3240,7 +3240,15 @@ Object {
3240
3240
  }
3241
3241
  `;
3242
3242
 
3243
- exports[`search tests searchAvailabilityForItinerary - bookable 1`] = `
3243
+ exports[`search tests searchAvailabilityForItinerary - bookable - on request 1`] = `
3244
+ Object {
3245
+ "bookable": true,
3246
+ "rates": Array [],
3247
+ "type": "on request",
3248
+ }
3249
+ `;
3250
+
3251
+ exports[`search tests searchAvailabilityForItinerary - bookable - static with inventory 1`] = `
3244
3252
  Object {
3245
3253
  "bookable": true,
3246
3254
  "rates": Array [
@@ -3289,6 +3297,7 @@ Object {
3289
3297
  "rateId": "$NZD48493f27a57b8c65,4,DOUB,C5 B1INF SKB DOUB BRKF",
3290
3298
  },
3291
3299
  ],
3300
+ "type": "inventory",
3292
3301
  }
3293
3302
  `;
3294
3303
 
@@ -3296,84 +3305,6 @@ exports[`search tests searchItineraries 1`] = `
3296
3305
  Object {
3297
3306
  "bookings": Array [
3298
3307
  Object {
3299
- "AccountingDetails": Object {
3300
- "AmountDue": 0,
3301
- "CreditsTotal": 0,
3302
- "FutureBilling": 187795,
3303
- "InvoicedTotal": 0,
3304
- "ReceivedTotal": 0,
3305
- },
3306
- "AgentRef": "2356674/1",
3307
- "BookingId": 316559,
3308
- "BookingStatus": "Quotation",
3309
- "BookingType": "F",
3310
- "BookingUpdateCount": 2,
3311
- "CanAddServices": "Y",
3312
- "CanCancel": "Y",
3313
- "Consult": "",
3314
- "Currency": "GBP",
3315
- "Dialogue": "",
3316
- "Email": "",
3317
- "EnteredDate": "2024-09-12",
3318
- "IsInternetBooking": "Y",
3319
- "Name": "2356674/1 Sean Conta",
3320
- "QB": "Q",
3321
- "ReadOnly": "N",
3322
- "Ref": "ALFI393706",
3323
- "Remarks": "",
3324
- "Services": Array [
3325
- Object {
3326
- "CanAccept": "N",
3327
- "CanUpdate": "N",
3328
- "CancelDeleteStatus": "D",
3329
- "Comment": "Deluxe King Room",
3330
- "CostedInBooking": "Y",
3331
- "Date": "2025-08-13",
3332
- "Description": "Bed and Full Buffet Breakfast",
3333
- "LinePrice": 187795,
3334
- "LocationCode": "LON",
3335
- "Opt": "LONHOSANLONBFBDLX",
3336
- "OptionNumber": 77490,
3337
- "Remarks": "Passenger Notes: NA.
3338
- Service Notes: NA.",
3339
- "RoomConfigs": Object {
3340
- "RoomConfig": Object {
3341
- "Adults": 1,
3342
- "Children": 0,
3343
- "Infants": 0,
3344
- "PaxList": Object {
3345
- "PaxDetails": Object {
3346
- "Forename": "Sean",
3347
- "PaxType": "A",
3348
- "PersonId": 628199,
3349
- "Surname": "Conta",
3350
- "Title": "Mr",
3351
- },
3352
- },
3353
- "RoomType": "DB",
3354
- },
3355
- },
3356
- "SCU": "night",
3357
- "SCUqty": 4,
3358
- "SequenceNumber": 10,
3359
- "ServiceExtras": Object {
3360
- "ServiceExtra": Object {
3361
- "ChargeBasis": "Room",
3362
- "Description": "Extra Bed",
3363
- "IsCompulsory": "N",
3364
- "IsPricePerPerson": "N",
3365
- "Quantity": 1,
3366
- "SequenceNumber": 1,
3367
- },
3368
- },
3369
- "ServiceLineId": 745684,
3370
- "ServiceLineUpdateCount": 1,
3371
- "SupplierName": "Sanderson",
3372
- "paxList": Array [],
3373
- },
3374
- ],
3375
- "TotalPrice": 187795,
3376
- "TravelDate": "2025-08-13",
3377
3308
  "agentRef": "2356674/1",
3378
3309
  "bookingId": "316559",
3379
3310
  "bookingStatus": "Quotation",
package/index.js CHANGED
@@ -525,10 +525,14 @@ class BuyerPlugin {
525
525
  chargeUnitQuantity,
526
526
  },
527
527
  }) {
528
- const model = {
528
+ /*
529
+ Need to S check and A check separately
530
+ because if A check is onRuest, AS will still result in empty response
531
+ */
532
+ const getModel = checkType => ({
529
533
  OptionInfoRequest: {
530
534
  Opt: optionId,
531
- Info: 'S',
535
+ Info: checkType,
532
536
  DateFrom: startDate,
533
537
  SCUqty: (() => {
534
538
  const num = parseInt(chargeUnitQuantity, 10);
@@ -539,12 +543,15 @@ class BuyerPlugin {
539
543
  AgentID: hostConnectAgentID,
540
544
  Password: hostConnectAgentPassword,
541
545
  },
542
- };
543
- const replyObj = await this.callTourplan({
544
- model,
545
- endpoint: hostConnectEndpoint,
546
- axios,
547
- xmlOptions: hostConnectXmlOptions,
546
+ });
547
+ const [SCheck, ACheck] = await Promise.map(['S', 'A'], async checkType => {
548
+ const replyObj = await this.callTourplan({
549
+ model: getModel(checkType),
550
+ endpoint: hostConnectEndpoint,
551
+ axios,
552
+ xmlOptions: hostConnectXmlOptions,
553
+ });
554
+ return R.path(['OptionInfoReply', 'Option'], replyObj);
548
555
  });
549
556
  /*
550
557
  If not rates, optionInfoReply is null, meaning it's not bookable
@@ -589,11 +596,55 @@ class BuyerPlugin {
589
596
  }
590
597
  }
591
598
  */
592
- const optionInfoReply = R.path(['OptionInfoReply'], replyObj);
593
- let OptStayResults = R.pathOr([], ['Option', 'OptStayResults'], optionInfoReply);
599
+ const SCheckPass = Boolean(SCheck);
600
+ const ACheckPass = (() => {
601
+ /*
602
+ FROM TP DOCS:
603
+ Each integer in the list gives the availability for one of the days in the range requested,
604
+ from the start date through to the end date. The integer values are to be interpreted as
605
+ follows:
606
+ Greater than 0 means that inventory is available, with the integer specifying the
607
+ number of units available. For options with a service type of Y , the inventory is in
608
+ units of rooms. For other service types, the inventory is in units of pax.
609
+ -1 Not available.
610
+ -2 Available on free sell.
611
+ -3 Available on request.
612
+ Note: A return value of 0 or something less than -3 is impossible.
613
+ */
614
+ const optAvail = parseInt(R.pathOr('-4', ['OptAvail'], ACheck), 10);
615
+ if (optAvail === -1) {
616
+ return {
617
+ available: false,
618
+ };
619
+ }
620
+ if (optAvail === -2) {
621
+ return {
622
+ available: true,
623
+ type: 'free sell',
624
+ };
625
+ }
626
+ if (optAvail === -3) {
627
+ return {
628
+ available: true,
629
+ type: 'on request',
630
+ };
631
+ }
632
+ if (optAvail > 0) {
633
+ return {
634
+ available: true,
635
+ type: 'inventory',
636
+ quantity: optAvail,
637
+ };
638
+ }
639
+ return {
640
+ available: false,
641
+ };
642
+ })();
643
+ let OptStayResults = R.pathOr([], ['OptStayResults'], SCheck);
594
644
  if (!Array.isArray(OptStayResults)) OptStayResults = [OptStayResults];
595
645
  return {
596
- bookable: Boolean(optionInfoReply),
646
+ bookable: Boolean(SCheckPass || ACheckPass.available),
647
+ type: ACheckPass.type,
597
648
  rates: OptStayResults.map(rate => {
598
649
  let externalRateText = R.pathOr('', ['ExternalRateDetails', 'ExtOptionDescr'], rate);
599
650
  const extRatePlanDescr = R.pathOr('', ['ExternalRateDetails', 'ExtRatePlanDescr'], rate);
@@ -606,166 +657,6 @@ class BuyerPlugin {
606
657
  };
607
658
  }),
608
659
  };
609
- // THE BELOW CODE is for A check, might still need it on user's future request
610
- // const optAvail = parseInt(R.pathOr('-4', ['OptionInfoReply', 'Option', 'OptAvail'], replyObj), 10);
611
- // /*
612
- // FROM TP DOCS:
613
- // Each integer in the list gives the availability for one of the days in the range requested,
614
- // from the start date through to the end date. The integer values are to be interpreted as
615
- // follows:
616
- // Greater than 0 means that inventory is available, with the integer specifying the
617
- // number of units available. For options with a service type of Y , the inventory is in
618
- // units of rooms. For other service types, the inventory is in units of pax.
619
- // -1 Not available.
620
- // -2 Available on free sell.
621
- // -3 Available on request.
622
- // Note: A return value of 0 or something less than -3 is impossible.
623
- // */
624
- // if (optAvail === -1) {
625
- // return {
626
- // available: false,
627
- // };
628
- // }
629
- // if (optAvail === -2) {
630
- // return {
631
- // available: true,
632
- // type: 'free sell',
633
- // };
634
- // }
635
- // if (optAvail === -3) {
636
- // return {
637
- // available: true,
638
- // type: 'on request',
639
- // };
640
- // }
641
- // if (optAvail > 0) {
642
- // return {
643
- // available: true,
644
- // type: 'inventory',
645
- // quantity: optAvail,
646
- // };
647
- // }
648
- // return {
649
- // available: false,
650
- // };
651
- }
652
-
653
-
654
- // TODO: safe to deprecate 7-14 days after release date
655
- async searchQuote({
656
- axios,
657
- token: {
658
- hostConnectEndpoint,
659
- hostConnectAgentID,
660
- hostConnectAgentPassword,
661
- },
662
- payload: {
663
- quoteName,
664
- rateId,
665
- quoteId,
666
- // existingQuoteId,
667
- // existingLineId,
668
- optionId,
669
- startDate,
670
- reference,
671
- /*
672
- paxConfigs: [{ roomType: 'DB', adults: 2 }, { roomType: 'TW', children: 2 }]
673
- */
674
- paxConfigs,
675
- /*
676
- The number of second charge units required (second charge units are discussed
677
- in the OptionInfo section). Should only be specified for options that have SCUs.
678
- Defaults to 1.
679
- */
680
- chargeUnitQuanity,
681
- extras,
682
- puInfo,
683
- doInfo,
684
- notes,
685
- QB,
686
- directHeaderPayload,
687
- directLinePayload,
688
- customFieldValues = [],
689
- },
690
- }) {
691
- const cfvPerService = customFieldValues.filter(f => f.isPerService && f.value)
692
- .reduce((acc, f) => {
693
- if (f.type === 'extended-option') {
694
- acc[f.id] = f.value.value || f.value;
695
- } else {
696
- acc[f.id] = f.value;
697
- }
698
- return acc;
699
- }, {});
700
- const model = {
701
- AddServiceRequest: {
702
- AgentID: hostConnectAgentID,
703
- Password: hostConnectAgentPassword,
704
- ...(quoteId ? {
705
- ExistingBookingInfo: { BookingId: quoteId },
706
- } : {
707
- NewBookingInfo: {
708
- Name: this.escapeInvalidXmlChars(quoteName),
709
- QB: QB || 'Q',
710
- ...(directHeaderPayload || {}),
711
- },
712
- }),
713
- ...(puInfo && (puInfo.time || puInfo.location || puInfo.flightDetails) ? {
714
- ...(puInfo.time && puInfo.time.replace(/\D/g, '') ? {
715
- puTime: puInfo.time.replace(/\D/g, ''),
716
- } : {}),
717
- puRemark: this.escapeInvalidXmlChars(`${puInfo.location ? `Location: ${puInfo.location || 'NA'},` : ''}
718
- ${puInfo.flightDetails ? `Flight: ${puInfo.flightDetails || 'NA'},` : ''}
719
- `),
720
- } : {}),
721
- ...(doInfo && (doInfo.time || doInfo.location || doInfo.flightDetails) ? {
722
- // only get numbers from doInfo.time
723
- ...(doInfo.time && doInfo.time.replace(/\D/g, '') ? {
724
- doTime: doInfo.time.replace(/\D/g, ''),
725
- } : {}),
726
- doRemark: this.escapeInvalidXmlChars(`${doInfo.location ? `Location: ${doInfo.location || 'NA'},` : ''}
727
- ${doInfo.flightDetails ? `Flight: ${doInfo.flightDetails || 'NA'},` : ''}
728
- `),
729
- } : {}),
730
- ...(extras && extras.filter(e => e.selectedExtra && e.selectedExtra.id).length ? {
731
- ExtraQuantities: {
732
- ExtraQuantityItem: extras.filter(e => e.selectedExtra && e.selectedExtra.id).map(e => ({
733
- SequenceNumber: e.selectedExtra.id,
734
- ExtraQuantity: e.quantity,
735
- })),
736
- },
737
- } : {}),
738
- Remarks: this.escapeInvalidXmlChars(notes).slice(0, 220),
739
- Opt: optionId,
740
- DateFrom: startDate,
741
- RateId: rateId || 'Default',
742
- SCUqty: (() => {
743
- const num = parseInt(chargeUnitQuanity, 10);
744
- if (isNaN(num) || num < 1) return 1;
745
- return num;
746
- })(),
747
- AgentRef: reference,
748
- RoomConfigs: this.getRoomConfigs(paxConfigs),
749
- ...(directLinePayload || {}),
750
- ...(cfvPerService || {}),
751
- },
752
- };
753
- const replyObj = await this.callTourplan({
754
- model,
755
- endpoint: hostConnectEndpoint,
756
- axios,
757
- xmlOptions: hostConnectXmlOptions,
758
- });
759
- return {
760
- message: R.path(['AddServiceReply', 'Status'], replyObj)
761
- === 'NO' ? 'Service cannot be added to quote for the requested date/stay. (e.g. no rates, block out period, on request, minimum stay etc.)' : '',
762
- quote: {
763
- id: R.path(['AddServiceReply', 'BookingId'], replyObj) || quoteId,
764
- reference: R.path(['AddServiceReply', 'Ref'], replyObj),
765
- linePrice: R.path(['AddServiceReply', 'Services', 'Service', 'LinePrice'], replyObj),
766
- lineId: R.path(['AddServiceReply', 'ServiceLineId'], replyObj),
767
- },
768
- };
769
660
  }
770
661
 
771
662
  async addServiceToItinerary({
@@ -999,47 +890,27 @@ class BuyerPlugin {
999
890
  const replyObjs = await Promise.all(allSearches);
1000
891
  const bookingHeaders = R.flatten(replyObjs.map(o => R.pathOr([], ['ListBookingsReply', 'BookingHeaders', 'BookingHeader'], o)));
1001
892
  const bookings = await Promise.map(bookingHeaders, async bookingHeader => {
1002
- const getBookingPayload = getPayload('GetBookingRequest', {
1003
- BookingId: R.prop('BookingId', bookingHeader),
1004
- ReturnAccountInfo: 'Y',
1005
- ReturnRoomConfigs: 'Y',
1006
- });
1007
- const bookingReply = await this.callTourplan(getBookingPayload);
1008
- const booking = R.path(['GetBookingReply'], bookingReply);
1009
- const newBooking = await translateItineraryBooking({
1010
- rootValue: booking,
1011
- typeDefs: itineraryBookingTypeDefs,
1012
- query: itineraryBookingQuery,
1013
- });
1014
- // TODO: safe to deprecate 7-14 days after release date
1015
- let Services = R.pathOr([], ['Services', 'Service'], booking);
1016
- if (!Array.isArray(Services)) Services = [Services];
1017
- Services = Services.map(s => {
1018
- let actualRoomConfigs = s.RoomConfigs.RoomConfig;
1019
- if (!Array.isArray(actualRoomConfigs)) actualRoomConfigs = [actualRoomConfigs];
1020
- const paxList = actualRoomConfigs.reduce((acc, roomConfig) => {
1021
- const paxDetails = R.pathOr([], ['PaxList', 'PaxDetails'], roomConfig);
1022
- if (!Array.isArray(paxDetails)) return acc;
1023
- return [...acc, ...paxDetails];
1024
- }, [])
1025
- .map(p => ({
1026
- personId: R.path(['PersonId'], p),
1027
- firstName: R.path(['Forename'], p),
1028
- lastName: R.path(['Surname'], p),
1029
- }));
1030
- return {
1031
- ...s,
1032
- paxList,
1033
- };
1034
- });
1035
- return {
1036
- ...newBooking,
1037
- ...booking,
1038
- Services,
1039
- };
893
+ try {
894
+ const getBookingPayload = getPayload('GetBookingRequest', {
895
+ BookingId: R.prop('BookingId', bookingHeader),
896
+ ReturnAccountInfo: 'Y',
897
+ ReturnRoomConfigs: 'Y',
898
+ });
899
+ const bookingReply = await this.callTourplan(getBookingPayload);
900
+ const booking = R.path(['GetBookingReply'], bookingReply);
901
+ const newBooking = await translateItineraryBooking({
902
+ rootValue: booking,
903
+ typeDefs: itineraryBookingTypeDefs,
904
+ query: itineraryBookingQuery,
905
+ });
906
+ return newBooking;
907
+ } catch (err) {
908
+ console.log('error in searchBooking', err);
909
+ return null;
910
+ }
1040
911
  }, { concurrency: 10 });
1041
912
  return {
1042
- bookings,
913
+ bookings: bookings.filter(b => b),
1043
914
  };
1044
915
  }
1045
916
  }
package/index.test.js CHANGED
@@ -52,7 +52,7 @@ describe('search tests', () => {
52
52
  };
53
53
  const dateFormat = 'DD/MM/YYYY';
54
54
  describe('tooling', () => {
55
- describe.skip('validateToken', () => {
55
+ describe('validateToken', () => {
56
56
  it('valid token', async () => {
57
57
  axios.mockImplementation(getFixture);
58
58
  const retVal = await app.validateToken({
@@ -65,12 +65,12 @@ describe('search tests', () => {
65
65
  axios.mockImplementation(getFixture);
66
66
  const retVal = await app.validateToken({
67
67
  axios,
68
- token: { ...token, username: 'somerandom' },
68
+ token: { ...token, username: 'somerandom', hostConnectAgentPassword: 'somerandom' },
69
69
  });
70
70
  expect(retVal).toBeFalsy();
71
71
  });
72
72
  });
73
- describe.skip('template tests', () => {
73
+ describe('template tests', () => {
74
74
  let template;
75
75
  it('get the template', async () => {
76
76
  template = await app.tokenTemplate();
@@ -96,7 +96,7 @@ describe('search tests', () => {
96
96
  });
97
97
  });
98
98
  });
99
- it.skip('read allotment empty', async () => {
99
+ it('read allotment empty', async () => {
100
100
  const request = axios.mockImplementation(getFixture);
101
101
  const retVal = await app.queryAllotment({
102
102
  axios,
@@ -119,7 +119,7 @@ describe('search tests', () => {
119
119
  expect(sentPayload.Date_From[0]).toBe('2022-08-01');
120
120
  expect(sentPayload.Date_To[0]).toBe('2022-08-15');
121
121
  });
122
- it.skip('read allotment not empty', async () => {
122
+ it('read allotment not empty', async () => {
123
123
  const request = axios.mockImplementation(getFixture);
124
124
  const retVal = await app.queryAllotment({
125
125
  axios,
@@ -155,7 +155,7 @@ describe('search tests', () => {
155
155
  expect(sentPayload.Date_From[0]).toBe('2021-09-02');
156
156
  expect(sentPayload.Date_To[0]).toBe('2021-10-02');
157
157
  });
158
- it.skip('read allotment that applies to more products', async () => {
158
+ it('read allotment that applies to more products', async () => {
159
159
  const request = axios.mockImplementation(getFixture);
160
160
  const retVal = await app.queryAllotment({
161
161
  axios,
@@ -218,7 +218,7 @@ describe('search tests', () => {
218
218
  expect(retVal.bookable).toBeFalsy();
219
219
  expect(retVal.rates.length).toBe(0);
220
220
  });
221
- it('searchAvailabilityForItinerary - bookable', async () => {
221
+ it('searchAvailabilityForItinerary - bookable - static with inventory', async () => {
222
222
  axios.mockImplementation(getFixture);
223
223
  const retVal = await app.searchAvailabilityForItinerary({
224
224
  axios,
@@ -233,6 +233,23 @@ describe('search tests', () => {
233
233
  expect(retVal).toMatchSnapshot();
234
234
  expect(retVal.bookable).toBeTruthy();
235
235
  expect(retVal.rates.length).toBeGreaterThan(0);
236
+ expect(retVal.type).toBe('inventory');
237
+ });
238
+ it('searchAvailabilityForItinerary - bookable - on request', async () => {
239
+ axios.mockImplementation(getFixture);
240
+ const retVal = await app.searchAvailabilityForItinerary({
241
+ axios,
242
+ token,
243
+ payload: {
244
+ optionId: 'FWMACINVCASFBSB',
245
+ startDate: '2025-04-01',
246
+ chargeUnitQuantity: 1,
247
+ paxConfigs: [{ roomType: 'DB', adults: 1 }],
248
+ },
249
+ });
250
+ expect(retVal).toMatchSnapshot();
251
+ expect(retVal.bookable).toBeTruthy();
252
+ expect(retVal.type).toBe('on request');
236
253
  });
237
254
  it('searchItineraries', async () => {
238
255
  axios.mockImplementation(getFixture);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ti2-tourplan",
3
- "version": "1.0.59",
3
+ "version": "1.0.61",
4
4
  "description": "Tourplan's TI2 Plugin",
5
5
  "main": "index.js",
6
6
  "scripts": {