SimFQT Logo  0.1.3
C++ Simulated Fare Quote System Library
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
FareQuoter.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 #include <sstream>
7 // StdAir
8 #include <stdair/basic/BasConst_BomDisplay.hpp>
9 #include <stdair/bom/BomKeyManager.hpp>
10 #include <stdair/bom/ParsedKey.hpp>
11 #include <stdair/bom/BomManager.hpp>
12 #include <stdair/bom/BomRoot.hpp>
13 #include <stdair/bom/InventoryKey.hpp>
14 #include <stdair/bom/FlightDateKey.hpp>
15 #include <stdair/bom/SegmentDateKey.hpp>
16 #include <stdair/bom/AirlineClassList.hpp>
17 #include <stdair/bom/AirportPair.hpp>
18 #include <stdair/bom/PosChannel.hpp>
19 #include <stdair/bom/DatePeriod.hpp>
20 #include <stdair/bom/TimePeriod.hpp>
21 #include <stdair/bom/FareFeatures.hpp>
22 #include <stdair/bom/BookingRequestStruct.hpp>
23 #include <stdair/bom/TravelSolutionStruct.hpp>
24 #include <stdair/service/Logger.hpp>
25 #include <stdair/bom/key_types.hpp>
26 // SimFQT
27 #include <simfqt/SIMFQT_Types.hpp>
29 
30 namespace SIMFQT {
31 
32  bool FareQuoter::_atLeastOneAvailableDateRule = false;
33  bool FareQuoter::_atLeastOneAvailablePosChannel = false;
34  bool FareQuoter::_atLeastOneAvailableTimeRule = false;
35  bool FareQuoter::_atLeastOneAvailableFeaturesRule = false;
36  bool FareQuoter::_atLeastOneAvailableAirlineClassRule= false;
37 
38  // //////////////////////////////////////////////////////////////////////
39  FareQuoter::FareQuoter() {
40  assert (false);
41  }
42 
43  // //////////////////////////////////////////////////////////////////////
44  FareQuoter::FareQuoter(const FareQuoter&) {
45  assert (false);
46  }
47 
48  // //////////////////////////////////////////////////////////////////////
49  FareQuoter::~FareQuoter() {
50  }
51 
52  // //////////////////////////////////////////////////////////////////////
53  void FareQuoter::reset() {
54  _atLeastOneAvailableDateRule = false;
55  _atLeastOneAvailablePosChannel = false;
56  _atLeastOneAvailableTimeRule = false;
57  _atLeastOneAvailableFeaturesRule = false;
58  _atLeastOneAvailableAirlineClassRule = false;
59  }
60 
61 
62  // //////////////////////////////////////////////////////////////////////
63  void FareQuoter::
64  priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
65  stdair::TravelSolutionList_T& ioTravelSolutionList,
66  const stdair::BomRoot& iBomRoot) {
67 
68  // Do an independent price quote for each travel solution related to the
69  // booking request.
70  for (stdair::TravelSolutionList_T::iterator itTravelSolution =
71  ioTravelSolutionList.begin();
72  itTravelSolution != ioTravelSolutionList.end(); ++itTravelSolution) {
73  reset();
74  // Select a travel solution.
75  stdair::TravelSolutionStruct& lTravelSolutionStruct = *itTravelSolution;
76  // Price quote the travel solution into question.
77  priceQuote (iBookingRequest, lTravelSolutionStruct, iBomRoot);
78  }
79  }
80 
81  // //////////////////////////////////////////////////////////////////////
82  void FareQuoter::
83  priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
84  stdair::TravelSolutionStruct& ioTravelSolution,
85  const stdair::BomRoot& iBomRoot) {
86 
87  // Get the origin of the first segment in order to get the origin of
88  // the solution.
89  const stdair::ParsedKey& lFirstSegmentKey =
90  getFirstSPParsedKey(ioTravelSolution);
91  const stdair::AirportCode_T& lOrigin = lFirstSegmentKey._boardingPoint;
92 
93  // Get the destination of the last segment in order to get the
94  // destination of the solution.
95  const stdair::ParsedKey& lLastSegmentKey =
96  getLastSPParsedKey(ioTravelSolution);
97  const stdair::AirportCode_T& lDestination = lLastSegmentKey._offPoint;
98 
99  // Construct the Airport pair stream of the segment path.
100  const stdair::AirportPairKey lAirportPairKey (lOrigin, lDestination);
101 
102  // Search for the fare rules having the same origin and destination airports
103  // as the travel solution
104  const stdair::AirportPair* lAirportPair_ptr = stdair::BomManager::
105  getObjectPtr<stdair::AirportPair> (iBomRoot, lAirportPairKey.toString());
106 
107  // If no fare rule has the same origin and destination airports, the pricing
108  // is not possible, throw an exception.
109  if (lAirportPair_ptr == NULL) {
110  STDAIR_LOG_ERROR ("No available fare rule for the "
111  << "Origin-Destination pair: "
112  << lAirportPairKey.toString());
113  throw AirportPairNotFoundException ("No available fare rule for "
114  "the Origin-Destination pair: "
115  + lAirportPairKey.toString());
116  }
117  // Sanity check.
118  assert(lAirportPair_ptr != NULL);
119 
120  // Fare rule(s) with the same origin and destination airports exist(s), now
121  // the date range need to be checked.
122  const stdair::AirportPair& lAirportPair = *lAirportPair_ptr;
123  priceQuote(iBookingRequest, ioTravelSolution, lAirportPair);
124 
125  if (_atLeastOneAvailableAirlineClassRule == false) {
126  displayMissingFareRuleMessage(iBookingRequest, ioTravelSolution);
127  }
128  }
129 
130  // //////////////////////////////////////////////////////////////////////
131  void FareQuoter::
132  priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
133  stdair::TravelSolutionStruct& ioTravelSolution,
134  const stdair::AirportPair& iAirportPair) {
135 
136  // Get the first segment path parsed key.
137  const stdair::ParsedKey lFirstSPParsedKey =
138  getFirstSPParsedKey(ioTravelSolution);
139 
140  // Get the date of the first segment date key.
141  const stdair::FlightDateKey& lFlightDateKey =
142  lFirstSPParsedKey.getFlightDateKey();
143  const stdair::Date_T& lSPDate = lFlightDateKey.getDepartureDate();
144 
145  // Get the list of the fare date ranges.
146  const stdair::DatePeriodList_T& lFareDatePeriodList =
147  stdair::BomManager::getList<stdair::DatePeriod> (iAirportPair);
148 
149  // Browse the list of the fare rules date range.
150  for (stdair::DatePeriodList_T::const_iterator itDateRange =
151  lFareDatePeriodList.begin();
152  itDateRange != lFareDatePeriodList.end(); ++itDateRange) {
153 
154  const stdair::DatePeriod* lCurrentFareDatePeriod_ptr = *itDateRange ;
155  assert (lCurrentFareDatePeriod_ptr != NULL);
156 
157  // Select the fare rules having a corresponding date range.
158  const bool isDepartureDateValid =
159  lCurrentFareDatePeriod_ptr->isDepartureDateValid (lSPDate);
160 
161  // If a fare rule has a corresponding date range, its channel and position
162  // need to be checked.
163  if (isDepartureDateValid == true) {
164  _atLeastOneAvailableDateRule = true;
165  const stdair::DatePeriod& lCurrentFareDatePeriod =
166  *lCurrentFareDatePeriod_ptr;
167  priceQuote (iBookingRequest, ioTravelSolution,
168  lCurrentFareDatePeriod, iAirportPair);
169  }
170  }
171 
172  }
173 
174  // //////////////////////////////////////////////////////////////////////
175  void FareQuoter::
176  priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
177  stdair::TravelSolutionStruct& ioTravelSolution,
178  const stdair::DatePeriod& iFareDatePeriod,
179  const stdair::AirportPair& iAirportPair) {
180 
181  // Get the point-of-sale of the booking request.
182  const stdair::CityCode_T& lPointOfSale = iBookingRequest.getPOS();
183 
184  // Get the booking request channel.
185  const stdair::ChannelLabel_T& lChannel =
186  iBookingRequest.getBookingChannel();
187 
188  // Construct the corresponding POS-channel primary key.
189  const stdair::PosChannelKey lFarePosChannelKey (lPointOfSale, lChannel);
190 
191  // Search for the fare rules having the same point-of-sale and channel as
192  // the travel solution.
193  const stdair::PosChannelList_T lFarePosChannelList =
194  stdair::BomManager::getList<stdair::PosChannel> (iFareDatePeriod);
195 
196  // Browse the list of the fare rules pos channel.
197  for (stdair::PosChannelList_T::const_iterator itPosChannel =
198  lFarePosChannelList.begin();
199  itPosChannel != lFarePosChannelList.end();
200  ++itPosChannel) {
201  const stdair::PosChannel* lCurrentFarePosChannel_ptr = *itPosChannel;
202  assert (lCurrentFarePosChannel_ptr != NULL);
203 
204  // Get the point-of-sale and channel of the current fare rule.
205  const stdair::CityCode_T& lCurrentPointOfSale =
206  lCurrentFarePosChannel_ptr->getPos();
207  const stdair::ChannelLabel_T& lCurrentChannel =
208  lCurrentFarePosChannel_ptr->getChannel();
209 
210  // Select the fare rules having a corresponding pos channel.
211  if (lCurrentPointOfSale == lPointOfSale &&
212  lCurrentChannel == lChannel) {
213  _atLeastOneAvailablePosChannel = true;
214  // Fare rule(s) with the same point-of-sale and channel exist(s), now
215  // the time range need to be checked.
216  const stdair::PosChannel& lFarePosChannel= *lCurrentFarePosChannel_ptr;
217  priceQuote (iBookingRequest, ioTravelSolution, lFarePosChannel);
218  }
219  }
220 
221  }
222 
223  // //////////////////////////////////////////////////////////////////////
224  void FareQuoter::
225  priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
226  stdair::TravelSolutionStruct& ioTravelSolution,
227  const stdair::PosChannel& iFarePosChannel) {
228 
229  // Get the first segment path parsed key.
230  const stdair::ParsedKey lFirstSPParsedKey =
231  getFirstSPParsedKey(ioTravelSolution);
232 
233  // Get the segment boarding time of the segment path.
234  const stdair::Duration_T& lSPTime = lFirstSPParsedKey.getBoardingTime();
235 
236  // Get the list of the fare rules time period.
237  const stdair::TimePeriodList_T& lFareTimePeriodList =
238  stdair::BomManager::getList<stdair::TimePeriod> (iFarePosChannel);
239 
240  // Browse the list of the fare rules time range.
241  for (stdair::TimePeriodList_T::const_iterator itTimeRange =
242  lFareTimePeriodList.begin();
243  itTimeRange != lFareTimePeriodList.end();
244  ++itTimeRange) {
245  const stdair::TimePeriod* lCurrentFareTimePeriod_ptr = *itTimeRange ;
246  assert (lCurrentFareTimePeriod_ptr != NULL);
247 
248  // Select the fare rules having a corresponding time range.
249  const bool isDepartureTimeValid =
250  lCurrentFareTimePeriod_ptr->isDepartureTimeValid (lSPTime);
251 
252  // If a fare rule has a corresponding time range, its advanced purchase,
253  // trip type and minimum stay duration need to be checked.
254  if (isDepartureTimeValid) {
255  _atLeastOneAvailableTimeRule = true;
256  const stdair::TimePeriod& lCurrentFareTimePeriod =
257  *lCurrentFareTimePeriod_ptr;
258  priceQuote (iBookingRequest, ioTravelSolution,
259  lCurrentFareTimePeriod, iFarePosChannel);
260  }
261  }
262 
263  }
264 
265  // //////////////////////////////////////////////////////////////////////
266  void FareQuoter::
267  priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
268  stdair::TravelSolutionStruct& ioTravelSolution,
269  const stdair::TimePeriod& iFareTimePeriod,
270  const stdair::PosChannel& iFarePosChannel) {
271 
272  // Get the stay duration of the booking request.
273  const stdair::DayDuration_T& lStayDuration=
274  iBookingRequest.getStayDuration();
275 
276  // Get the booking request trip type.
277  const stdair::TripType_T& lTripType =
278  iBookingRequest.getTripType();
279 
280  // Get the booking request date time.
281  const stdair::DateTime_T& lRequestDateTime =
282  iBookingRequest.getRequestDateTime();
283 
284  // Get the referenced departure date of the segment path.
285  const stdair::ParsedKey lFirstSPParsedKey =
286  getFirstSPParsedKey(ioTravelSolution);
287  const stdair::Date_T& lSPDate =
288  lFirstSPParsedKey.getFlightDateKey().getDepartureDate();
289 
290  // Get the segment boarding time of the segment path.
291  const stdair::Duration_T& lSPTime = lFirstSPParsedKey.getBoardingTime();
292 
293  // Construct the date-time type correponding to the flight date
294  const stdair::DateTime_T lSPDateTime (lSPDate, lSPTime);
295 
296  bool isTripTypeValid = false;
297  bool isStayDurationValid = false;
298  bool isAdvancePurchaseValid = false;
299 
300  // Get the list of the fare features.
301  const stdair::FareFeaturesList_T& lFareFeaturesList =
302  stdair::BomManager::getList<stdair::FareFeatures> (iFareTimePeriod);
303 
304  // Browse the list of the fare rules features.
305  for (stdair::FareFeaturesList_T::const_iterator itFareFeatures =
306  lFareFeaturesList.begin();
307  itFareFeatures != lFareFeaturesList.end();
308  ++itFareFeatures) {
309  const stdair::FareFeatures* lCurrentFareFeatures_ptr =
310  *itFareFeatures;
311  assert (lCurrentFareFeatures_ptr != NULL);
312 
313  // Does the current fare features correspond to a correct trip
314  // type?
315  isTripTypeValid =
316  lCurrentFareFeatures_ptr->isTripTypeValid (lTripType);
317  // Does the current fare features correspond to a correct stay
318  // duration?
319  isStayDurationValid =
320  lCurrentFareFeatures_ptr->isStayDurationValid (lStayDuration);
321  // Does the current fare features correspond to a correct advanced
322  // purchase?
323  isAdvancePurchaseValid = lCurrentFareFeatures_ptr->
324  isAdvancePurchaseValid (lRequestDateTime,
325  lSPDateTime);
326 
327  // Search for the fare rules having corresponding features.
328  if (isStayDurationValid && isAdvancePurchaseValid && isTripTypeValid){
329  _atLeastOneAvailableFeaturesRule = true;
330  // Create a fare structure for the travel solution.
331  stdair::FareOptionStruct lFareOption;
332  const stdair::ChangeFees_T& lChangeFees =
333  lCurrentFareFeatures_ptr->getChangeFees();
334  // Set the fare change fees.
335  lFareOption.setChangeFees (lChangeFees);
336  const stdair::NonRefundable_T& lNonRefundable =
337  lCurrentFareFeatures_ptr->getRefundableOption();
338  // Set the fare refundable option.
339  lFareOption.setNonRefundable (lNonRefundable);
340  const stdair::SaturdayStay_T& lSaturdayStay =
341  lCurrentFareFeatures_ptr->getSaturdayStay();
342  // Set the fare saturday night stay option.
343  lFareOption.setSaturdayStay (lSaturdayStay);
344  const stdair::FareFeatures& lCurrentFareFeatures =
345  *lCurrentFareFeatures_ptr;
346  priceQuote (iBookingRequest, ioTravelSolution,
347  lCurrentFareFeatures, iFarePosChannel,
348  lFareOption);
349  }
350  }
351 
352  }
353 
354 
355  // //////////////////////////////////////////////////////////////////////
356  void FareQuoter::
357  priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
358  stdair::TravelSolutionStruct& ioTravelSolution,
359  const stdair::FareFeatures& iFareFeatures,
360  const stdair::PosChannel& iFarePosChannel,
361  stdair::FareOptionStruct& iFareOption) {
362 
363  // Get the first segment path parsed key.
364  const stdair::ParsedKey lFirstSPParsedKey =
365  getFirstSPParsedKey(ioTravelSolution);
366 
367  // Get the segment-path of the travel solution.
368  const stdair::SegmentPath_T& lSegmentPath =
369  ioTravelSolution.getSegmentPath();
370 
371  // Get the list of the fare rules.
372  const stdair::AirlineClassListList_T& lAirlineClassListList =
373  stdair::BomManager::getList<stdair::AirlineClassList> (iFareFeatures);
374 
375  bool lCorrectAirlineRule = false;
376  bool lAtLeastOneDifferentAirline = false;
377 
378  // Browse the list of airline code list and search for the fare rules
379  // having a corresponding airline list.
380  for (stdair::AirlineClassListList_T::const_iterator itAirlineClassList =
381  lAirlineClassListList.begin();
382  itAirlineClassList != lAirlineClassListList.end();
383  ++itAirlineClassList) {
384  const stdair::AirlineClassList* lCurrentAirlineClassList_ptr =
385  *itAirlineClassList;
386  assert (lCurrentAirlineClassList_ptr != NULL);
387 
388  lCorrectAirlineRule = true;
389  lAtLeastOneDifferentAirline = false;
390 
391  const stdair::ClassList_StringList_T lClassList_StringList =
392  lCurrentAirlineClassList_ptr->getAirlineCodeList();
393 
394  // Compare the segment path airline list with the fare rule airline list.
395  if (lClassList_StringList.size() == lSegmentPath.size()) {
396  // If the two sizes are equal, we need to compare the airline codes.
397  stdair::SegmentPath_T::const_iterator itSegmentPath =
398  lSegmentPath.begin();
399 
400  stdair::ClassList_StringList_T::const_iterator itClassList_String =
401  lClassList_StringList.begin();
402  // Browse the segment path airline code list (while the segment path
403  // airline list is equal to the fare rule airline list).
404  while (itSegmentPath != lSegmentPath.end()
405  && lAtLeastOneDifferentAirline == false) {
406 
407  // Get the segment airline code.
408  const std::string lSegmentDateKey = *itSegmentPath;
409  const stdair::ParsedKey& lParsedKey =
410  stdair::BomKeyManager::extractKeys (lSegmentDateKey);
411  const stdair::InventoryKey& lInventoryKey =
412  lParsedKey.getInventoryKey();
413  const stdair::AirlineCode_T& lSegmentAirlineCode =
414  lInventoryKey.getAirlineCode();
415 
416  // Get the fare rule airline code.
417  const stdair::AirlineCode_T& lFareRuleAirlineCode =
418  *itClassList_String;
419 
420  if (lSegmentAirlineCode != lFareRuleAirlineCode) {
421  lAtLeastOneDifferentAirline = true;
422  }
423  itSegmentPath++;
424  itClassList_String++;
425  }
426 
427  } else {
428  // If the two sizes are different, the fare rule does not match the
429  // travel solution into question.
430  lCorrectAirlineRule = false;
431  }
432 
433  // If one segment airline code and one fare rule airline code are
434  // different then the fare rule does not match the travel solution.
435  if (lAtLeastOneDifferentAirline == true) {
436  lCorrectAirlineRule = false;
437  }
438 
439  // If the current fare rule is a match, add the fare option structure
440  // to the travel solution into question.
441  if (lCorrectAirlineRule == true) {
442  _atLeastOneAvailableAirlineClassRule = true;
443  // Get the booking request trip type.
444  const stdair::TripType_T& lTripType =
445  iBookingRequest.getTripType();
446 
447  // Get the travel fare.
448  stdair::Fare_T lFare =
449  lCurrentAirlineClassList_ptr->getFare();
450  // If the trip into question is the inbound or outbound part of a round trip,
451  // the applicable fare is a half RT fare.
452  if (lTripType == "RI" || lTripType == "RO") {
453  lFare /= 2;
454  }
455  // Set the travel fare option.
456  iFareOption.setFare (lFare);
457  // Copy the class path list into the fare option.
458  const stdair::ClassList_StringList_T& lClassCodeList =
459  lCurrentAirlineClassList_ptr->getClassCodeList();
460  for (stdair::ClassList_StringList_T::const_iterator itClassCodeList =
461  lClassCodeList.begin();
462  itClassCodeList != lClassCodeList.end(); ++itClassCodeList ) {
463  const stdair::ClassList_String_T& lClassCodeList = *itClassCodeList;
464  iFareOption.addClassList (lClassCodeList);
465  }
466 
467  // Add the fare option to the travel solution into question.
468  ioTravelSolution.addFareOption (iFareOption);
469 
470  // DEBUG
471  STDAIR_LOG_DEBUG ("Segment path: " << lFirstSPParsedKey.toString()
472  << ". A corresponding fare option for the '"
473  << lCurrentAirlineClassList_ptr->describeKey()
474  << "' class is: " << iFareOption);
475 
476  iFareOption.emptyClassList();
477  }
478  }
479 
480  }
481 
482  // //////////////////////////////////////////////////////////////////////
483  stdair::ParsedKey FareQuoter::
484  getFirstSPParsedKey (stdair::TravelSolutionStruct& ioTravelSolution) {
485 
486  // Get the segment-path of the travel solution.
487  const stdair::SegmentPath_T& lSegmentPath =
488  ioTravelSolution.getSegmentPath();
489 
490  // Get the number of segments of the travel solution.
491  const stdair::NbOfSegments_T& lNbSegments = lSegmentPath.size();
492 
493  // Sanity check: there is at least one segment in the travel solution.
494  assert (lNbSegments >= 1);
495 
496  // Get the first segment of the travel solution.
497  const std::string& lFirstSegmentDateKey = lSegmentPath.front();
498 
499  // Get the parsed key of the first segment of the travel solution.
500  const stdair::ParsedKey& lFirstSegmentParsedKey =
501  stdair::BomKeyManager::extractKeys (lFirstSegmentDateKey);
502 
503  return lFirstSegmentParsedKey;
504 
505  }
506 
507  // //////////////////////////////////////////////////////////////////////
508  stdair::ParsedKey FareQuoter::
509  getLastSPParsedKey (stdair::TravelSolutionStruct& ioTravelSolution) {
510 
511  // Get the segment-path of the travel solution.
512  const stdair::SegmentPath_T& lSegmentPath =
513  ioTravelSolution.getSegmentPath();
514 
515  // Get the number of segments of the travel solution.
516  const stdair::NbOfSegments_T& lNbSegments = lSegmentPath.size();
517 
518  // Sanity check: there is at least one segment in the travel solution.
519  assert (lNbSegments >= 1);
520 
521  // Get the last segment of the travel solution.
522  const std::string& lLastSegmentDateKey = lSegmentPath.back();
523 
524  // Get the parsed key of the last segment of the travel solution.
525  const stdair::ParsedKey& lLastSegmentParsedKey =
526  stdair::BomKeyManager::extractKeys (lLastSegmentDateKey);
527 
528  return lLastSegmentParsedKey;
529 
530  }
531 
532  // //////////////////////////////////////////////////////////////////////
533  void FareQuoter::
534  displayMissingFareRuleMessage (const stdair::BookingRequestStruct& iBookingRequest,
535  stdair::TravelSolutionStruct& ioTravelSolution) {
536 
537  // Get the origin of the first segment in order to get the origin of
538  // the solution.
539  const stdair::ParsedKey lFirstSPParsedKey =
540  getFirstSPParsedKey(ioTravelSolution);
541  const stdair::AirportCode_T& lOrigin = lFirstSPParsedKey._boardingPoint;
542 
543  // Get the destination of the last segment in order to get the
544  // destination of the solution.
545  const stdair::ParsedKey& lLastSegmentKey =
546  getLastSPParsedKey(ioTravelSolution);
547  const stdair::AirportCode_T& lDestination = lLastSegmentKey._offPoint;
548 
549  // Construct the Airport pair stream of the segment path.
550  const stdair::AirportPairKey lAirportPairKey (lOrigin, lDestination);
551 
552  // Get the date of the first segment date key.
553  const stdair::FlightDateKey& lFlightDateKey =
554  lFirstSPParsedKey.getFlightDateKey();
555 
556  // Get the point-of-sale of the booking request.
557  const stdair::CityCode_T& lPointOfSale = iBookingRequest.getPOS();
558  // Get the booking request channel.
559  const stdair::ChannelLabel_T& lChannel =
560  iBookingRequest.getBookingChannel();
561  // Construct the corresponding POS-channel primary key.
562  const stdair::PosChannelKey lFarePosChannelKey (lPointOfSale, lChannel);
563 
564  // Get the booking request date time.
565  const stdair::DateTime_T& lRequestDateTime =
566  iBookingRequest.getRequestDateTime();
567 
568  // If no fare rule has a corresponding date range, the pricing is not
569  // possible, throw an exception.
570  if (_atLeastOneAvailableDateRule == false) {
571  const stdair::SegmentDateKey lSegmentDateKey =
572  lFirstSPParsedKey.getSegmentKey();
573  STDAIR_LOG_ERROR ("No available fare rule corresponding to the "
574  "flight date " << lFlightDateKey.toString()
575  << " and the Origin-Destination pair: "
576  << lSegmentDateKey.toString());
577  throw FlightDateNotFoundException ("No available fare rule for the "
578  "flight date "
579  + lFlightDateKey.toString()
580  + " and the Origin-Destination pair: "
581  + lSegmentDateKey.toString());
582  }
583  // If no fare rule has a corresponding pos channel, the pricing is not possible,
584  // throw an exception.
585  else if (_atLeastOneAvailablePosChannel == false) {
586  STDAIR_LOG_ERROR ("No available fare rule corresponding to the "
587  "point of sale " << lPointOfSale
588  << ", to the channel " << lChannel
589  << ", to the flight date "
590  << lFlightDateKey.toString()
591  << " and to the Origin-Destination pair: "
592  << lAirportPairKey.toString());
593  throw PosOrChannelNotFoundException ("No available fare rule for the "
594  "point of sale " + lPointOfSale
595  + ", the channel " + lChannel
596  + ", the flight date "
597  + lFlightDateKey.toString()
598  + " and the Origin-Destination pair: "
599  + lAirportPairKey.toString());
600  }
601  // If no fare rule has a corresponding time range, the pricing is not possible,
602  // throw an exception.
603  else if (_atLeastOneAvailableTimeRule == false) {
604  STDAIR_LOG_ERROR ("No available fare rule corresponding to '"
605  << lFirstSPParsedKey.toString() << "' (parsed key) and to '"
606  << lFarePosChannelKey.toString() << "' (POS and channel)");
607  throw FlightTimeNotFoundException ("No available fare rule corresponding "
608  "to '" + lFirstSPParsedKey.toString()
609  + "' (parsed key) and to '"
610  + lFarePosChannelKey.toString()
611  + "' (POS and channel)");
612  }
613  // If no fare rule matches the advance purchase, trip type and stay
614  // duration criterion, the pricing is not possible, throw an exception.
615  else if (_atLeastOneAvailableFeaturesRule == false) {
616  // Get the stay duration of the booking request.
617  const stdair::DayDuration_T& lStayDuration=
618  iBookingRequest.getStayDuration();
619  std::ostringstream lStayDurationStream;
620  lStayDurationStream << lStayDuration;
621  const std::string lStayDurationString (lStayDurationStream.str());
622 
623  // Get the booking request trip type.
624  const stdair::TripType_T& lTripType =
625  iBookingRequest.getTripType();
626 
627  STDAIR_LOG_ERROR ("No available fare rule corresponding to a "
628  "trip type " << lTripType
629  << ", to a stay duration of " << lStayDurationString
630  << ", to a request date time of " << lRequestDateTime
631  << ", to '" << lFirstSPParsedKey.toString()
632  << "' (parsed key) and to '"
633  << lFarePosChannelKey << "' (POS and channel)");
634  throw FeaturesNotFoundException ("No available fare rule corresponding to a "
635  "trip type " + lTripType
636  + ", to a stay duration of "
637  + lStayDurationString
638  + ", to a request date time of "
639  + boost::posix_time::to_simple_string(lRequestDateTime)
640  + ", to '" + lFirstSPParsedKey.toString()
641  + "' (parsed key) and to '"
642  + lFarePosChannelKey.toString()
643  + "' (POS and channel)");
644  }
645  assert (_atLeastOneAvailableAirlineClassRule == false);
646  // If no fare rule matches the airline class path, the pricing is not
647  // possible, throw an exception.
648  STDAIR_LOG_ERROR ("No available fare rule corresponding to '"
649  << lFirstSPParsedKey .toString() << "' (parsed key), to '"
650  << iBookingRequest.describe()
651  << "' (booking request) and to '"
652  << lFarePosChannelKey.toString() << "' (POS and channel)");
653  throw AirlineNotFoundException ("No available fare rule corresponding to '"
654  + lFirstSPParsedKey .toString()
655  + "' (parsed key), to '"
656  + iBookingRequest.describe()
657  + "' (booking request) and to '"
658  + lFarePosChannelKey.toString()
659  + "' (POS and channel)");
660  }
661 }
662