ti2 1.0.10 → 1.0.13
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/README.md +40 -66
- package/api.yml +480 -15
- package/controllers/__tests__/bookings.js +74 -2
- package/controllers/bookings.js +114 -1
- package/jsdoc.conf.json +25 -0
- package/package.json +5 -2
- package/test/plugin.js +386 -3
- package/tutorials/index.json +8 -0
- package/tutorials/plugin-development.md +220 -0
- package/tutorials/setup-your-instance.md +77 -0
|
@@ -11,7 +11,7 @@ describe('user: booking search', () => {
|
|
|
11
11
|
packageName: 'ti2-travelgate',
|
|
12
12
|
adminEmail: 'engineering+travelgate@tourconnect.com',
|
|
13
13
|
};
|
|
14
|
-
|
|
14
|
+
const appKey = newApp.name;
|
|
15
15
|
const userId = '551394be5ac58e5c76000019';
|
|
16
16
|
const token = {
|
|
17
17
|
endpoint: 'https://api.travelgatex.com',
|
|
@@ -77,7 +77,7 @@ describe('user: booking search', () => {
|
|
|
77
77
|
expect(value).toBeTruthy();
|
|
78
78
|
}
|
|
79
79
|
});
|
|
80
|
-
it('should be able to search a
|
|
80
|
+
it('should be able to search a for a booking', async () => {
|
|
81
81
|
const payload = {
|
|
82
82
|
bookingId: '', supplierId: '', name: '',
|
|
83
83
|
};
|
|
@@ -94,4 +94,76 @@ describe('user: booking search', () => {
|
|
|
94
94
|
// expect(Array.isArray(retVal.bookings)).toBeTruthy();
|
|
95
95
|
// expect(retVal.bookings.length > 0).toBeTruthy();
|
|
96
96
|
});
|
|
97
|
+
|
|
98
|
+
it('should be able to search a for a booking product', async () => {
|
|
99
|
+
const payload = {};
|
|
100
|
+
const { products } = await doApiPost({
|
|
101
|
+
url: `/products/${appKey}/${userId}/search`,
|
|
102
|
+
token: userToken,
|
|
103
|
+
payload,
|
|
104
|
+
});
|
|
105
|
+
expect(plugins[0].searchProducts).toHaveBeenCalled();
|
|
106
|
+
expect(Array.isArray(products)).toBeTruthy();
|
|
107
|
+
expect(plugins[0].searchProducts.mock.calls[0][0].payload).toEqual(payload);
|
|
108
|
+
expect(plugins[0].searchProducts.mock.calls[0][0].token).toEqual(token);
|
|
109
|
+
|
|
110
|
+
// expect(Array.isArray(retVal.bookings)).toBeTruthy();
|
|
111
|
+
// expect(retVal.bookings.length > 0).toBeTruthy();
|
|
112
|
+
});
|
|
113
|
+
it('should be able to search for availabiility', async () => {
|
|
114
|
+
const payload = {
|
|
115
|
+
travelDateStart: '12/30/2025',
|
|
116
|
+
travelDateEnd: '01/15/2026',
|
|
117
|
+
dateFormat: 'MM/DD/YYYY',
|
|
118
|
+
occupancies: [{ paxes: [{ age: 30 }, { age: 40 }] }],
|
|
119
|
+
currency: 'EUR',
|
|
120
|
+
market: 'ES',
|
|
121
|
+
language: 'es',
|
|
122
|
+
nationality: 'ES',
|
|
123
|
+
};
|
|
124
|
+
const { availability } = await doApiPost({
|
|
125
|
+
url: `/bookings/${appKey}/${userId}/availability`,
|
|
126
|
+
token: userToken,
|
|
127
|
+
payload,
|
|
128
|
+
});
|
|
129
|
+
expect(plugins[0].searchAvailability).toHaveBeenCalled();
|
|
130
|
+
expect(Array.isArray(availability)).toBeTruthy();
|
|
131
|
+
expect(plugins[0].searchAvailability.mock.calls[0][0].payload).toEqual(payload);
|
|
132
|
+
expect(plugins[0].searchAvailability.mock.calls[0][0].token).toEqual(token);
|
|
133
|
+
});
|
|
134
|
+
it('should be able to obtain a quote', async () => {
|
|
135
|
+
const payload = {
|
|
136
|
+
id: chance.guid(), // availability result id
|
|
137
|
+
travelDateStart: '12/30/2025',
|
|
138
|
+
travelDateEnd: '01/15/2026',
|
|
139
|
+
dateFormat: 'MM/DD/YYYY',
|
|
140
|
+
occupancies: [{ paxes: [{ age: 30 }, { age: 40 }] }],
|
|
141
|
+
currency: 'EUR',
|
|
142
|
+
market: 'ES',
|
|
143
|
+
language: 'es',
|
|
144
|
+
nationality: 'ES',
|
|
145
|
+
};
|
|
146
|
+
const { quote } = await doApiPost({
|
|
147
|
+
url: `/bookings/${appKey}/${userId}/quote`,
|
|
148
|
+
token: userToken,
|
|
149
|
+
payload,
|
|
150
|
+
});
|
|
151
|
+
expect(plugins[0].searchQuote).toHaveBeenCalled();
|
|
152
|
+
expect(Array.isArray(quote)).toBeTruthy();
|
|
153
|
+
expect(plugins[0].searchQuote.mock.calls[0][0].payload).toEqual(payload);
|
|
154
|
+
expect(plugins[0].searchQuote.mock.calls[0][0].token).toEqual(token);
|
|
155
|
+
});
|
|
156
|
+
it('should be able create a booking', async () => {
|
|
157
|
+
const payload = {
|
|
158
|
+
id: chance.guid(),
|
|
159
|
+
};
|
|
160
|
+
await doApiPost({
|
|
161
|
+
url: `/bookings/${appKey}/${userId}/booking`,
|
|
162
|
+
token: userToken,
|
|
163
|
+
payload,
|
|
164
|
+
});
|
|
165
|
+
expect(plugins[0].createBooking).toHaveBeenCalled();
|
|
166
|
+
expect(plugins[0].createBooking.mock.calls[0][0].payload).toEqual(payload);
|
|
167
|
+
expect(plugins[0].createBooking.mock.calls[0][0].token).toEqual(token);
|
|
168
|
+
});
|
|
97
169
|
});
|
package/controllers/bookings.js
CHANGED
|
@@ -25,7 +25,6 @@ const bookingsSearch = plugins => async (req, res, next) => {
|
|
|
25
25
|
});
|
|
26
26
|
return res.json(results);
|
|
27
27
|
} catch (err) {
|
|
28
|
-
console.log({ err });
|
|
29
28
|
return next(err);
|
|
30
29
|
}
|
|
31
30
|
};
|
|
@@ -57,7 +56,121 @@ const bookingsCancel = plugins => async (req, res, next) => {
|
|
|
57
56
|
}
|
|
58
57
|
};
|
|
59
58
|
|
|
59
|
+
const bookingsProductSearch = plugins => async (req, res, next) => {
|
|
60
|
+
const {
|
|
61
|
+
params: { appKey, userId, hint },
|
|
62
|
+
body: payload,
|
|
63
|
+
} = req;
|
|
64
|
+
try {
|
|
65
|
+
const app = plugins.find(({ name }) => name === appKey);
|
|
66
|
+
// const app = load(appKey);
|
|
67
|
+
const userAppKeys = (await UserAppKey.findOne({
|
|
68
|
+
where: {
|
|
69
|
+
userId,
|
|
70
|
+
integrationId: appKey,
|
|
71
|
+
...(hint ? { hint } : {}),
|
|
72
|
+
},
|
|
73
|
+
}));
|
|
74
|
+
assert(userAppKeys, 'could not find the app key');
|
|
75
|
+
const token = userAppKeys.appKey;
|
|
76
|
+
const results = await app.searchProducts({
|
|
77
|
+
token,
|
|
78
|
+
payload,
|
|
79
|
+
});
|
|
80
|
+
return res.json(results);
|
|
81
|
+
} catch (err) {
|
|
82
|
+
return next(err);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const bookingsAvailabilitySearch = plugins => async (req, res, next) => {
|
|
87
|
+
const {
|
|
88
|
+
params: { appKey, userId, hint },
|
|
89
|
+
body: payload,
|
|
90
|
+
} = req;
|
|
91
|
+
try {
|
|
92
|
+
const app = plugins.find(({ name }) => name === appKey);
|
|
93
|
+
// const app = load(appKey);
|
|
94
|
+
const userAppKeys = (await UserAppKey.findOne({
|
|
95
|
+
where: {
|
|
96
|
+
userId,
|
|
97
|
+
integrationId: appKey,
|
|
98
|
+
...(hint ? { hint } : {}),
|
|
99
|
+
},
|
|
100
|
+
}));
|
|
101
|
+
assert(userAppKeys, 'could not find the app key');
|
|
102
|
+
const token = userAppKeys.appKey;
|
|
103
|
+
const results = await app.searchAvailability({
|
|
104
|
+
token,
|
|
105
|
+
payload,
|
|
106
|
+
});
|
|
107
|
+
return res.json(results);
|
|
108
|
+
} catch (err) {
|
|
109
|
+
return next(err);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const searchQuote = plugins => async (req, res, next) => {
|
|
114
|
+
const {
|
|
115
|
+
params: { appKey, userId, hint },
|
|
116
|
+
body: payload,
|
|
117
|
+
} = req;
|
|
118
|
+
try {
|
|
119
|
+
const app = plugins.find(({ name }) => name === appKey);
|
|
120
|
+
// const app = load(appKey);
|
|
121
|
+
const userAppKeys = (await UserAppKey.findOne({
|
|
122
|
+
where: {
|
|
123
|
+
userId,
|
|
124
|
+
integrationId: appKey,
|
|
125
|
+
...(hint ? { hint } : {}),
|
|
126
|
+
},
|
|
127
|
+
}));
|
|
128
|
+
assert(userAppKeys, 'could not find the app key');
|
|
129
|
+
const token = userAppKeys.appKey;
|
|
130
|
+
assert(payload.id, 'the availability id is required');
|
|
131
|
+
const results = await app.searchQuote({
|
|
132
|
+
token,
|
|
133
|
+
payload,
|
|
134
|
+
});
|
|
135
|
+
return res.json(results);
|
|
136
|
+
} catch (err) {
|
|
137
|
+
return next(err);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const createBooking = plugins => async (req, res, next) => {
|
|
142
|
+
const {
|
|
143
|
+
params: { appKey, userId, hint },
|
|
144
|
+
body: payload,
|
|
145
|
+
} = req;
|
|
146
|
+
try {
|
|
147
|
+
const app = plugins.find(({ name }) => name === appKey);
|
|
148
|
+
// const app = load(appKey);
|
|
149
|
+
const userAppKeys = (await UserAppKey.findOne({
|
|
150
|
+
where: {
|
|
151
|
+
userId,
|
|
152
|
+
integrationId: appKey,
|
|
153
|
+
...(hint ? { hint } : {}),
|
|
154
|
+
},
|
|
155
|
+
}));
|
|
156
|
+
assert(userAppKeys, 'could not find the app key');
|
|
157
|
+
const token = userAppKeys.appKey;
|
|
158
|
+
assert(payload.id, 'the quote id is required');
|
|
159
|
+
const results = await app.createBooking({
|
|
160
|
+
token,
|
|
161
|
+
payload,
|
|
162
|
+
});
|
|
163
|
+
return res.json(results);
|
|
164
|
+
} catch (err) {
|
|
165
|
+
return next(err);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
60
169
|
module.exports = plugins => ({
|
|
61
170
|
bookingsSearch: bookingsSearch(plugins),
|
|
62
171
|
bookingsCancel: bookingsCancel(plugins),
|
|
172
|
+
bookingsProductSearch: bookingsProductSearch(plugins),
|
|
173
|
+
bookingsAvailabilitySearch: bookingsAvailabilitySearch(plugins),
|
|
174
|
+
searchQuote: searchQuote(plugins),
|
|
175
|
+
createBooking: createBooking(plugins),
|
|
63
176
|
});
|
package/jsdoc.conf.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tags": {
|
|
3
|
+
"allowUnknownTags": true,
|
|
4
|
+
"dictionaries": ["jsdoc","closure"]
|
|
5
|
+
},
|
|
6
|
+
"source": {
|
|
7
|
+
"include": ["test"],
|
|
8
|
+
"includePattern": ".+\\.js(doc|x)?$",
|
|
9
|
+
"excludePattern": "(^|\\/|\\\\)_"
|
|
10
|
+
},
|
|
11
|
+
"plugins": [
|
|
12
|
+
"plugins/markdown"
|
|
13
|
+
],
|
|
14
|
+
"templates": {
|
|
15
|
+
"cleverLinks": true,
|
|
16
|
+
"monospaceLinks": true
|
|
17
|
+
},
|
|
18
|
+
"opts": {
|
|
19
|
+
"destination": "docs",
|
|
20
|
+
"recurse": true,
|
|
21
|
+
"sort": false,
|
|
22
|
+
"readme": "README.md",
|
|
23
|
+
"template": "node_modules/minami"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ti2",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "Tourist Industry Exchange (TI2)",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "jest",
|
|
8
|
-
"sequelize": "sequelize-cli"
|
|
8
|
+
"sequelize": "sequelize-cli",
|
|
9
|
+
"doc": "jsdoc -c jsdoc.conf.json -u tutorials"
|
|
9
10
|
},
|
|
10
11
|
"repository": {
|
|
11
12
|
"type": "git",
|
|
@@ -39,6 +40,8 @@
|
|
|
39
40
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
40
41
|
"eslint-plugin-import": "^2.25.4",
|
|
41
42
|
"jest": "^27.4.7",
|
|
43
|
+
"jsdoc": "^3.6.10",
|
|
44
|
+
"minami": "git+https://github.com/MyNameReallySux/minami.git#sort-data",
|
|
42
45
|
"supertest": "^6.2.2"
|
|
43
46
|
}
|
|
44
47
|
}
|
package/test/plugin.js
CHANGED
|
@@ -1,17 +1,400 @@
|
|
|
1
|
-
/* global jest */
|
|
1
|
+
/* global jest, expect */
|
|
2
|
+
const chance = require('chance').Chance();
|
|
2
3
|
|
|
3
4
|
class Plugin {
|
|
5
|
+
/**
|
|
6
|
+
* For a comprehensive list of mehtods visit the
|
|
7
|
+
* [Plugin Development]{@tutorial plugin-development} page.
|
|
8
|
+
*
|
|
9
|
+
* ---
|
|
10
|
+
*
|
|
11
|
+
* @param {Object} args - New / Overwriting attributes for the Plugin.
|
|
12
|
+
*/
|
|
4
13
|
constructor(params = {}) {
|
|
5
14
|
Object.entries(params).forEach(([attr, value]) => {
|
|
6
15
|
this[attr] = value;
|
|
7
16
|
});
|
|
17
|
+
// mock implementations
|
|
18
|
+
this.validateToken = jest.fn(() => true);
|
|
19
|
+
this.getProfile = jest.fn(() => {});
|
|
20
|
+
this.updateProfile = jest.fn(() => {});
|
|
21
|
+
this.getProduct = jest.fn(() => ({ products: [] }));
|
|
22
|
+
this.getProducts = jest.fn(() => true);
|
|
23
|
+
this.createLocation = jest.fn(() => ({ locationId: chance.guid() }));
|
|
24
|
+
this.updateLocation = jest.fn(() => true);
|
|
25
|
+
this.searchBooking = jest.fn(() => ({ bookings: [] }));
|
|
26
|
+
this.searchProducts = jest.fn(() => ({ bookings: [], products: [] }));
|
|
27
|
+
this.searchAvailability = jest.fn(({
|
|
28
|
+
token,
|
|
29
|
+
payload: {
|
|
30
|
+
travelDateStart,
|
|
31
|
+
travelDateEnd,
|
|
32
|
+
dateFormat,
|
|
33
|
+
occupancies,
|
|
34
|
+
},
|
|
35
|
+
}) => {
|
|
36
|
+
expect(token).toBeTruthy();
|
|
37
|
+
expect(travelDateStart).toBeTruthy();
|
|
38
|
+
expect(travelDateEnd).toBeTruthy();
|
|
39
|
+
expect(dateFormat).toBeTruthy();
|
|
40
|
+
expect(Array.isArray(occupancies)).toBeTruthy();
|
|
41
|
+
return { availability: [{ id: chance.guid() }] };
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
this.searchQuote = jest.fn(() => ({ quote: [{ id: chance.guid() }] }));
|
|
45
|
+
this.createBooking = jest.fn(() => {});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Check the vailidity of an integration token.
|
|
50
|
+
* @async
|
|
51
|
+
* @param {Object} args - Availability search arguments.
|
|
52
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
53
|
+
* @returns {Boolean} - The token vailidity True/False
|
|
54
|
+
*/
|
|
55
|
+
validateToken() {
|
|
56
|
+
return Boolean(this);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* GPS Location Object
|
|
60
|
+
* @typedef {Object} GPSLocation
|
|
61
|
+
* @property {String} lat - GPS latitude
|
|
62
|
+
* @property {String} lng - GPS Longitude
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Address Object
|
|
67
|
+
* @typedef {Object} Address
|
|
68
|
+
* @property {string} addressOne - Street Address first line of text
|
|
69
|
+
* @property {string} addressTwo - Street Address second line of text
|
|
70
|
+
* @property {string} city - City
|
|
71
|
+
* @property {string} state - State
|
|
72
|
+
* @property {string} zipCode - Zip/Postal Code
|
|
73
|
+
* @property {GPSLocation} loc -Location
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Profile Object
|
|
78
|
+
* @typedef {Object} Profile
|
|
79
|
+
* @property {string} companyName
|
|
80
|
+
* @property {Address} address
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Returns the profile details of the account.
|
|
85
|
+
* @category Methods
|
|
86
|
+
* @subcategory Content
|
|
87
|
+
* Returns the profile details of the account.
|
|
88
|
+
* @async
|
|
89
|
+
* @param {Object} args - Availability search arguments.
|
|
90
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
91
|
+
* @returns {Profile} - The profile details.
|
|
92
|
+
*/
|
|
93
|
+
getProfile() {
|
|
94
|
+
return {};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Updates profile information
|
|
99
|
+
* @async
|
|
100
|
+
* @param {Object} args - Availability search arguments.
|
|
101
|
+
* @param {Profile} args.payload - Updated profile information
|
|
102
|
+
* @returns {boolean} - True/False success status.
|
|
103
|
+
*/
|
|
104
|
+
updateProfile() {
|
|
105
|
+
return {};
|
|
8
106
|
}
|
|
9
107
|
|
|
10
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Location Object
|
|
110
|
+
* @typedef {Object} Location
|
|
111
|
+
* @property {string} telephone
|
|
112
|
+
* @property {Address} address
|
|
113
|
+
*/
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Create a Location
|
|
117
|
+
* @async
|
|
118
|
+
* @param {Object} args - Availability search arguments.
|
|
119
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
120
|
+
* @param {Location} args.payload - The new location details.
|
|
121
|
+
* @returns {Object} retVal - An object containing return values.
|
|
122
|
+
* @returns {string} retVal.locationId - The new location unique identifier.
|
|
123
|
+
*/
|
|
124
|
+
createLocation() {
|
|
125
|
+
return { locationId: chance.guid() };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Update a Location
|
|
130
|
+
* @async
|
|
131
|
+
* @param {Object} args - Availability search arguments.
|
|
132
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
133
|
+
* @param {string} args.locationId - The unique identifier of the location to update.
|
|
134
|
+
* @param {Location} args.payload - The new location details.
|
|
135
|
+
* @returns {boolean} - True/False success status.
|
|
136
|
+
*/
|
|
137
|
+
updateLocation() {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Media Object
|
|
142
|
+
* @typedef {Object} Media - Media Details
|
|
143
|
+
* @property {string} mediaType - MimeType of media
|
|
144
|
+
* @property {string} url - URL of media
|
|
145
|
+
*/
|
|
11
146
|
|
|
12
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Media Collection
|
|
149
|
+
* @typedef {Object} MediaCollection - Media Collection, grouped by type
|
|
150
|
+
* @property {Array.Media} image
|
|
151
|
+
* @property {Array.Media} video
|
|
152
|
+
*/
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Room Object
|
|
156
|
+
* @typedef {Object} RoomInfo - Room details object
|
|
157
|
+
* @property {number} count - Number of rooms
|
|
158
|
+
* @property {string} bedType - Bedding type
|
|
159
|
+
* @property {string} other - Exta Information
|
|
160
|
+
*/
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Value and UUnit spec
|
|
164
|
+
* @typedef {Object} ValueUnit - ValueDetails fields
|
|
165
|
+
* @property {string} unit - A unit specification
|
|
166
|
+
* @property {number} value - The number of units
|
|
167
|
+
*/
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Get the product details related to a location
|
|
171
|
+
* @async
|
|
172
|
+
* @param {Object} args - Availability search arguments.
|
|
173
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
174
|
+
* @param {Object} args.locationId - A location unique identifier for the matching product.
|
|
175
|
+
* @param {Object} args.productId - The product unique identifier.
|
|
176
|
+
* @returns {Object} retVal - A return object.
|
|
177
|
+
* @returns {Product} retVal.product - Details of the matching product.
|
|
178
|
+
*/
|
|
179
|
+
/**
|
|
180
|
+
* ProductInfo type
|
|
181
|
+
* @typedef ProductInfo
|
|
182
|
+
* @property {string} include
|
|
183
|
+
* @property {string} exclude
|
|
184
|
+
* @property {string} whatToBring
|
|
185
|
+
*/
|
|
186
|
+
/**
|
|
187
|
+
* bedsAndSofas type
|
|
188
|
+
* @typedef BedsAndSofas
|
|
189
|
+
* @property {boolean} isApartment
|
|
190
|
+
* @property {numeric} count
|
|
191
|
+
* @property {string} other
|
|
192
|
+
*/
|
|
193
|
+
/**
|
|
194
|
+
* Product Object
|
|
195
|
+
* @typedef {Object} Product - Product information Object
|
|
196
|
+
* @property {string} productId - A unique identifier for a product
|
|
197
|
+
* @property {string} productName
|
|
198
|
+
* @property {('accommodation'|'non-accommodation')} productType
|
|
199
|
+
* @property {string} productCode
|
|
200
|
+
* @property {string} description
|
|
201
|
+
* @property {string} notes
|
|
202
|
+
* @property {string} coverImageUrl
|
|
203
|
+
* @property {boolean} interconnectingRooms
|
|
204
|
+
* @property {string} amenities
|
|
205
|
+
* @property {ValueUnit} roomCountInfo
|
|
206
|
+
* @property {MediaCollection} media
|
|
207
|
+
* @property {ValueUnit} roomSizeInfo
|
|
208
|
+
* @property {ValueUnit} tourDuration
|
|
209
|
+
* @property {number} totalMaxPassengers
|
|
210
|
+
* @property {number} totalMinPassengers
|
|
211
|
+
* @property {ValueUnit} totalDuration
|
|
212
|
+
* @property {boolean} tourDurationDoesNotApply
|
|
213
|
+
* @property {ProductInfo} productInfo
|
|
214
|
+
* @property {BedsAndSofas} bedsAndSofas
|
|
215
|
+
*/
|
|
216
|
+
getProduct() {
|
|
217
|
+
return {};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Get the list of products for a given location
|
|
222
|
+
* @async
|
|
223
|
+
* @param {Object} args - Availability search arguments.
|
|
224
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
225
|
+
* @param {Object} args.locationId - A location unique identifier to get the list of products.
|
|
226
|
+
* @returns {Object} retVal - An object containing return values.
|
|
227
|
+
* @returns {Array.Product} retVal.products - An array of matching products.
|
|
228
|
+
*/
|
|
229
|
+
getProducts() {
|
|
230
|
+
return { products: [] };
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Create a Product
|
|
235
|
+
* @async
|
|
236
|
+
* @param {Object} args - Availability search arguments.
|
|
237
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
238
|
+
* @param {string} args.locationId - The unique identifier of the location that will contain the product.
|
|
239
|
+
* @param {Product} args.payload - The new product details.
|
|
240
|
+
* @returns {Object} retVal - An object containing return values.
|
|
241
|
+
* @returns {string} retVal.locationId - The new location unique identifier.
|
|
242
|
+
*/
|
|
243
|
+
createProduct() {
|
|
244
|
+
return { locationId: chance.guid(), productId: chance.guid() };
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Update a Product
|
|
249
|
+
* @async
|
|
250
|
+
* @param {Object} args - Availability search arguments.
|
|
251
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
252
|
+
* @param {string} args.locationId - The unique identifier of the location that contains the product.
|
|
253
|
+
* @param {string} args.productId - The unique identifier of the product to update.
|
|
254
|
+
* @param {Product} args.payload - The new location details.
|
|
255
|
+
* @returns {boolean} - True/False success status.
|
|
256
|
+
*/
|
|
257
|
+
updateProduct() {
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
13
260
|
|
|
14
261
|
searchHotelBooking = jest.fn(() => ({ bookings: [] }));
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Booking Object
|
|
265
|
+
* @typedef {Object} Booking
|
|
266
|
+
* @property {string} id Booking unique identifier.
|
|
267
|
+
* @property {Cancelled|Active|Pending} status The currrent booking status.
|
|
268
|
+
* @property {Holder} holder Booking holder information.
|
|
269
|
+
* @property {string} telephone Contact telephone.
|
|
270
|
+
* @property {string} supplierId Supplier of the Booking
|
|
271
|
+
* @property {string} hotelId A HotelId if the booking is for an accommodation.
|
|
272
|
+
* @property {string} hotelName A Hotel Name if the booking is for an accommodation.
|
|
273
|
+
* @property {BookingRoom[]} rooms Booking Room details.
|
|
274
|
+
* @property {string} start CheckIn.
|
|
275
|
+
* @property {string} end CheckOut.
|
|
276
|
+
* @property {string} bookingDate Date when the booking was created.
|
|
277
|
+
* @property {numeric} price Total price for the booking.
|
|
278
|
+
* @property {CancelPolicy} cancelPolicy Cancellation policies for the booking.
|
|
279
|
+
*/
|
|
280
|
+
/**
|
|
281
|
+
* Booking Room
|
|
282
|
+
* @typedef {Object} BookingRoom
|
|
283
|
+
* @property {string} roomId
|
|
284
|
+
* @property {string} description
|
|
285
|
+
* @property {numeric} price
|
|
286
|
+
*/
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Cancel Policy
|
|
290
|
+
* @typedef {Object} CancelPolicy
|
|
291
|
+
* @property {boolean} refundable
|
|
292
|
+
* @property {string} cancelPenalties
|
|
293
|
+
*/
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Search for bookings with a criteria.
|
|
297
|
+
* @async
|
|
298
|
+
* @param {Object} args - Booking search arguments.
|
|
299
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
300
|
+
* @param {Object} args.payload - Search criteria object.
|
|
301
|
+
* @param {string} args.payload.bookingId - a Booking Id.
|
|
302
|
+
* @param {string} args.payload.dateFormat - Date format sent, using [momentjs formatting](https://momentjs.com/docs/#/parsing/string-format/).
|
|
303
|
+
* @param {string} args.payload.purchaseDateStart - Date of purchase start.
|
|
304
|
+
* @param {string} args.payload.purchaseDateEnd - Date of purchase end.
|
|
305
|
+
* @param {string} args.payload.travelDateStart - Date of travel start.
|
|
306
|
+
* @param {string} args.payload.travelDateEnd - Date of travel end.
|
|
307
|
+
* @param {Holder} args.payload.holder - Search for a particular holder.
|
|
308
|
+
* @returns {object} retVal - the return object.
|
|
309
|
+
* @returns {Booking[]} retVal.bookings - Array of Bookings matchin the criteria.
|
|
310
|
+
*/
|
|
311
|
+
searchBooking() {
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Search for bookable products
|
|
316
|
+
* @async
|
|
317
|
+
* @param {Object} args - Product search arguments.
|
|
318
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
319
|
+
* @param {Object} args.payload - Search criteria object.
|
|
320
|
+
* @returns {object} retVal - the return object.
|
|
321
|
+
* @returns {Hotel[]} retVal.hotels - Array of bookable hotels.
|
|
322
|
+
* @returns {Product[]} retVal.products - Array of bookable activities.
|
|
323
|
+
* @todo Define search criteria and Hotel/Product spec.
|
|
324
|
+
*/
|
|
325
|
+
searchProducts() {
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Occupancy Object
|
|
330
|
+
* @typedef {Object} Occupancy
|
|
331
|
+
* @property {Pax[]} paxes
|
|
332
|
+
*/
|
|
333
|
+
/**
|
|
334
|
+
* A Pax item with an age spec.
|
|
335
|
+
* @typedef {Object} Pax
|
|
336
|
+
* @property {number} age Age in years of the pax when the startDate starts on local timezone.
|
|
337
|
+
*/
|
|
338
|
+
/**
|
|
339
|
+
* An availability return spec.
|
|
340
|
+
* @typedef {Object} Availability
|
|
341
|
+
* @property {string} id An identifier that can be used to retrieve a quote.
|
|
342
|
+
*/
|
|
343
|
+
/**
|
|
344
|
+
* A booking holder spec.
|
|
345
|
+
* @typedef {Object} Holder
|
|
346
|
+
* @property {string} name The booking's holder first name (s).
|
|
347
|
+
* @property {string} surname Surname / Last Name(s) for the booking holder.
|
|
348
|
+
* @property {string} email The booking's holder email.
|
|
349
|
+
*/
|
|
350
|
+
/**
|
|
351
|
+
* Search for availability of products winthin dates of travel.
|
|
352
|
+
* @async
|
|
353
|
+
* @param {Object} args - Availability search arguments.
|
|
354
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
355
|
+
* @param {Object} args.payload - Search spect object.
|
|
356
|
+
* @param {string} args.payload.dateFormat - Date format sent, using [momentjs formatting](https://momentjs.com/docs/#/parsing/string-format/).
|
|
357
|
+
* @param {string} args.payload.travelDateStart - Date of travel start.
|
|
358
|
+
* @param {string} args.payload.travelDateEnd - Date of travel end.
|
|
359
|
+
* @param {Occupancy[]} args.payload.occupancies - Occupancy detail.
|
|
360
|
+
* @returns {object} retVal - the return object
|
|
361
|
+
* @returns {Availability[]} retVal.availability - Array of availability objects
|
|
362
|
+
*/
|
|
363
|
+
searchAvailability() {
|
|
364
|
+
// return (args);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* A quote return spec
|
|
369
|
+
* @typedef {Object} Quote
|
|
370
|
+
* @property {string} id An identifier that can be used to create a booking.
|
|
371
|
+
*/
|
|
372
|
+
/**
|
|
373
|
+
* Quote an availability.
|
|
374
|
+
* @async
|
|
375
|
+
* @param {Object} args - Availability quote arguments.
|
|
376
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
377
|
+
* @param {Object} args.payload - Search spect object.
|
|
378
|
+
* @param {string} args.payload.id - An availability Id.
|
|
379
|
+
* @returns {object} retVal - the return object.
|
|
380
|
+
* @returns {Quote} retVal.quote - A Quote Object instance.
|
|
381
|
+
*/
|
|
382
|
+
searchQuote() {
|
|
383
|
+
// return (args);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Create a Booking
|
|
388
|
+
* @async
|
|
389
|
+
* @param {Object} args - Booking arguments.
|
|
390
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
391
|
+
* @param {Object} args.payload - Search spect object.
|
|
392
|
+
* @param {string} args.payload.id - A quote id.
|
|
393
|
+
* @param {Holder} args.payload.holder - Contact information of the booking holder.
|
|
394
|
+
* @returns {object} retVal - the return object.
|
|
395
|
+
* @returns {Booking} retVal.booking - A Booking object.
|
|
396
|
+
*/
|
|
397
|
+
createBooking() {}
|
|
15
398
|
}
|
|
16
399
|
|
|
17
400
|
module.exports = Plugin;
|