@@ -193,7 +193,7 @@ class Plugin {
193
193
// add one RoomConfig for each room required (i.e. one for each PaxConfig)
194
194
RoomConfigs . RoomConfig = [ ] ;
195
195
let indexRoomConfig = 0 ;
196
- paxConfigs . map ( ( { roomType, passengers = [ ] } ) => {
196
+ paxConfigs . forEach ( ( { roomType, passengers = [ ] } ) => {
197
197
const EachRoomConfig = passengers . reduce ( ( acc , p ) => {
198
198
console . log ( JSON . stringify ( p ) ) ;
199
199
if ( p . passengerType === 'Adult' ) {
@@ -223,9 +223,21 @@ class Plugin {
223
223
if ( passengers && passengers . length && ! noPaxList ) {
224
224
// There should be only 1 PaxList inside each EachRoomConfig
225
225
EachRoomConfig . PaxList = { } ;
226
- // Inside PaxList, there should be 1 PaxDetails for each passenger (Pax)
227
- EachRoomConfig . PaxList . PaxDetails = [ ] ;
228
- passengers . forEach ( ( p , indexEachPax ) => {
226
+ // Inside PaxList, there should be 1 PaxDetail for each passenger (Pax)
227
+ EachRoomConfig . PaxList . PaxDetails = passengers . map ( p => {
228
+ /*
229
+ TP API doesn't allow us to modify existing pax details
230
+ when PersonId is present, other details are ignored by TP anyways
231
+ when it is not present, TP is comparing every key in PaxDetail to identify
232
+ duplicate, so if we send Pax Detail with the same first and last name, but different
233
+ Age, TP will consider them to be different pax, which actually is duplicate, given
234
+ sometimes AI could be extracting inconsistent data
235
+ */
236
+ if ( p . personId ) {
237
+ return {
238
+ PersonId : p . personId ,
239
+ } ;
240
+ }
229
241
const EachPaxDetails = {
230
242
Forename : this . escapeInvalidXmlChars ( p . firstName ) ,
231
243
Surname : this . escapeInvalidXmlChars ( p . lastName ) ,
@@ -242,7 +254,7 @@ class Plugin {
242
254
EachPaxDetails . Age = p . age ;
243
255
}
244
256
}
245
- EachRoomConfig . PaxList . PaxDetails [ indexEachPax ] = EachPaxDetails ;
257
+ return EachPaxDetails ;
246
258
} ) ;
247
259
}
248
260
RoomConfigs . RoomConfig [ indexRoomConfig ++ ] = EachRoomConfig
@@ -703,10 +715,21 @@ class Plugin {
703
715
puInfo,
704
716
doInfo,
705
717
notes,
718
+ QB ,
706
719
directHeaderPayload,
707
720
directLinePayload,
721
+ customFieldValues = [ ] ,
708
722
} ,
709
723
} ) {
724
+ const cfvPerService = customFieldValues . filter ( f => f . isPerService && f . value )
725
+ . reduce ( ( acc , f ) => {
726
+ if ( f . type === 'extended-option' ) {
727
+ acc [ f . id ] = f . value . value || f . value ;
728
+ } else {
729
+ acc [ f . id ] = f . value ;
730
+ }
731
+ return acc ;
732
+ } , { } ) ;
710
733
const model = {
711
734
AddServiceRequest : {
712
735
AgentID : hostConnectAgentID ,
@@ -716,7 +739,7 @@ class Plugin {
716
739
} : {
717
740
NewBookingInfo : {
718
741
Name : this . escapeInvalidXmlChars ( quoteName ) ,
719
- QB : 'Q' ,
742
+ QB : QB || 'Q' ,
720
743
...( directHeaderPayload || { } ) ,
721
744
} ,
722
745
} ) ,
@@ -757,6 +780,7 @@ class Plugin {
757
780
AgentRef : reference ,
758
781
RoomConfigs : this . getRoomConfigs ( paxConfigs ) ,
759
782
...( directLinePayload || { } ) ,
783
+ ...( cfvPerService || { } ) ,
760
784
} ,
761
785
} ;
762
786
const replyObj = await this . callTourplan ( {
@@ -769,7 +793,7 @@ class Plugin {
769
793
message : R . path ( [ 'AddServiceReply' , 'Status' ] , replyObj )
770
794
=== 'NO' ? 'Service cannot be added to quote for the requested date/stay. (e.g. no rates, block out period, on request, minimum stay etc.)' : '' ,
771
795
quote : {
772
- id : R . path ( [ 'AddServiceReply' , 'BookingId' ] , replyObj ) ,
796
+ id : R . path ( [ 'AddServiceReply' , 'BookingId' ] , replyObj ) || quoteId ,
773
797
reference : R . path ( [ 'AddServiceReply' , 'Ref' ] , replyObj ) ,
774
798
linePrice : R . path ( [ 'AddServiceReply' , 'Services' , 'Service' , 'LinePrice' ] , replyObj ) ,
775
799
lineId : R . path ( [ 'AddServiceReply' , 'ServiceLineId' ] , replyObj ) ,
@@ -779,14 +803,38 @@ class Plugin {
779
803
780
804
// eslint-disable-next-line class-methods-use-this
781
805
async getCreateBookingFields ( {
782
- // token: {
783
- // hostConnectAgentID,
784
- // hostConnectAgentPassword,
785
- // hostConnectEndpoint,
786
- // },
787
- // axios,
806
+ token : {
807
+ hostConnectAgentID,
808
+ hostConnectAgentPassword,
809
+ hostConnectEndpoint,
810
+ } ,
811
+ axios,
788
812
} ) {
789
- const customFields = [ ] ;
813
+ const model = {
814
+ GetLocationsRequest : {
815
+ AgentID : hostConnectAgentID ,
816
+ Password : hostConnectAgentPassword ,
817
+ } ,
818
+ } ;
819
+ const GetLocationsReply = await this . cache . getOrExec ( {
820
+ fnParams : [ model ] ,
821
+ fn : ( ) => this . callTourplan ( {
822
+ model,
823
+ endpoint : hostConnectEndpoint ,
824
+ axios,
825
+ xmlOptions : hostConnectXmlOptions ,
826
+ } ) ,
827
+ ttl : 60 * 60 * 12 , // 2 hours
828
+ } ) ;
829
+ let locationCodes = R . pathOr ( [ ] , [ 'GetLocationsReply' , 'Locations' , 'Location' ] , GetLocationsReply ) ;
830
+ if ( ! Array . isArray ( locationCodes ) ) locationCodes = [ locationCodes ] ;
831
+ const customFields = [ {
832
+ id : 'LocationCode' ,
833
+ label : 'Location Code' ,
834
+ type : 'extended-option' ,
835
+ isPerService : true ,
836
+ options : locationCodes . map ( o => ( { value : o . Code , label : `${ o . Name } (${ o . Code } )` } ) ) ,
837
+ } ] ;
790
838
return {
791
839
fields : [ ] ,
792
840
customFields,
@@ -866,13 +914,68 @@ class Plugin {
866
914
const getBookingPayload = getPayload ( 'GetBookingRequest' , {
867
915
BookingId : R . prop ( 'BookingId' , bookingHeader ) ,
868
916
ReturnAccountInfo : 'Y' ,
917
+ ReturnRoomConfigs : 'Y' ,
869
918
} ) ;
870
919
const bookingReply = await this . callTourplan ( getBookingPayload ) ;
871
920
const booking = R . path ( [ 'GetBookingReply' ] , bookingReply ) ;
872
- const Services = R . pathOr ( [ ] , [ 'Services' , 'Service' ] , booking ) ;
921
+ /*
922
+ booking = {
923
+ Services: {
924
+ ...
925
+ RoomConfigs: {
926
+ RoomConfig: {
927
+ Adults: '2',
928
+ Children: '0',
929
+ Infants: '0',
930
+ PaxList: {
931
+ PaxDetails: [
932
+ {
933
+ Age: '37',
934
+ DateOfBirth: '1987-09-26',
935
+ Forename: 'Chris',
936
+ PaxType: 'A',
937
+ PersonId: '628206',
938
+ Surname: 'Voss'
939
+ },
940
+ {
941
+ Age: '36',
942
+ DateOfBirth: '1988-09-26',
943
+ Forename: 'Joy',
944
+ PaxType: 'A',
945
+ PersonId: '628207',
946
+ Surname: 'Voss'
947
+ }
948
+ ]
949
+ }
950
+ }
951
+ },
952
+ ...
953
+ }
954
+ }
955
+ */
956
+ let Services = R . pathOr ( [ ] , [ 'Services' , 'Service' ] , booking ) ;
957
+ if ( ! Array . isArray ( Services ) ) Services = [ Services ] ;
958
+ Services = Services . map ( s => {
959
+ let actualRoomConfigs = s . RoomConfigs . RoomConfig ;
960
+ if ( ! Array . isArray ( actualRoomConfigs ) ) actualRoomConfigs = [ actualRoomConfigs ] ;
961
+ const paxList = actualRoomConfigs . reduce ( ( acc , roomConfig ) => {
962
+ const paxDetails = R . pathOr ( [ ] , [ 'PaxList' , 'PaxDetails' ] , roomConfig ) ;
963
+ if ( ! Array . isArray ( paxDetails ) ) return acc ;
964
+ return [ ...acc , ...paxDetails ] ;
965
+ } , [ ] )
966
+ . map ( p => ( {
967
+ personId : R . path ( [ 'PersonId' ] , p ) ,
968
+ firstName : R . path ( [ 'Forename' ] , p ) ,
969
+ lastName : R . path ( [ 'Surname' ] , p ) ,
970
+ } ) ) ;
971
+ return {
972
+ ...s ,
973
+ paxList,
974
+ } ;
975
+ } ) ;
873
976
return {
874
977
...booking ,
875
- Services : Array . isArray ( Services ) ? Services : [ Services ] ,
978
+ Services,
876
979
} ;
877
980
} , { concurrency : 10 } ) ;
878
981
return {
0 commit comments