|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* amadeus-ws-client |
|
4
|
|
|
* |
|
5
|
|
|
* Copyright 2015 Amadeus Benelux NV |
|
6
|
|
|
* |
|
7
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
8
|
|
|
* you may not use this file except in compliance with the License. |
|
9
|
|
|
* You may obtain a copy of the License at |
|
10
|
|
|
* |
|
11
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
12
|
|
|
* |
|
13
|
|
|
* Unless required by applicable law or agreed to in writing, software |
|
14
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
15
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
16
|
|
|
* See the License for the specific language governing permissions and |
|
17
|
|
|
* limitations under the License. |
|
18
|
|
|
* |
|
19
|
|
|
* @package Amadeus |
|
20
|
|
|
* @license https://opensource.org/licenses/Apache-2.0 Apache 2.0 |
|
21
|
|
|
*/ |
|
22
|
|
|
|
|
23
|
|
|
namespace Amadeus\Client\ResponseHandler\Air; |
|
24
|
|
|
|
|
25
|
|
|
use Amadeus\Client\ResponseHandler\StandardResponseHandler; |
|
26
|
|
|
use Amadeus\Client\Result; |
|
27
|
|
|
use Amadeus\Client\Session\Handler\SendResult; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* Utility class to get proper error messages from an Air_RetrieveSeatMapReply message |
|
31
|
|
|
* |
|
32
|
|
|
* @package Amadeus\Client\ResponseHandler\Air |
|
33
|
|
|
* @author Dieter Devlieghere <[email protected]> |
|
34
|
|
|
*/ |
|
35
|
|
|
class HandlerRetrieveSeatMap extends StandardResponseHandler |
|
36
|
|
|
{ |
|
37
|
|
|
/** |
|
38
|
|
|
* @param SendResult $response |
|
39
|
|
|
* @return Result |
|
40
|
|
|
*/ |
|
41
|
|
|
public function analyze(SendResult $response) |
|
42
|
|
|
{ |
|
43
|
|
|
$analyzeResponse = new Result($response); |
|
44
|
|
|
|
|
45
|
|
|
$domXpath = $this->makeDomXpath($response->responseXml); |
|
46
|
|
|
|
|
47
|
|
|
$errorCodeNode = $domXpath->query('//m:errorInformation/m:errorDetails/m:code'); |
|
48
|
|
View Code Duplication |
if ($errorCodeNode->length > 0) { |
|
|
|
|
|
|
49
|
|
|
$analyzeResponse->status = Result::STATUS_ERROR; |
|
50
|
|
|
|
|
51
|
|
|
$errCode = $errorCodeNode->item(0)->nodeValue; |
|
52
|
|
|
$level = null; |
|
53
|
|
|
|
|
54
|
|
|
$errorLevelNode = $domXpath->query('//m:errorInformation/m:errorDetails/m:processingLevel'); |
|
55
|
|
|
if ($errorLevelNode->length > 0) { |
|
56
|
|
|
$level = self::decodeProcessingLevel($errorLevelNode->item(0)->nodeValue); |
|
57
|
|
|
} |
|
58
|
|
|
|
|
59
|
|
|
$errorDescNode = $domXpath->query('//m:errorInformation/m:errorDetails/m:description'); |
|
60
|
|
|
if ($errorDescNode->length > 0) { |
|
61
|
|
|
$errDesc = $errorDescNode->item(0)->nodeValue; |
|
62
|
|
|
} else { |
|
63
|
|
|
$errDesc = self::findMessage($errCode); |
|
64
|
|
|
} |
|
65
|
|
|
|
|
66
|
|
|
$analyzeResponse->messages[] = new Result\NotOk( |
|
67
|
|
|
$errCode, |
|
68
|
|
|
$errDesc, |
|
69
|
|
|
$level |
|
70
|
|
|
); |
|
71
|
|
|
} |
|
72
|
|
|
|
|
73
|
|
|
$codeNode = $domXpath->query('//m:warningInformation/m:warningDetails/m:number'); |
|
74
|
|
View Code Duplication |
if ($codeNode->length > 0) { |
|
|
|
|
|
|
75
|
|
|
$analyzeResponse->status = Result::STATUS_WARN; |
|
76
|
|
|
|
|
77
|
|
|
$warnCode = $codeNode->item(0)->nodeValue; |
|
78
|
|
|
$level = null; |
|
79
|
|
|
|
|
80
|
|
|
$levelNode = $domXpath->query('//m:warningInformation/m:warningDetails/m:processingLevel'); |
|
81
|
|
|
if ($levelNode->length > 0) { |
|
82
|
|
|
$level = self::decodeProcessingLevel($levelNode->item(0)->nodeValue); |
|
83
|
|
|
} |
|
84
|
|
|
|
|
85
|
|
|
$descNode = $domXpath->query('//m:warningInformation/m:warningDetails/m:description'); |
|
86
|
|
|
if ($descNode->length > 0) { |
|
87
|
|
|
$warnDesc = $descNode->item(0)->nodeValue; |
|
88
|
|
|
} else { |
|
89
|
|
|
$warnDesc = self::findMessage($warnCode); |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
$analyzeResponse->messages[] = new Result\NotOk( |
|
93
|
|
|
$warnCode, |
|
94
|
|
|
$warnDesc, |
|
95
|
|
|
$level |
|
96
|
|
|
); |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
return $analyzeResponse; |
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
/** |
|
103
|
|
|
* Find the error message for a given error code |
|
104
|
|
|
* |
|
105
|
|
|
* @param string $code |
|
106
|
|
|
* @return string|null |
|
107
|
|
|
*/ |
|
108
|
|
|
public static function findMessage($code) |
|
109
|
|
|
{ |
|
110
|
|
|
$message = null; |
|
111
|
|
|
|
|
112
|
|
|
if (array_key_exists($code, self::$errorList)) { |
|
113
|
|
|
$message = self::$errorList[$code]; |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
return $message; |
|
117
|
|
|
} |
|
118
|
|
|
|
|
119
|
|
|
/** |
|
120
|
|
|
* Decode error processing level code |
|
121
|
|
|
* |
|
122
|
|
|
* @param int|string $level |
|
123
|
|
|
* @return string|null |
|
124
|
|
|
*/ |
|
125
|
|
|
public static function decodeProcessingLevel($level) |
|
126
|
|
|
{ |
|
127
|
|
|
$decoded = null; |
|
128
|
|
|
|
|
129
|
|
|
$map = [ |
|
130
|
|
|
0 => 'system', |
|
131
|
|
|
1 => 'application' |
|
132
|
|
|
]; |
|
133
|
|
|
|
|
134
|
|
|
if (array_key_exists($level, $map)) { |
|
135
|
|
|
$decoded = $map[$level]; |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
return $decoded; |
|
139
|
|
|
} |
|
140
|
|
|
|
|
141
|
|
|
/** |
|
142
|
|
|
* @var array |
|
143
|
|
|
*/ |
|
144
|
|
|
public static $errorList = [ |
|
145
|
|
|
'1' => 'Passenger surname not found', |
|
146
|
|
|
'10' => 'Location of arrival is invalid', |
|
147
|
|
|
'100' => 'Seat map not available, request seat at check-in', |
|
148
|
|
|
'101' => 'Seat map contains conditional seats, it may be subject to reseating', |
|
149
|
|
|
'102' => 'Unable to process', |
|
150
|
|
|
'103' => 'Segment/Passenger does not qualify for advanced seating', |
|
151
|
|
|
'11' => 'Departure/Arrival city pair is invalid', |
|
152
|
|
|
'12' => 'Unique name not found', |
|
153
|
|
|
'13' => 'Invalid seat number', |
|
154
|
|
|
'14' => 'Airline code and/or flight number invalid', |
|
155
|
|
|
'15' => 'Flight cancelled', |
|
156
|
|
|
'16' => 'Flight check-in held or suspended temporarily', |
|
157
|
|
|
'17' => 'Passenger surname already checked in', |
|
158
|
|
|
'18' => 'Seating conflict - request contradicts the facility rules', |
|
159
|
|
|
'185' => 'Use airline name', |
|
160
|
|
|
'186' => 'Use passenger status', |
|
161
|
|
|
'187' => 'Flight changes from smoking to non smoking', |
|
162
|
|
|
'188' => 'Flight changes from non smoking to smoking', |
|
163
|
|
|
'189' => 'Pax has pre-reserved exit seat unable to C/I', |
|
164
|
|
|
'19' => 'Baggage weight is required', |
|
165
|
|
|
'190' => 'Pax cannot be seated together', |
|
166
|
|
|
'191' => 'Generic seat change not supported', |
|
167
|
|
|
'192' => 'Seat change-request in row change not supported', |
|
168
|
|
|
'193' => 'API pax data required', |
|
169
|
|
|
'194' => 'Passenger surname not checked in', |
|
170
|
|
|
'195' => 'Change of equipment on this flight', |
|
171
|
|
|
'196' => 'Time out occured on host 3', |
|
172
|
|
|
'197' => 'Error in frequent flyer number', |
|
173
|
|
|
'198' => 'Class code required', |
|
174
|
|
|
'199' => 'Check-in separately', |
|
175
|
|
|
'2' => 'Seat not available on the requested class/zone', |
|
176
|
|
|
'20' => 'Bag count conflict - weight update for non-existing bag', |
|
177
|
|
|
'200' => 'FQTV number not accepted', |
|
178
|
|
|
'201' => 'FQTV number already present', |
|
179
|
|
|
'202' => 'Baggage details not updated', |
|
180
|
|
|
'203' => 'SSR details not updated', |
|
181
|
|
|
'204' => 'Row invalid', |
|
182
|
|
|
'205' => 'Short connection baggage', |
|
183
|
|
|
'206' => 'Seat change only supported for single passenger', |
|
184
|
|
|
'207' => 'Use generic seating only', |
|
185
|
|
|
'208' => 'Update separately', |
|
186
|
|
|
'209' => 'Flight changes from seating to openseating (freeseating)', |
|
187
|
|
|
'21' => 'Seats not available for passenger type', |
|
188
|
|
|
'210' => 'Flight changes from openseating (freeseating) to seating', |
|
189
|
|
|
'211' => 'Unable to through-check - complexing/COG/codeshare flight', |
|
190
|
|
|
'212' => 'API pax data not supported', |
|
191
|
|
|
'213' => 'Time invalid - max/min connecting time for though checkin', |
|
192
|
|
|
'214' => 'API date of birth required', |
|
193
|
|
|
'215' => 'API passport number required', |
|
194
|
|
|
'217' => 'API pax first name required', |
|
195
|
|
|
'218' => 'API pax gender required', |
|
196
|
|
|
'22' => 'Too many connections - need manual tags', |
|
197
|
|
|
'223' => 'API infant data required', |
|
198
|
|
|
'224' => 'Passenger holds advance boarding pass', |
|
199
|
|
|
'225' => 'Seat Map not available as flight operated by another carrier', |
|
200
|
|
|
'226' => 'Seat Request not available as flight operated by another carrier', |
|
201
|
|
|
'227' => 'Seat change not possible/seats limited in this area', |
|
202
|
|
|
'228' => 'Exchange advanced boarding pass - new data', |
|
203
|
|
|
'229' => 'Change not performed on subsequent flight(s)', |
|
204
|
|
|
'23' => 'Invalid bag destination - need manual tags', |
|
205
|
|
|
'230' => 'Unable to seat change - complexing/COG/codeshare flight', |
|
206
|
|
|
'231' => 'Passenger not E.T. type', |
|
207
|
|
|
'232' => 'Passenger is E.T. type - needs E.T. indicator', |
|
208
|
|
|
'233' => 'Passenger is E.T. type - needs E.T. number', |
|
209
|
|
|
'234' => 'Unable to through check - E.T. passenger', |
|
210
|
|
|
'235' => 'Tier level not accepted', |
|
211
|
|
|
'236' => 'Unable to process - codeshare flight', |
|
212
|
|
|
'237' => 'Forward seat due connection - no seat change allowed', |
|
213
|
|
|
'238' => 'Australian Visa required - use TIETAC entry each pax', |
|
214
|
|
|
'239' => 'Advice of handcarry baggage allowance', |
|
215
|
|
|
'24' => 'Passenger actual weight required for this flight', |
|
216
|
|
|
'240' => 'Emergency contact information required for U.S. citizen', |
|
217
|
|
|
'244' => 'Epass passenger - number differs', |
|
218
|
|
|
'245' => 'Epass passenger - not authorized', |
|
219
|
|
|
'246' => 'Epass passenger - possible status discrepency', |
|
220
|
|
|
'247' => 'Message limit exceed', |
|
221
|
|
|
'248' => 'Insufficient upgrade balance', |
|
222
|
|
|
'249' => 'Reissue bag tags to correct destination', |
|
223
|
|
|
'25' => 'Hand baggage details required', |
|
224
|
|
|
'250' => 'Add API data - retry Check in', |
|
225
|
|
|
'251' => 'Advise visa and/or documentation status', |
|
226
|
|
|
'252' => 'Passenger is E.T. type - ticket/reservation conflict', |
|
227
|
|
|
'253' => 'Passenger is E.T. type - ticket record not accessible', |
|
228
|
|
|
'254' => 'Cascaded query timed out', |
|
229
|
|
|
'255' => 'Unable to check-in - Security profile restriction', |
|
230
|
|
|
'256' => 'Passport number printed on boarding pass required', |
|
231
|
|
|
'26' => 'No seat selection on this flight', |
|
232
|
|
|
'264' => 'API pax data not required', |
|
233
|
|
|
'265' => 'Missing or invalid airport check-in identification (FOID)', |
|
234
|
|
|
'27' => 'Location of departure is invalid', |
|
235
|
|
|
'28' => 'Flight rescheduled - through check-in no longer allowed', |
|
236
|
|
|
'29' => 'Flight full in the requested class', |
|
237
|
|
|
'3' => 'Invalid seat request', |
|
238
|
|
|
'30' => 'Passenger surname off-loaded', |
|
239
|
|
|
'300' => 'Seat Map not available for unticketed passengers', |
|
240
|
|
|
'31' => 'Passenger surname deleted/cancelled from the flight', |
|
241
|
|
|
'32' => 'Bag tag number invalid', |
|
242
|
|
|
'33' => 'Flight gated - through check-in is not allowed', |
|
243
|
|
|
'34' => 'Time invalid - minimum connecting time for check-in violated', |
|
244
|
|
|
'35' => 'Flight closed', |
|
245
|
|
|
'36' => 'Passenger not accessible in the system (error/protection)', |
|
246
|
|
|
'37' => 'Unique reference for passenger is invalid', |
|
247
|
|
|
'38' => 'Passenger party reference is invalid', |
|
248
|
|
|
'39' => 'Booking/Ticketing class conflict', |
|
249
|
|
|
'4' => 'Bag tag number details required', |
|
250
|
|
|
'40' => 'Status conflict - status does not exist', |
|
251
|
|
|
'41' => 'Frequent flyer number is invalid', |
|
252
|
|
|
'42' => 'Booking/Ticketing class invalid', |
|
253
|
|
|
'43' => 'Passenger type conflicts with seats held', |
|
254
|
|
|
'44' => 'Too many passengers', |
|
255
|
|
|
'45' => 'Unable - group names', |
|
256
|
|
|
'46' => 'Unable to check-in partial party', |
|
257
|
|
|
'47' => 'Passenger status conflict', |
|
258
|
|
|
'48' => 'PNR locator unknown in the receiving system', |
|
259
|
|
|
'49' => 'Ticket number invalid', |
|
260
|
|
|
'5' => 'Invalid flight/Date', |
|
261
|
|
|
'50' => 'Pool airline invalid', |
|
262
|
|
|
'51' => 'Operating airline invalid', |
|
263
|
|
|
'52' => 'Not authorized - company level', |
|
264
|
|
|
'53' => 'Not authorized - station level', |
|
265
|
|
|
'54' => 'Not authorized - data level', |
|
266
|
|
|
'55' => 'Passenger regraded', |
|
267
|
|
|
'56' => 'Passenger seated elsewhere than requested', |
|
268
|
|
|
'57' => 'Seat not available in the requested class', |
|
269
|
|
|
'58' => 'Seat not available in the requested zone', |
|
270
|
|
|
'59' => 'Specific seat not available', |
|
271
|
|
|
'6' => 'Too many passengers with the same Surname', |
|
272
|
|
|
'60' => 'Free seating in the requested flight', |
|
273
|
|
|
'61' => 'Too many infants', |
|
274
|
|
|
'62' => 'Smoking zone unavailable', |
|
275
|
|
|
'63' => 'Non-smoking zone unavailable', |
|
276
|
|
|
'64' => 'Indifferent zone unavailable', |
|
277
|
|
|
'65' => 'Check visa and/or documentation', |
|
278
|
|
|
'66' => 'No baggage update required for this flight', |
|
279
|
|
|
'67' => 'Gender weight is required', |
|
280
|
|
|
'68' => 'Item conflict', |
|
281
|
|
|
'69' => 'Item weight is required', |
|
282
|
|
|
'7' => 'Passenger type or gender conflict', |
|
283
|
|
|
'70' => 'Modification not possible', |
|
284
|
|
|
'700' => 'Item/data not found - data not existing in processing host', |
|
285
|
|
|
'701' => 'Invalid format - data does not match EDIFACT rules', |
|
286
|
|
|
'702' => 'No action - Processing host can not support the function', |
|
287
|
|
|
'71' => 'No common itinerary', |
|
288
|
|
|
'72' => 'Unable to give seat', |
|
289
|
|
|
'73' => 'Passenger needs initial', |
|
290
|
|
|
'74' => 'Passenger needs first name', |
|
291
|
|
|
'75' => 'Collect second flight name', |
|
292
|
|
|
'76' => 'Check smallpox vaccination', |
|
293
|
|
|
'77' => 'Check yellow fever vaccination', |
|
294
|
|
|
'78' => 'Check cholera vaccination', |
|
295
|
|
|
'79' => 'Passenger has pre-reserved seat', |
|
296
|
|
|
'8' => 'More precise gender is required', |
|
297
|
|
|
'80' => 'Flight initialised - retry check in', |
|
298
|
|
|
'81' => 'Bag through labeling not allowed beyond this station', |
|
299
|
|
|
'82' => 'Too many bags', |
|
300
|
|
|
'83' => 'Flight operated as', |
|
301
|
|
|
'84' => 'Function not supported', |
|
302
|
|
|
'85' => 'Invalid reservations booking modifier', |
|
303
|
|
|
'86' => 'Invalid compartment designator code', |
|
304
|
|
|
'87' => 'Invalid country code', |
|
305
|
|
|
'88' => 'Invalid source of business', |
|
306
|
|
|
'89' => 'Invalid agent\'s code', |
|
307
|
|
|
'9' => 'Flight is not open for through check-in', |
|
308
|
|
|
'90' => 'Requester identification required', |
|
309
|
|
|
'91' => 'Seat Map Display request is outside system date range', |
|
310
|
|
|
'92' => 'Flight does not operate due to weather, mechanical or other operational conditions', |
|
311
|
|
|
'93' => 'Flight does not operate on date requested', |
|
312
|
|
|
'94' => 'Flight does not operate between requested cities', |
|
313
|
|
|
'95' => 'Schedule change in progress', |
|
314
|
|
|
'96' => 'Repeat request updating in progress', |
|
315
|
|
|
'97' => 'Flight has departed', |
|
316
|
|
|
'98' => 'Seating closed due flight under departure control', |
|
317
|
|
|
'99' => 'Seat map not available for requested zone, seat may be requested', |
|
318
|
|
|
]; |
|
319
|
|
|
} |
|
320
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.