ti2 1.0.10 → 1.0.11
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 +28 -9
- 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 +401 -3
package/README.md
CHANGED
|
@@ -37,10 +37,10 @@ Some environment variables are required for ti2 to start
|
|
|
37
37
|
|
|
38
38
|
### Starting your server
|
|
39
39
|
|
|
40
|
-
You can start your own instance by
|
|
40
|
+
You can start your own instance by instlling ti2 and any aplugin syou may want to use on your own nodejs project root folter:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
$ npm i ti2
|
|
43
|
+
$ npm i ti2 ti2-travelgate ti2-ventrata ti2-tourconnect
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
To start the server with default values use the following:
|
|
@@ -67,12 +67,31 @@ Plugin ENV variable name convention: ti2_pluginName_environmenVariableName, for
|
|
|
67
67
|
ti2_tourconnect_apiUrl=http://backend:8080
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
###
|
|
71
|
-
|
|
72
|
-
|
|
|
73
|
-
| ---- | -------- | ---------- |
|
|
74
|
-
|
|
75
|
-
|
|
|
70
|
+
### Plugin Library
|
|
71
|
+
|
|
72
|
+
| Methods | [Ventrata](https://github.com/TourConnect/ti2-ventrata) | [TravelGateX](https://github.com/TourConnect/ti2-travelgate) | [Didgigo](https://github.com/TourConnect/ti2-didgigo) | [TourConnect](https://github.com/TourConnect/ti2-tourconnect)
|
|
73
|
+
| ---- | -------- | ---------- | ---- | ---- |
|
|
74
|
+
|**Base**|
|
|
75
|
+
|validateToken|||✓|✓|
|
|
76
|
+
|copyMedia||||✓|
|
|
77
|
+
|**Content**|
|
|
78
|
+
|getProfile|||✓|✓|
|
|
79
|
+
|updateProfile||||✓|
|
|
80
|
+
|getLocations|||✓|✓|
|
|
81
|
+
|getLocation|||✓|✓|
|
|
82
|
+
|createLocation|||✓|✓|
|
|
83
|
+
|updateLocation|||✓|✓|
|
|
84
|
+
|getProducts|||✓|✓|
|
|
85
|
+
|getProduct|||✓|✓|
|
|
86
|
+
|createProduct|||✓|✓|
|
|
87
|
+
|updateProduct|||✓|✓|
|
|
88
|
+
|**Bookings**|
|
|
89
|
+
|searchProducts|✓|✓|
|
|
90
|
+
|searchBooking|✓|✓|
|
|
91
|
+
|searchAvailability|✓|✓|
|
|
92
|
+
|quoteAvailability|✓|✓|
|
|
93
|
+
|createBooking|✓|✓|
|
|
94
|
+
|cancelBooking|✓|✓|
|
|
76
95
|
|
|
77
96
|
## API logging
|
|
78
97
|
|
|
@@ -111,7 +130,7 @@ Feel free to check the [Issues Page](https://github.com/TourConnect/ti2/issues).
|
|
|
111
130
|
|
|
112
131
|
## License
|
|
113
132
|
|
|
114
|
-
Distributed under the GPL-3 License. See LICENSE
|
|
133
|
+
Distributed under the GPL-3 License. See LICENSE file for more information.
|
|
115
134
|
|
|
116
135
|
TL;DR Here's what the license entails:
|
|
117
136
|
|
package/api.yml
CHANGED
|
@@ -141,6 +141,7 @@ components:
|
|
|
141
141
|
type: string
|
|
142
142
|
bookingSearchQuery:
|
|
143
143
|
type: object
|
|
144
|
+
additionalProperties: true
|
|
144
145
|
properties:
|
|
145
146
|
bookingId:
|
|
146
147
|
type: string
|
|
@@ -172,6 +173,7 @@ components:
|
|
|
172
173
|
default: "DD/MM/YYYY"
|
|
173
174
|
bookingDetail:
|
|
174
175
|
type: object
|
|
176
|
+
additionalProperties: true
|
|
175
177
|
properties:
|
|
176
178
|
id:
|
|
177
179
|
type: string
|
|
@@ -181,7 +183,15 @@ components:
|
|
|
181
183
|
type: string
|
|
182
184
|
required: true
|
|
183
185
|
description: The booking status
|
|
184
|
-
|
|
186
|
+
bookingSearchQueryResults:
|
|
187
|
+
type: object
|
|
188
|
+
additionalProperties: true
|
|
189
|
+
properties:
|
|
190
|
+
bookings:
|
|
191
|
+
type: object
|
|
192
|
+
required: true
|
|
193
|
+
items:
|
|
194
|
+
$ref: '#/components/schemas/bookingDetail'
|
|
185
195
|
bookingDetailsForCancel:
|
|
186
196
|
allOf: # Combines the BasicErrorModel and the inline model
|
|
187
197
|
- $ref: '#/components/schemas/bookingDetail'
|
|
@@ -191,6 +201,89 @@ components:
|
|
|
191
201
|
type: integer
|
|
192
202
|
required: true
|
|
193
203
|
description: The unix time the cancellation was sent
|
|
204
|
+
cancellationReturn:
|
|
205
|
+
type: object
|
|
206
|
+
properties:
|
|
207
|
+
cancellation:
|
|
208
|
+
type: object
|
|
209
|
+
allOf: # Combines the BasicErrorModel and the inline model
|
|
210
|
+
- $ref: '#/components/schemas/bookingDetail'
|
|
211
|
+
bookingsProductQuery:
|
|
212
|
+
type: object
|
|
213
|
+
additionalProperties: true
|
|
214
|
+
description: Additional properties may be included
|
|
215
|
+
properties:
|
|
216
|
+
productName:
|
|
217
|
+
type: string
|
|
218
|
+
required: false
|
|
219
|
+
description: Product Name wildcard match
|
|
220
|
+
example: '*bus*'
|
|
221
|
+
bookingsProductSearchReturn:
|
|
222
|
+
type: object
|
|
223
|
+
additionalProperties: true
|
|
224
|
+
description: Additional properties may be included
|
|
225
|
+
properties:
|
|
226
|
+
products:
|
|
227
|
+
type: array
|
|
228
|
+
required: false
|
|
229
|
+
description: Product Search Results
|
|
230
|
+
items:
|
|
231
|
+
type: object
|
|
232
|
+
accommodation:
|
|
233
|
+
type: array
|
|
234
|
+
required: false,
|
|
235
|
+
decription: Accommodation search results
|
|
236
|
+
items:
|
|
237
|
+
type: object
|
|
238
|
+
pricingItem:
|
|
239
|
+
type: object
|
|
240
|
+
additionalProperties: true
|
|
241
|
+
properties:
|
|
242
|
+
original:
|
|
243
|
+
type: integer
|
|
244
|
+
retail:
|
|
245
|
+
type: integer
|
|
246
|
+
net:
|
|
247
|
+
type: integer
|
|
248
|
+
currency:
|
|
249
|
+
type: string
|
|
250
|
+
example: "USD"
|
|
251
|
+
currencyPrecision:
|
|
252
|
+
type: integer
|
|
253
|
+
includedTaxes:
|
|
254
|
+
type: array
|
|
255
|
+
items:
|
|
256
|
+
type: object
|
|
257
|
+
additionalProperties: true
|
|
258
|
+
properties:
|
|
259
|
+
name:
|
|
260
|
+
type: string
|
|
261
|
+
retail:
|
|
262
|
+
type: integer
|
|
263
|
+
net:
|
|
264
|
+
type: integer
|
|
265
|
+
availabilityItem:
|
|
266
|
+
type: object
|
|
267
|
+
additionalProperties: true
|
|
268
|
+
properties:
|
|
269
|
+
id:
|
|
270
|
+
type: string
|
|
271
|
+
required: true
|
|
272
|
+
description: An availability Id that can be used for quoting
|
|
273
|
+
pricing:
|
|
274
|
+
$ref: '#/components/schemas/pricingItem'
|
|
275
|
+
required: false
|
|
276
|
+
cancelPolicy:
|
|
277
|
+
type: string
|
|
278
|
+
required: false
|
|
279
|
+
bookingRequest:
|
|
280
|
+
type: object
|
|
281
|
+
additionalProperties: true
|
|
282
|
+
required: true
|
|
283
|
+
properties:
|
|
284
|
+
id:
|
|
285
|
+
type: string
|
|
286
|
+
description: a quote Id to make a reservation for
|
|
194
287
|
paths:
|
|
195
288
|
/ping:
|
|
196
289
|
get:
|
|
@@ -516,10 +609,12 @@ paths:
|
|
|
516
609
|
schema:
|
|
517
610
|
$ref: '#/components/schemas/bookingSearchQuery'
|
|
518
611
|
responses:
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
612
|
+
'200':
|
|
613
|
+
description: search results
|
|
614
|
+
content:
|
|
615
|
+
application/json:
|
|
616
|
+
schema:
|
|
617
|
+
$ref: '#/components/schemas/bookingSearchQueryResults'
|
|
523
618
|
/bookings/{appKey}/{userId}/{hint}/search:
|
|
524
619
|
post:
|
|
525
620
|
security:
|
|
@@ -557,10 +652,12 @@ paths:
|
|
|
557
652
|
schema:
|
|
558
653
|
$ref: '#/components/schemas/bookingSearchQuery'
|
|
559
654
|
responses:
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
655
|
+
'200':
|
|
656
|
+
description: search results
|
|
657
|
+
content:
|
|
658
|
+
application/json:
|
|
659
|
+
schema:
|
|
660
|
+
$ref: '#/components/schemas/bookingSearchQueryResults'
|
|
564
661
|
/bookings/{appKey}/{userId}/cancel:
|
|
565
662
|
post:
|
|
566
663
|
security:
|
|
@@ -591,10 +688,12 @@ paths:
|
|
|
591
688
|
schema:
|
|
592
689
|
$ref: '#/components/schemas/bookingDetailsForCancel'
|
|
593
690
|
responses:
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
691
|
+
'200':
|
|
692
|
+
description: Cancellation confirmation details
|
|
693
|
+
content:
|
|
694
|
+
application/json:
|
|
695
|
+
schema:
|
|
696
|
+
$ref: '#/components/schemas/cancellationReturn'
|
|
598
697
|
/bookings/{appKey}/{userId}/{hint}/cancel:
|
|
599
698
|
post:
|
|
600
699
|
security:
|
|
@@ -632,7 +731,373 @@ paths:
|
|
|
632
731
|
schema:
|
|
633
732
|
$ref: '#/components/schemas/bookingDetailsForCancel'
|
|
634
733
|
responses:
|
|
635
|
-
|
|
734
|
+
'200':
|
|
735
|
+
description: Cancellation confirmation details
|
|
736
|
+
content:
|
|
737
|
+
application/json:
|
|
738
|
+
schema:
|
|
739
|
+
$ref: '#/components/schemas/cancellationReturn'
|
|
740
|
+
/products/{appKey}/{userId}/search:
|
|
741
|
+
post:
|
|
742
|
+
security:
|
|
743
|
+
- bearerAuth: ['admin', 'user']
|
|
744
|
+
tags:
|
|
745
|
+
- bookings
|
|
746
|
+
summary: Product Search
|
|
747
|
+
operationId: bookingsProductSearch
|
|
748
|
+
parameters:
|
|
749
|
+
- name: appKey
|
|
750
|
+
in: path
|
|
751
|
+
description: app to search the booking products, defaults to first token
|
|
752
|
+
required: true
|
|
753
|
+
example: 'travelgate-hotelx'
|
|
754
|
+
schema:
|
|
755
|
+
type: string
|
|
756
|
+
- name: userId
|
|
757
|
+
in: path
|
|
758
|
+
description: the user/company that the appKey belongs to
|
|
759
|
+
required: true
|
|
760
|
+
schema:
|
|
761
|
+
type: string
|
|
762
|
+
requestBody:
|
|
763
|
+
description: Search query
|
|
764
|
+
required: true
|
|
765
|
+
content:
|
|
766
|
+
application/json:
|
|
767
|
+
schema:
|
|
768
|
+
$ref: '#/components/schemas/bookingsProductQuery'
|
|
769
|
+
responses:
|
|
770
|
+
'200':
|
|
771
|
+
description: search results
|
|
772
|
+
content:
|
|
773
|
+
application/json:
|
|
774
|
+
schema:
|
|
775
|
+
$ref: '#/components/schemas/bookingsProductSearchReturn'
|
|
776
|
+
/products/{appKey}/{userId}/{hint}/search:
|
|
777
|
+
post:
|
|
778
|
+
security:
|
|
779
|
+
- bearerAuth: ['admin', 'user']
|
|
780
|
+
tags:
|
|
781
|
+
- bookings
|
|
782
|
+
summary: Product Search using for an specific hint
|
|
783
|
+
operationId: bookingsProductSearch
|
|
784
|
+
parameters:
|
|
785
|
+
- name: appKey
|
|
786
|
+
in: path
|
|
787
|
+
description: app to search the booking products, defaults to first token
|
|
788
|
+
required: true
|
|
789
|
+
example: 'travelgate-hotelx'
|
|
790
|
+
schema:
|
|
791
|
+
type: string
|
|
792
|
+
- name: userId
|
|
793
|
+
in: path
|
|
794
|
+
description: the user/company that the appKey belongs to
|
|
795
|
+
required: true
|
|
796
|
+
schema:
|
|
797
|
+
type: string
|
|
798
|
+
- name: hint
|
|
799
|
+
in: path
|
|
800
|
+
description: a specific token hint to be used
|
|
801
|
+
required: true
|
|
802
|
+
example: 'travelgate-australia'
|
|
803
|
+
schema:
|
|
804
|
+
type: string
|
|
805
|
+
requestBody:
|
|
806
|
+
description: Search query
|
|
807
|
+
required: true
|
|
808
|
+
content:
|
|
809
|
+
application/json:
|
|
810
|
+
schema:
|
|
811
|
+
$ref: '#/components/schemas/bookingsProductQuery'
|
|
812
|
+
responses:
|
|
813
|
+
'200':
|
|
814
|
+
description: search results
|
|
815
|
+
content:
|
|
816
|
+
application/json:
|
|
817
|
+
schema:
|
|
818
|
+
$ref: '#/components/schemas/bookingsProductSearchReturn'
|
|
819
|
+
/bookings/{appKey}/{userId}/availability:
|
|
820
|
+
post:
|
|
821
|
+
security:
|
|
822
|
+
- bearerAuth: ['admin', 'user']
|
|
823
|
+
tags:
|
|
824
|
+
- bookings
|
|
825
|
+
summary: Availability Search
|
|
826
|
+
operationId: bookingsAvailabilitySearch
|
|
827
|
+
parameters:
|
|
828
|
+
- name: appKey
|
|
829
|
+
in: path
|
|
830
|
+
description: app to search availability for, defaults to first token
|
|
831
|
+
required: true
|
|
832
|
+
example: 'travelgate-hotelx'
|
|
833
|
+
schema:
|
|
834
|
+
type: string
|
|
835
|
+
- name: userId
|
|
836
|
+
in: path
|
|
837
|
+
description: the user/company that the appKey belongs to
|
|
838
|
+
required: true
|
|
839
|
+
schema:
|
|
840
|
+
type: string
|
|
841
|
+
requestBody:
|
|
842
|
+
description: both app details
|
|
843
|
+
required: true
|
|
844
|
+
content:
|
|
845
|
+
application/json:
|
|
846
|
+
schema:
|
|
847
|
+
$ref: '#/components/schemas/AnyValue'
|
|
848
|
+
responses:
|
|
849
|
+
'200':
|
|
850
|
+
description: search results
|
|
851
|
+
content:
|
|
852
|
+
application/json:
|
|
853
|
+
schema:
|
|
854
|
+
type: object
|
|
855
|
+
properties:
|
|
856
|
+
availability:
|
|
857
|
+
type: array
|
|
858
|
+
required: true
|
|
859
|
+
items:
|
|
860
|
+
$ref: '#/components/schemas/availabilityItem'
|
|
861
|
+
/bookings/{appKey}/{userId}/{hint}/availability:
|
|
862
|
+
post:
|
|
863
|
+
security:
|
|
864
|
+
- bearerAuth: ['admin', 'user']
|
|
865
|
+
tags:
|
|
866
|
+
- bookings
|
|
867
|
+
summary: Availability Search for an specific hint
|
|
868
|
+
operationId: bookingsAvailabilitySearch
|
|
869
|
+
parameters:
|
|
870
|
+
- name: appKey
|
|
871
|
+
in: path
|
|
872
|
+
description: app to search availability for, defaults to first token
|
|
873
|
+
required: true
|
|
874
|
+
example: 'travelgate-hotelx'
|
|
875
|
+
schema:
|
|
876
|
+
type: string
|
|
877
|
+
- name: userId
|
|
878
|
+
in: path
|
|
879
|
+
description: the user/company that the appKey belongs to
|
|
880
|
+
required: true
|
|
881
|
+
schema:
|
|
882
|
+
type: string
|
|
883
|
+
- name: hint
|
|
884
|
+
in: path
|
|
885
|
+
description: a specific token hint to be used
|
|
886
|
+
required: true
|
|
887
|
+
example: 'travelgate-australia'
|
|
888
|
+
schema:
|
|
889
|
+
type: string
|
|
890
|
+
requestBody:
|
|
891
|
+
description: both app details
|
|
892
|
+
required: true
|
|
893
|
+
content:
|
|
894
|
+
application/json:
|
|
895
|
+
schema:
|
|
896
|
+
$ref: '#/components/schemas/AnyValue'
|
|
897
|
+
responses:
|
|
898
|
+
'200':
|
|
899
|
+
description: search results
|
|
900
|
+
content:
|
|
901
|
+
application/json:
|
|
902
|
+
schema:
|
|
903
|
+
type: object
|
|
904
|
+
properties:
|
|
905
|
+
availability:
|
|
906
|
+
type: array
|
|
907
|
+
required: true
|
|
908
|
+
items:
|
|
909
|
+
$ref: '#/components/schemas/availabilityItem'
|
|
910
|
+
/bookings/{appKey}/{userId}/quote:
|
|
911
|
+
post:
|
|
912
|
+
security:
|
|
913
|
+
- bearerAuth: ['admin', 'user']
|
|
914
|
+
tags:
|
|
915
|
+
- bookings
|
|
916
|
+
summary: Quote an Availability
|
|
917
|
+
operationId: searchQuote
|
|
918
|
+
parameters:
|
|
919
|
+
- name: appKey
|
|
920
|
+
in: path
|
|
921
|
+
description: app to quote availability for, defaults to first token
|
|
922
|
+
required: true
|
|
923
|
+
example: 'travelgate-hotelx'
|
|
924
|
+
schema:
|
|
925
|
+
type: string
|
|
926
|
+
- name: userId
|
|
927
|
+
in: path
|
|
928
|
+
description: the user/company that the appKey belongs to
|
|
929
|
+
required: true
|
|
930
|
+
schema:
|
|
931
|
+
type: string
|
|
932
|
+
requestBody:
|
|
933
|
+
description: Availability spec to be quoted
|
|
934
|
+
required: true
|
|
636
935
|
content:
|
|
637
936
|
application/json:
|
|
638
|
-
schema:
|
|
937
|
+
schema:
|
|
938
|
+
type: object
|
|
939
|
+
additionalProperties: true
|
|
940
|
+
properties:
|
|
941
|
+
id:
|
|
942
|
+
type: string
|
|
943
|
+
required: true
|
|
944
|
+
description: An availability Id to quote
|
|
945
|
+
responses:
|
|
946
|
+
'200':
|
|
947
|
+
description: Quote Details
|
|
948
|
+
content:
|
|
949
|
+
application/json:
|
|
950
|
+
schema:
|
|
951
|
+
type: object
|
|
952
|
+
required: true
|
|
953
|
+
properties:
|
|
954
|
+
quote:
|
|
955
|
+
type: array
|
|
956
|
+
required: true
|
|
957
|
+
items:
|
|
958
|
+
type: object
|
|
959
|
+
additionalProperties: true
|
|
960
|
+
properties:
|
|
961
|
+
id:
|
|
962
|
+
type: string
|
|
963
|
+
description: a quote Id that can be use to book
|
|
964
|
+
/bookings/{appKey}/{userId}/{hint}/quote:
|
|
965
|
+
post:
|
|
966
|
+
security:
|
|
967
|
+
- bearerAuth: ['admin', 'user']
|
|
968
|
+
tags:
|
|
969
|
+
- bookings
|
|
970
|
+
summary: Quote an Availability for an specific hint
|
|
971
|
+
operationId: searchQuote
|
|
972
|
+
parameters:
|
|
973
|
+
- name: appKey
|
|
974
|
+
in: path
|
|
975
|
+
description: app to quote the availability for, defaults to first token
|
|
976
|
+
required: true
|
|
977
|
+
example: 'travelgate-hotelx'
|
|
978
|
+
schema:
|
|
979
|
+
type: string
|
|
980
|
+
- name: userId
|
|
981
|
+
in: path
|
|
982
|
+
description: the user/company that the appKey belongs to
|
|
983
|
+
required: true
|
|
984
|
+
schema:
|
|
985
|
+
type: string
|
|
986
|
+
- name: hint
|
|
987
|
+
in: path
|
|
988
|
+
description: a specific token hint to be used
|
|
989
|
+
required: true
|
|
990
|
+
example: 'travelgate-australia'
|
|
991
|
+
schema:
|
|
992
|
+
type: string
|
|
993
|
+
requestBody:
|
|
994
|
+
description: Availability spec to be quoted
|
|
995
|
+
required: true
|
|
996
|
+
content:
|
|
997
|
+
application/json:
|
|
998
|
+
schema:
|
|
999
|
+
type: object
|
|
1000
|
+
additionalProperties: true
|
|
1001
|
+
properties:
|
|
1002
|
+
id:
|
|
1003
|
+
type: string
|
|
1004
|
+
required: true
|
|
1005
|
+
description: An availability Id to quote
|
|
1006
|
+
responses:
|
|
1007
|
+
'200':
|
|
1008
|
+
description: Quote Details
|
|
1009
|
+
content:
|
|
1010
|
+
application/json:
|
|
1011
|
+
schema:
|
|
1012
|
+
type: object
|
|
1013
|
+
required: true
|
|
1014
|
+
properties:
|
|
1015
|
+
quote:
|
|
1016
|
+
type: array
|
|
1017
|
+
required: true
|
|
1018
|
+
items:
|
|
1019
|
+
type: object
|
|
1020
|
+
additionalProperties: true
|
|
1021
|
+
properties:
|
|
1022
|
+
id:
|
|
1023
|
+
type: string
|
|
1024
|
+
description: a quote Id that can be use to book
|
|
1025
|
+
/bookings/{appKey}/{userId}/booking:
|
|
1026
|
+
post:
|
|
1027
|
+
security:
|
|
1028
|
+
- bearerAuth: ['admin', 'user']
|
|
1029
|
+
tags:
|
|
1030
|
+
- bookings
|
|
1031
|
+
summary: Create a Booking
|
|
1032
|
+
operationId: createBooking
|
|
1033
|
+
parameters:
|
|
1034
|
+
- name: appKey
|
|
1035
|
+
in: path
|
|
1036
|
+
description: app to create the booking for, defaults to first token
|
|
1037
|
+
required: true
|
|
1038
|
+
example: 'travelgate-hotelx'
|
|
1039
|
+
schema:
|
|
1040
|
+
type: string
|
|
1041
|
+
- name: userId
|
|
1042
|
+
in: path
|
|
1043
|
+
description: the user/company that the appKey belongs to
|
|
1044
|
+
required: true
|
|
1045
|
+
schema:
|
|
1046
|
+
type: string
|
|
1047
|
+
requestBody:
|
|
1048
|
+
description: Booking creation payload
|
|
1049
|
+
required: true
|
|
1050
|
+
content:
|
|
1051
|
+
application/json:
|
|
1052
|
+
schema:
|
|
1053
|
+
$ref: '#/components/schemas/bookingRequest'
|
|
1054
|
+
responses:
|
|
1055
|
+
'200':
|
|
1056
|
+
description: Booking Details
|
|
1057
|
+
content:
|
|
1058
|
+
application/json:
|
|
1059
|
+
schema:
|
|
1060
|
+
$ref: '#/components/schemas/AnyValue'
|
|
1061
|
+
/bookings/{appKey}/{userId}/{hint}/booking:
|
|
1062
|
+
post:
|
|
1063
|
+
security:
|
|
1064
|
+
- bearerAuth: ['admin', 'user']
|
|
1065
|
+
tags:
|
|
1066
|
+
- bookings
|
|
1067
|
+
summary: Create a Booking for an specific hint
|
|
1068
|
+
operationId: createBooking
|
|
1069
|
+
parameters:
|
|
1070
|
+
- name: appKey
|
|
1071
|
+
in: path
|
|
1072
|
+
description: app to create the booking for, defaults to first token
|
|
1073
|
+
required: true
|
|
1074
|
+
example: 'travelgate-hotelx'
|
|
1075
|
+
schema:
|
|
1076
|
+
type: string
|
|
1077
|
+
- name: userId
|
|
1078
|
+
in: path
|
|
1079
|
+
description: the user/company that the appKey belongs to
|
|
1080
|
+
required: true
|
|
1081
|
+
schema:
|
|
1082
|
+
type: string
|
|
1083
|
+
- name: hint
|
|
1084
|
+
in: path
|
|
1085
|
+
description: a specific token hint to be used
|
|
1086
|
+
required: true
|
|
1087
|
+
example: 'travelgate-australia'
|
|
1088
|
+
schema:
|
|
1089
|
+
type: string
|
|
1090
|
+
requestBody:
|
|
1091
|
+
description: Booking creation payload
|
|
1092
|
+
required: true
|
|
1093
|
+
content:
|
|
1094
|
+
application/json:
|
|
1095
|
+
schema:
|
|
1096
|
+
$ref: '#/components/schemas/bookingRequest'
|
|
1097
|
+
responses:
|
|
1098
|
+
'200':
|
|
1099
|
+
description: Booking Details
|
|
1100
|
+
content:
|
|
1101
|
+
application/json:
|
|
1102
|
+
schema:
|
|
1103
|
+
$ref: '#/components/schemas/AnyValue'
|
|
@@ -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.11",
|
|
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"
|
|
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,415 @@
|
|
|
1
|
-
/* global jest */
|
|
1
|
+
/* global jest, expect */
|
|
2
|
+
const chance = require('chance').Chance();
|
|
2
3
|
|
|
3
4
|
class Plugin {
|
|
5
|
+
/**
|
|
6
|
+
* **General** Methods:
|
|
7
|
+
* * [validateToken](#validateToken).
|
|
8
|
+
*
|
|
9
|
+
* **Content Methods**:
|
|
10
|
+
* * [getProfile](#getProfile)
|
|
11
|
+
* * [updateProfile](#updateProfile)
|
|
12
|
+
* * [createLocation](#createLocation)
|
|
13
|
+
* * [updateLocation](#updateLocation)
|
|
14
|
+
* * [getProducts](#getProducts)
|
|
15
|
+
* * [createProduct](#createProduct)
|
|
16
|
+
* * [updateProduct](#updateProduct)
|
|
17
|
+
*
|
|
18
|
+
* **Booking Methods**:
|
|
19
|
+
* * [searchBooking](#searchBooking)
|
|
20
|
+
* * [searchProducts](#searchProducts)
|
|
21
|
+
* * [searchAvailability](#searchAvailability)
|
|
22
|
+
* * [quoteAvailability](#quoteAvailability)
|
|
23
|
+
* * [createBooking](#createBooking)
|
|
24
|
+
* ---
|
|
25
|
+
*
|
|
26
|
+
* @param {Object} args - New / Overwriting attributes for the Plugin.
|
|
27
|
+
*/
|
|
4
28
|
constructor(params = {}) {
|
|
5
29
|
Object.entries(params).forEach(([attr, value]) => {
|
|
6
30
|
this[attr] = value;
|
|
7
31
|
});
|
|
32
|
+
// mock implementations
|
|
33
|
+
this.validateToken = jest.fn(() => true);
|
|
34
|
+
this.getProfile = jest.fn(() => {});
|
|
35
|
+
this.updateProfile = jest.fn(() => {});
|
|
36
|
+
this.getProduct = jest.fn(() => ({ products: [] }));
|
|
37
|
+
this.getProducts = jest.fn(() => true);
|
|
38
|
+
this.createLocation = jest.fn(() => ({ locationId: chance.guid() }));
|
|
39
|
+
this.updateLocation = jest.fn(() => true);
|
|
40
|
+
this.searchBooking = jest.fn(() => ({ bookings: [] }));
|
|
41
|
+
this.searchProducts = jest.fn(() => ({ bookings: [], products: [] }));
|
|
42
|
+
this.searchAvailability = jest.fn(({
|
|
43
|
+
token,
|
|
44
|
+
payload: {
|
|
45
|
+
travelDateStart,
|
|
46
|
+
travelDateEnd,
|
|
47
|
+
dateFormat,
|
|
48
|
+
occupancies,
|
|
49
|
+
},
|
|
50
|
+
}) => {
|
|
51
|
+
expect(token).toBeTruthy();
|
|
52
|
+
expect(travelDateStart).toBeTruthy();
|
|
53
|
+
expect(travelDateEnd).toBeTruthy();
|
|
54
|
+
expect(dateFormat).toBeTruthy();
|
|
55
|
+
expect(Array.isArray(occupancies)).toBeTruthy();
|
|
56
|
+
return { availability: [{ id: chance.guid() }] };
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
this.searchQuote = jest.fn(() => ({ quote: [{ id: chance.guid() }] }));
|
|
60
|
+
this.createBooking = jest.fn(() => {});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Check the vailidity of an integration token. *part of **General** Methods*
|
|
65
|
+
* @async
|
|
66
|
+
* @param {Object} args - Availability search arguments.
|
|
67
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
68
|
+
* @returns {Boolean} - The token vailidity True/False
|
|
69
|
+
*/
|
|
70
|
+
validateToken() {
|
|
71
|
+
return Boolean(this);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* GPS Location Object
|
|
75
|
+
* @typedef {Object} GPSLocation
|
|
76
|
+
* @property {String} lat - GPS latitude
|
|
77
|
+
* @property {String} lng - GPS Longitude
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Address Object
|
|
82
|
+
* @typedef {Object} Address
|
|
83
|
+
* @property {string} addressOne - Street Address first line of text
|
|
84
|
+
* @property {string} addressTwo - Street Address second line of text
|
|
85
|
+
* @property {string} city - City
|
|
86
|
+
* @property {string} state - State
|
|
87
|
+
* @property {string} zipCode - Zip/Postal Code
|
|
88
|
+
* @property {GPSLocation} loc -Location
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Profile Object
|
|
93
|
+
* @typedef {Object} Profile
|
|
94
|
+
* @property {string} companyName
|
|
95
|
+
* @property {Address} address
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Returns the profile details of the account.
|
|
100
|
+
* @category Methods
|
|
101
|
+
* @subcategory Content
|
|
102
|
+
* Returns the profile details of the account.
|
|
103
|
+
* @async
|
|
104
|
+
* @param {Object} args - Availability search arguments.
|
|
105
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
106
|
+
* @returns {Profile} - The profile details.
|
|
107
|
+
*/
|
|
108
|
+
getProfile() {
|
|
109
|
+
return {};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Updates profile information
|
|
114
|
+
* @async
|
|
115
|
+
* @param {Object} args - Availability search arguments.
|
|
116
|
+
* @param {Profile} args.payload - Updated profile information
|
|
117
|
+
* @returns {boolean} - True/False success status.
|
|
118
|
+
*/
|
|
119
|
+
updateProfile() {
|
|
120
|
+
return {};
|
|
8
121
|
}
|
|
9
122
|
|
|
10
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Location Object
|
|
125
|
+
* @typedef {Object} Location
|
|
126
|
+
* @property {string} telephone
|
|
127
|
+
* @property {Address} address
|
|
128
|
+
*/
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Create a Location
|
|
132
|
+
* @async
|
|
133
|
+
* @param {Object} args - Availability search arguments.
|
|
134
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
135
|
+
* @param {Location} args.payload - The new location details.
|
|
136
|
+
* @returns {Object} retVal - An object containing return values.
|
|
137
|
+
* @returns {string} retVal.locationId - The new location unique identifier.
|
|
138
|
+
*/
|
|
139
|
+
createLocation() {
|
|
140
|
+
return { locationId: chance.guid() };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Update a Location
|
|
145
|
+
* @async
|
|
146
|
+
* @param {Object} args - Availability search arguments.
|
|
147
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
148
|
+
* @param {string} args.locationId - The unique identifier of the location to update.
|
|
149
|
+
* @param {Location} args.payload - The new location details.
|
|
150
|
+
* @returns {boolean} - True/False success status.
|
|
151
|
+
*/
|
|
152
|
+
updateLocation() {
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Media Object
|
|
157
|
+
* @typedef {Object} Media - Media Details
|
|
158
|
+
* @property {string} mediaType - MimeType of media
|
|
159
|
+
* @property {string} url - URL of media
|
|
160
|
+
*/
|
|
11
161
|
|
|
12
|
-
|
|
162
|
+
/**
|
|
163
|
+
* Media Collection
|
|
164
|
+
* @typedef {Object} MediaCollection - Media Collection, grouped by type
|
|
165
|
+
* @property {Array.Media} image
|
|
166
|
+
* @property {Array.Media} video
|
|
167
|
+
*/
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Room Object
|
|
171
|
+
* @typedef {Object} RoomInfo - Room details object
|
|
172
|
+
* @property {number} count - Number of rooms
|
|
173
|
+
* @property {string} bedType - Bedding type
|
|
174
|
+
* @property {string} other - Exta Information
|
|
175
|
+
*/
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Value and UUnit spec
|
|
179
|
+
* @typedef {Object} ValueUnit - ValueDetails fields
|
|
180
|
+
* @property {string} unit - A unit specification
|
|
181
|
+
* @property {number} value - The number of units
|
|
182
|
+
*/
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Get the product details related to a location
|
|
186
|
+
* @async
|
|
187
|
+
* @param {Object} args - Availability search arguments.
|
|
188
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
189
|
+
* @param {Object} args.locationId - A location unique identifier for the matching product.
|
|
190
|
+
* @param {Object} args.productId - The product unique identifier.
|
|
191
|
+
* @returns {Object} retVal - A return object.
|
|
192
|
+
* @returns {Product} retVal.product - Details of the matching product.
|
|
193
|
+
*/
|
|
194
|
+
/**
|
|
195
|
+
* ProductInfo type
|
|
196
|
+
* @typedef ProductInfo
|
|
197
|
+
* @property {string} include
|
|
198
|
+
* @property {string} exclude
|
|
199
|
+
* @property {string} whatToBring
|
|
200
|
+
*/
|
|
201
|
+
/**
|
|
202
|
+
* bedsAndSofas type
|
|
203
|
+
* @typedef BedsAndSofas
|
|
204
|
+
* @property {boolean} isApartment
|
|
205
|
+
* @property {numeric} count
|
|
206
|
+
* @property {string} other
|
|
207
|
+
*/
|
|
208
|
+
/**
|
|
209
|
+
* Product Object
|
|
210
|
+
* @typedef {Object} Product - Product information Object
|
|
211
|
+
* @property {string} productId - A unique identifier for a product
|
|
212
|
+
* @property {string} productName
|
|
213
|
+
* @property {('accommodation'|'non-accommodation')} productType
|
|
214
|
+
* @property {string} productCode
|
|
215
|
+
* @property {string} description
|
|
216
|
+
* @property {string} notes
|
|
217
|
+
* @property {string} coverImageUrl
|
|
218
|
+
* @property {boolean} interconnectingRooms
|
|
219
|
+
* @property {string} amenities
|
|
220
|
+
* @property {ValueUnit} roomCountInfo
|
|
221
|
+
* @property {MediaCollection} media
|
|
222
|
+
* @property {ValueUnit} roomSizeInfo
|
|
223
|
+
* @property {ValueUnit} tourDuration
|
|
224
|
+
* @property {number} totalMaxPassengers
|
|
225
|
+
* @property {number} totalMinPassengers
|
|
226
|
+
* @property {ValueUnit} totalDuration
|
|
227
|
+
* @property {boolean} tourDurationDoesNotApply
|
|
228
|
+
* @property {ProductInfo} productInfo
|
|
229
|
+
* @property {BedsAndSofas} bedsAndSofas
|
|
230
|
+
*/
|
|
231
|
+
getProduct() {
|
|
232
|
+
return {};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Get the list of products for a given location
|
|
237
|
+
* @async
|
|
238
|
+
* @param {Object} args - Availability search arguments.
|
|
239
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
240
|
+
* @param {Object} args.locationId - A location unique identifier to get the list of products.
|
|
241
|
+
* @returns {Object} retVal - An object containing return values.
|
|
242
|
+
* @returns {Array.Product} retVal.products - An array of matching products.
|
|
243
|
+
*/
|
|
244
|
+
getProducts() {
|
|
245
|
+
return { products: [] };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Create a Product
|
|
250
|
+
* @async
|
|
251
|
+
* @param {Object} args - Availability search arguments.
|
|
252
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
253
|
+
* @param {string} args.locationId - The unique identifier of the location that will contain the product.
|
|
254
|
+
* @param {Product} args.payload - The new product details.
|
|
255
|
+
* @returns {Object} retVal - An object containing return values.
|
|
256
|
+
* @returns {string} retVal.locationId - The new location unique identifier.
|
|
257
|
+
*/
|
|
258
|
+
createProduct() {
|
|
259
|
+
return { locationId: chance.guid(), productId: chance.guid() };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Update a Product
|
|
264
|
+
* @async
|
|
265
|
+
* @param {Object} args - Availability search arguments.
|
|
266
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
267
|
+
* @param {string} args.locationId - The unique identifier of the location that contains the product.
|
|
268
|
+
* @param {string} args.productId - The unique identifier of the product to update.
|
|
269
|
+
* @param {Product} args.payload - The new location details.
|
|
270
|
+
* @returns {boolean} - True/False success status.
|
|
271
|
+
*/
|
|
272
|
+
updateProduct() {
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
13
275
|
|
|
14
276
|
searchHotelBooking = jest.fn(() => ({ bookings: [] }));
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Booking Object
|
|
280
|
+
* @typedef {Object} Booking
|
|
281
|
+
* @property {string} id Booking unique identifier.
|
|
282
|
+
* @property {Cancelled|Active|Pending} status The currrent booking status.
|
|
283
|
+
* @property {Holder} holder Booking holder information.
|
|
284
|
+
* @property {string} telephone Contact telephone.
|
|
285
|
+
* @property {string} supplierId Supplier of the Booking
|
|
286
|
+
* @property {string} hotelId A HotelId if the booking is for an accommodation.
|
|
287
|
+
* @property {string} hotelName A Hotel Name if the booking is for an accommodation.
|
|
288
|
+
* @property {BookingRoom[]} rooms Booking Room details.
|
|
289
|
+
* @property {string} start CheckIn.
|
|
290
|
+
* @property {string} end CheckOut.
|
|
291
|
+
* @property {string} bookingDate Date when the booking was created.
|
|
292
|
+
* @property {numeric} price Total price for the booking.
|
|
293
|
+
* @property {CancelPolicy} cancelPolicy Cancellation policies for the booking.
|
|
294
|
+
*/
|
|
295
|
+
/**
|
|
296
|
+
* Booking Room
|
|
297
|
+
* @typedef {Object} BookingRoom
|
|
298
|
+
* @property {string} roomId
|
|
299
|
+
* @property {string} description
|
|
300
|
+
* @property {numeric} price
|
|
301
|
+
*/
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Cancel Policy
|
|
305
|
+
* @typedef {Object} CancelPolicy
|
|
306
|
+
* @property {boolean} refundable
|
|
307
|
+
* @property {string} cancelPenalties
|
|
308
|
+
*/
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Search for bookings with a criteria.
|
|
312
|
+
* @async
|
|
313
|
+
* @param {Object} args - Booking search arguments.
|
|
314
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
315
|
+
* @param {Object} args.payload - Search criteria object.
|
|
316
|
+
* @param {string} args.payload.bookingId - a Booking Id.
|
|
317
|
+
* @param {string} args.payload.dateFormat - Date format sent, using [momentjs formatting](https://momentjs.com/docs/#/parsing/string-format/).
|
|
318
|
+
* @param {string} args.payload.purchaseDateStart - Date of purchase start.
|
|
319
|
+
* @param {string} args.payload.purchaseDateEnd - Date of purchase end.
|
|
320
|
+
* @param {string} args.payload.travelDateStart - Date of travel start.
|
|
321
|
+
* @param {string} args.payload.travelDateEnd - Date of travel end.
|
|
322
|
+
* @param {Holder} args.payload.holder - Search for a particular holder.
|
|
323
|
+
* @returns {object} retVal - the return object.
|
|
324
|
+
* @returns {Booking[]} retVal.bookings - Array of Bookings matchin the criteria.
|
|
325
|
+
*/
|
|
326
|
+
searchBooking() {
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Search for bookable products
|
|
331
|
+
* @async
|
|
332
|
+
* @param {Object} args - Product search arguments.
|
|
333
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
334
|
+
* @param {Object} args.payload - Search criteria object.
|
|
335
|
+
* @returns {object} retVal - the return object.
|
|
336
|
+
* @returns {Hotel[]} retVal.hotels - Array of bookable hotels.
|
|
337
|
+
* @returns {Product[]} retVal.products - Array of bookable activities.
|
|
338
|
+
* @todo Define search criteria and Hotel/Product spec.
|
|
339
|
+
*/
|
|
340
|
+
searchProducts() {
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Occupancy Object
|
|
345
|
+
* @typedef {Object} Occupancy
|
|
346
|
+
* @property {Pax[]} paxes
|
|
347
|
+
*/
|
|
348
|
+
/**
|
|
349
|
+
* A Pax item with an age spec.
|
|
350
|
+
* @typedef {Object} Pax
|
|
351
|
+
* @property {number} age Age in years of the pax when the startDate starts on local timezone.
|
|
352
|
+
*/
|
|
353
|
+
/**
|
|
354
|
+
* An availability return spec.
|
|
355
|
+
* @typedef {Object} Availability
|
|
356
|
+
* @property {string} id An identifier that can be used to retrieve a quote.
|
|
357
|
+
*/
|
|
358
|
+
/**
|
|
359
|
+
* A booking holder spec.
|
|
360
|
+
* @typedef {Object} Holder
|
|
361
|
+
* @property {string} name The booking's holder first name (s).
|
|
362
|
+
* @property {string} surname Surname / Last Name(s) for the booking holder.
|
|
363
|
+
* @property {string} email The booking's holder email.
|
|
364
|
+
*/
|
|
365
|
+
/**
|
|
366
|
+
* Search for availability of products winthin dates of travel.
|
|
367
|
+
* @async
|
|
368
|
+
* @param {Object} args - Availability search arguments.
|
|
369
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
370
|
+
* @param {Object} args.payload - Search spect object.
|
|
371
|
+
* @param {string} args.payload.dateFormat - Date format sent, using [momentjs formatting](https://momentjs.com/docs/#/parsing/string-format/).
|
|
372
|
+
* @param {string} args.payload.travelDateStart - Date of travel start.
|
|
373
|
+
* @param {string} args.payload.travelDateEnd - Date of travel end.
|
|
374
|
+
* @param {Occupancy[]} args.payload.occupancies - Occupancy detail.
|
|
375
|
+
* @returns {object} retVal - the return object
|
|
376
|
+
* @returns {Availability[]} retVal.availability - Array of availability objects
|
|
377
|
+
*/
|
|
378
|
+
searchAvailability() {
|
|
379
|
+
// return (args);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* A quote return spec
|
|
384
|
+
* @typedef {Object} Quote
|
|
385
|
+
* @property {string} id An identifier that can be used to create a booking.
|
|
386
|
+
*/
|
|
387
|
+
/**
|
|
388
|
+
* Quote an availability.
|
|
389
|
+
* @async
|
|
390
|
+
* @param {Object} args - Availability quote arguments.
|
|
391
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
392
|
+
* @param {Object} args.payload - Search spect object.
|
|
393
|
+
* @param {string} args.payload.id - An availability Id.
|
|
394
|
+
* @returns {object} retVal - the return object.
|
|
395
|
+
* @returns {Quote} retVal.quote - A Quote Object instance.
|
|
396
|
+
*/
|
|
397
|
+
searchQuote() {
|
|
398
|
+
// return (args);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Create a Booking
|
|
403
|
+
* @async
|
|
404
|
+
* @param {Object} args - Booking arguments.
|
|
405
|
+
* @param {Object} args.token - A token definition, it's content varies between integrations.
|
|
406
|
+
* @param {Object} args.payload - Search spect object.
|
|
407
|
+
* @param {string} args.payload.id - A quote id.
|
|
408
|
+
* @param {Holder} args.payload.holder - Contact information of the booking holder.
|
|
409
|
+
* @returns {object} retVal - the return object.
|
|
410
|
+
* @returns {Booking} retVal.booking - A Booking object.
|
|
411
|
+
*/
|
|
412
|
+
createBooking() {}
|
|
15
413
|
}
|
|
16
414
|
|
|
17
415
|
module.exports = Plugin;
|