ti2-tourplan 1.0.37 → 1.0.39

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.
package/index.js CHANGED
@@ -201,7 +201,7 @@ class Plugin {
201
201
  Double: 'DB',
202
202
  Twin: 'TW',
203
203
  Triple: 'TR',
204
- Quad: 'QU',
204
+ Quad: 'QD',
205
205
  })[roomType];
206
206
  if (RoomType) RoomConfig.RoomType = RoomType;
207
207
  if (passengers && passengers.length && !noPaxList) {
@@ -214,10 +214,10 @@ class Plugin {
214
214
  Child: 'C',
215
215
  Infant: 'I',
216
216
  }[p.passengerType] || 'A',
217
- Title: p.salutation,
218
217
  };
218
+ if (p.salutation) PaxDetails.Title = p.salutation;
219
219
  if (p.dob) PaxDetails.DateOfBirth = p.dob;
220
- if (!isNaN(p.age)) {
220
+ if (!R.isNil(p.age) && !isNaN(p.age)) {
221
221
  if (!(p.passengerType === 'Adult' && p.age === 0)) {
222
222
  PaxDetails.Age = p.age;
223
223
  }
@@ -242,7 +242,12 @@ class Plugin {
242
242
  .replace(/>/g, '>')
243
243
  .replace(/"/g, '"')
244
244
  .replace(/'/g, ''')
245
- }
245
+ };
246
+
247
+ // this.errorPathsAxiosErrors = () => ([ // axios triggered errors
248
+ // ['response', 'data', 'error'],
249
+ // ]);
250
+ // this.errorPathsAxiosAny = () => ([]); // 200's that should be errors
246
251
  }
247
252
 
248
253
  async validateToken({
@@ -518,9 +523,13 @@ class Plugin {
518
523
  const model = {
519
524
  OptionInfoRequest: {
520
525
  Opt: optionId,
521
- Info: 'A',
526
+ Info: 'S',
522
527
  DateFrom: startDate,
523
- DateTo: startDate,
528
+ SCUqty: (() => {
529
+ const num = parseInt(chargeUnitQuanity, 10);
530
+ if (isNaN(num) || num < 1) return 1;
531
+ return num;
532
+ })(),
524
533
  RoomConfigs: this.getPaxConfigs(paxConfigs, true),
525
534
  AgentID: hostConnectAgentID,
526
535
  Password: hostConnectAgentPassword,
@@ -532,47 +541,84 @@ class Plugin {
532
541
  axios,
533
542
  xmlOptions: hostConnectXmlOptions,
534
543
  });
535
- const optAvail = R.path(['OptionInfoReply', 'Option', 'OptAvail'], replyObj);
536
544
  /*
537
- FROM TP DOCS:
538
- Each integer in the list gives the availability for one of the days in the range requested,
539
- from the start date through to the end date. The integer values are to be interpreted as
540
- follows:
541
- Greater than 0 means that inventory is available, with the integer specifying the
542
- number of units available. For options with a service type of Y , the inventory is in
543
- units of rooms. For other service types, the inventory is in units of pax.
544
- -1 Not available.
545
- -2 Available on free sell.
546
- -3 Available on request.
547
- Note: A return value of 0 or something less than -3 is impossible.
545
+ If not rates, optionInfoReply is null, meaning it's not bookable
546
+ otherwise, example data:
547
+ {
548
+ optionInfoReply: {
549
+ Option: {
550
+ Opt: 'LHRTRDAVIDSHABTVC',
551
+ OptStayResults: {
552
+ AgentPrice: '51175',
553
+ Availability: 'RQ',
554
+ CancelHours: '96',
555
+ CommissionPercent: '0.00',
556
+ Currency: 'GBP',
557
+ PeriodValueAdds: {
558
+ PeriodValueAdd: {
559
+ DateFrom: '2024-08-10',
560
+ DateTo: '2024-08-10',
561
+ RateName: 'Std-Mon Sun',
562
+ RateText: 'Std'
563
+ }
564
+ },
565
+ RateId: 'Default',
566
+ RateName: 'Std-Mon Sun',
567
+ RateText: 'Std',
568
+ SaleFrom: '2023-12-20',
569
+ TotalPrice: '51175'
570
+ },
571
+ OptionNumber: '70461'
572
+ }
573
+ }
574
+ }
548
575
  */
549
- if (optAvail === -1) {
550
- return {
551
- available: false,
552
- };
553
- }
554
- if (optAvail === -2) {
555
- return {
556
- available: true,
557
- type: 'free sell',
558
- };
559
- }
560
- if (optAvail === -3) {
561
- return {
562
- available: true,
563
- type: 'on request',
564
- };
565
- }
566
- if (optAvail > 0) {
567
- return {
568
- available: true,
569
- type: 'inventory',
570
- quantity: optAvail,
571
- };
572
- }
576
+ const optionInfoReply = R.path(['OptionInfoReply'], replyObj);
573
577
  return {
574
- available: false,
578
+ bookable: Boolean(optionInfoReply),
575
579
  };
580
+ // THE BELOW CODE is for A check, might still need it on user's future request
581
+ // const optAvail = parseInt(R.pathOr('-4', ['OptionInfoReply', 'Option', 'OptAvail'], replyObj), 10);
582
+ // /*
583
+ // FROM TP DOCS:
584
+ // Each integer in the list gives the availability for one of the days in the range requested,
585
+ // from the start date through to the end date. The integer values are to be interpreted as
586
+ // follows:
587
+ // Greater than 0 means that inventory is available, with the integer specifying the
588
+ // number of units available. For options with a service type of Y , the inventory is in
589
+ // units of rooms. For other service types, the inventory is in units of pax.
590
+ // -1 Not available.
591
+ // -2 Available on free sell.
592
+ // -3 Available on request.
593
+ // Note: A return value of 0 or something less than -3 is impossible.
594
+ // */
595
+ // if (optAvail === -1) {
596
+ // return {
597
+ // available: false,
598
+ // };
599
+ // }
600
+ // if (optAvail === -2) {
601
+ // return {
602
+ // available: true,
603
+ // type: 'free sell',
604
+ // };
605
+ // }
606
+ // if (optAvail === -3) {
607
+ // return {
608
+ // available: true,
609
+ // type: 'on request',
610
+ // };
611
+ // }
612
+ // if (optAvail > 0) {
613
+ // return {
614
+ // available: true,
615
+ // type: 'inventory',
616
+ // quantity: optAvail,
617
+ // };
618
+ // }
619
+ // return {
620
+ // available: false,
621
+ // };
576
622
  }
577
623
 
578
624
  async searchQuote({
@@ -625,30 +671,34 @@ class Plugin {
625
671
  ...(rateId ? {
626
672
  RateId: rateId,
627
673
  } : {}),
628
- ...(puInfo ? {
674
+ ...(puInfo && (puInfo.time || puInfo.location || puInfo.flightDetails) ? {
629
675
  ...(puInfo.time && puInfo.time.replace(/\D/g, '') ? {
630
676
  puTime: puInfo.time.replace(/\D/g, ''),
631
677
  } : {}),
632
- puRemark: this.escapeInvalidXmlChars(`Time: ${puInfo.time || 'NA'},
633
- Location: ${puInfo.location || 'NA'},
634
- Flight: ${puInfo.flightDetails || 'NA'},
678
+ puRemark: this.escapeInvalidXmlChars(`${puInfo.time ? `Time: ${puInfo.time || 'NA'},` : ''}
679
+ ${puInfo.location ? `Location: ${puInfo.location || 'NA'},` : ''}
680
+ ${puInfo.flightDetails ? `Flight: ${puInfo.flightDetails || 'NA'},` : ''}
635
681
  `),
636
682
  } : {}),
637
- ...(doInfo ? {
683
+ ...(doInfo && (doInfo.time || doInfo.location || doInfo.flightDetails) ? {
638
684
  // only get numbers from doInfo.time
639
685
  ...(doInfo.time && doInfo.time.replace(/\D/g, '') ? {
640
686
  doTime: doInfo.time.replace(/\D/g, ''),
641
687
  } : {}),
642
- doRemark: this.escapeInvalidXmlChars(`Time: ${doInfo.time || 'NA'},
643
- Location: ${doInfo.location || 'NA'},
644
- Flight: ${doInfo.flightDetails || 'NA'},
688
+ doRemark: this.escapeInvalidXmlChars(`${doInfo.time ? `Time: ${doInfo.time || 'NA'},` : ''}
689
+ ${doInfo.location ? `Location: ${doInfo.location || 'NA'},` : ''}
690
+ ${doInfo.flightDetails ? `Flight: ${doInfo.flightDetails || 'NA'},` : ''}
645
691
  `),
646
692
  } : {}),
647
- Remarks: this.escapeInvalidXmlChars(`${notes || ''} ${extraText ? `\nExtras: ${extraText}` : ''}`),
693
+ Remarks: this.escapeInvalidXmlChars(`${notes || ''} ${extraText ? `\nExtras: ${extraText}` : ''}`).slice(0, 240),
648
694
  Opt: optionId,
649
695
  DateFrom: startDate,
650
696
  RateId: 'Default',
651
- SCUqty: chargeUnitQuanity || 1,
697
+ SCUqty: (() => {
698
+ const num = parseInt(chargeUnitQuanity, 10);
699
+ if (isNaN(num) || num < 1) return 1;
700
+ return num;
701
+ })(),
652
702
  AgentRef: reference,
653
703
  RoomConfigs: this.getPaxConfigs(paxConfigs),
654
704
  },
@@ -661,7 +711,7 @@ class Plugin {
661
711
  });
662
712
  return {
663
713
  message: R.path(['AddServiceReply', 'Status'], replyObj)
664
- === 'NO' ? 'Service cannot be added to quote' : '',
714
+ === 'NO' ? 'Service cannot be added to quote (could be due to no rates)' : '',
665
715
  quote: {
666
716
  id: R.path(['AddServiceReply', 'BookingId'], replyObj),
667
717
  reference: R.path(['AddServiceReply', 'Ref'], replyObj),
@@ -722,6 +772,10 @@ class Plugin {
722
772
  try {
723
773
  reply = await this.callTourplan(getPayload('ListBookingsRequest', { [key]: bookingId }));
724
774
  } catch (err) {
775
+ if (err.includes && err.includes('Request failed with status code')) {
776
+ throw Error(err);
777
+ }
778
+ // if it's not server error, we just considered as no booking is found
725
779
  console.log('error in searchBooking', err);
726
780
  reply = { ListBookingsReply: { BookingHeaders: { BookingHeader: [] } } };
727
781
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ti2-tourplan",
3
- "version": "1.0.37",
3
+ "version": "1.0.39",
4
4
  "description": "Tourplan's TI2 Plugin",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -123,15 +123,16 @@ const translateTPOption = ({ optionsGroupedBySupplierId, supplierData }) => {
123
123
  } : null].filter(Boolean);
124
124
  }
125
125
  if (R.path(['OptGeneral', 'SType'], option) === 'Y' || R.path(['OptGeneral', 'SType'], option) === 'P') {
126
+ console.log('hit here')
126
127
  return ['Single', 'Twin', 'Double', 'Quad']
127
- .map(([unitId, unitName]) => ({
128
+ .map((unitId) => ({
128
129
  unitId,
129
- unitName,
130
+ unitName: unitId,
130
131
  pricing: [],
131
132
  restrictions: {
132
- allowed: R.path(['OptGeneral', `${unitName}_Avail`], option) === 'Y',
133
- paxCount: R.path(['OptGeneral', `${unitName}_Max`], option)
134
- || R.path(['OptGeneral', `${unitName}_Ad_Max`], option),
133
+ allowed: R.path(['OptGeneral', `${unitId}_Avail`], option) === 'Y',
134
+ paxCount: R.path(['OptGeneral', `${unitId}_Max`], option)
135
+ || R.path(['OptGeneral', `${unitId}_Ad_Max`], option),
135
136
  },
136
137
  }));
137
138
  }