ti2-tourplan 1.0.41 → 1.0.42
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 +60 -54
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -170,13 +170,14 @@ class Plugin {
|
|
|
170
170
|
}
|
|
171
171
|
const requestType = R.keys(model)[0];
|
|
172
172
|
if (!replyObj) throw new Error(`${requestType} failed: ${errorStr || 'no reply object'}`);
|
|
173
|
-
|
|
173
|
+
let error = replyObj.error || R.path(['Reply', 'ErrorReply', 'Error'], replyObj);
|
|
174
174
|
if (error) {
|
|
175
|
-
if (error.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
175
|
+
if (error.includes('DateFrom in the past')) {
|
|
176
|
+
error = '1002 - Date is in the past';
|
|
177
|
+
} else if (error.includes('1052 SCN')) {
|
|
178
|
+
error = '1052 - OptionId not found(Check if it is Internet Enabled)';
|
|
179
|
+
} else if (error.includes('SCN Server overloaded')) {
|
|
180
|
+
error = "2051 - The Tourplan server is unavailable. Please wait a minute and try again. If you keep getting this error, please contact your team's Tourplan administrator or Tourplan support."
|
|
180
181
|
}
|
|
181
182
|
throw new Error(`${requestType} failed: ${error}`);
|
|
182
183
|
}
|
|
@@ -442,50 +443,57 @@ class Plugin {
|
|
|
442
443
|
xmlOptions: hostConnectXmlOptions,
|
|
443
444
|
};
|
|
444
445
|
// use cache if we are getting the full list
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
root => {
|
|
482
|
-
const
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
446
|
+
// for example: for searchInput (backend search), we shouldn't get the full list from
|
|
447
|
+
// tourplan each time user search
|
|
448
|
+
const replyObj = optionId
|
|
449
|
+
? await this.callTourplan(payload)
|
|
450
|
+
: await this.cache.getOrExec({
|
|
451
|
+
fnParams: [model],
|
|
452
|
+
fn: () => this.callTourplan(payload),
|
|
453
|
+
ttl: 60 * 60 * 2, // 2 hours
|
|
454
|
+
forceRefresh: Boolean(forceRefresh),
|
|
455
|
+
});
|
|
456
|
+
const products = R.call(R.compose(
|
|
457
|
+
R.map(optionsGroupedBySupplierId => {
|
|
458
|
+
const OptGeneral = R.pathOr({}, [0, 'OptGeneral'], optionsGroupedBySupplierId);
|
|
459
|
+
const supplierData = {
|
|
460
|
+
supplierId: R.path(['SupplierId'], OptGeneral),
|
|
461
|
+
supplierName: R.path(['SupplierName'], OptGeneral),
|
|
462
|
+
supplierAddress: `${R.pathOr('', ['Address1'], OptGeneral)}, ${R.pathOr('', ['Address2'], OptGeneral)}, ${R.pathOr('', ['Address3'], OptGeneral)}, ${R.pathOr('', ['Address4'], OptGeneral)}, ${R.pathOr('', ['Address5'], OptGeneral)}`,
|
|
463
|
+
serviceTypes: R.uniq(optionsGroupedBySupplierId.map(R.path(['OptGeneral', 'ButtonName']))),
|
|
464
|
+
};
|
|
465
|
+
return translateTPOption({
|
|
466
|
+
supplierData,
|
|
467
|
+
optionsGroupedBySupplierId,
|
|
468
|
+
typeDefs: productTypeDefs,
|
|
469
|
+
query: productQuery,
|
|
470
|
+
});
|
|
471
|
+
}),
|
|
472
|
+
R.values,
|
|
473
|
+
R.groupBy(R.path(['OptGeneral', 'SupplierId'])),
|
|
474
|
+
root => {
|
|
475
|
+
if (!searchInput) return root;
|
|
476
|
+
const getFullSearchStr = o => {
|
|
477
|
+
const fullPptionName = `${R.path(['OptGeneral', 'Description'], o) || ''}-${R.path(['OptGeneral', 'Comment'], o) || ''}`;
|
|
478
|
+
return `${R.path(['OptGeneral', 'SupplierName'], o) || ''} ${fullPptionName} ${R.path(['Opt'], o)} ${R.path(['OptGeneral', 'SupplierId'], o) || ''}`;
|
|
479
|
+
};
|
|
480
|
+
const inputValueLower = searchInput.trim().toLowerCase();
|
|
481
|
+
const parts = inputValueLower.split(' ').filter(Boolean); // Filter out any empty strings just in case
|
|
482
|
+
return root.filter(option => {
|
|
483
|
+
const fullSearchStr = getFullSearchStr(option).toLowerCase();
|
|
484
|
+
return parts.every(part => fullSearchStr.includes(part));
|
|
485
|
+
});
|
|
486
|
+
},
|
|
487
|
+
root => {
|
|
488
|
+
const options = R.pathOr([], ['OptionInfoReply', 'Option'], root);
|
|
489
|
+
// due to the new parser, single option will be returned as an object
|
|
490
|
+
// instead of an array
|
|
491
|
+
if (Array.isArray(options)) return options;
|
|
492
|
+
return [options];
|
|
493
|
+
},
|
|
494
|
+
), replyObj);
|
|
495
|
+
if (!(products && products.length)) {
|
|
496
|
+
throw new Error('No products found');
|
|
489
497
|
}
|
|
490
498
|
return {
|
|
491
499
|
products,
|
|
@@ -673,8 +681,7 @@ class Plugin {
|
|
|
673
681
|
...(puInfo.time && puInfo.time.replace(/\D/g, '') ? {
|
|
674
682
|
puTime: puInfo.time.replace(/\D/g, ''),
|
|
675
683
|
} : {}),
|
|
676
|
-
puRemark: this.escapeInvalidXmlChars(`${puInfo.
|
|
677
|
-
${puInfo.location ? `Location: ${puInfo.location || 'NA'},` : ''}
|
|
684
|
+
puRemark: this.escapeInvalidXmlChars(`${puInfo.location ? `Location: ${puInfo.location || 'NA'},` : ''}
|
|
678
685
|
${puInfo.flightDetails ? `Flight: ${puInfo.flightDetails || 'NA'},` : ''}
|
|
679
686
|
`),
|
|
680
687
|
} : {}),
|
|
@@ -683,8 +690,7 @@ class Plugin {
|
|
|
683
690
|
...(doInfo.time && doInfo.time.replace(/\D/g, '') ? {
|
|
684
691
|
doTime: doInfo.time.replace(/\D/g, ''),
|
|
685
692
|
} : {}),
|
|
686
|
-
doRemark: this.escapeInvalidXmlChars(`${doInfo.
|
|
687
|
-
${doInfo.location ? `Location: ${doInfo.location || 'NA'},` : ''}
|
|
693
|
+
doRemark: this.escapeInvalidXmlChars(`${doInfo.location ? `Location: ${doInfo.location || 'NA'},` : ''}
|
|
688
694
|
${doInfo.flightDetails ? `Flight: ${doInfo.flightDetails || 'NA'},` : ''}
|
|
689
695
|
`),
|
|
690
696
|
} : {}),
|