00001
00002
00003
00004
00005 #include <cassert>
00006 #include <sstream>
00007
00008 #include <stdair/basic/BasConst_BomDisplay.hpp>
00009 #include <stdair/bom/BomKeyManager.hpp>
00010 #include <stdair/bom/ParsedKey.hpp>
00011 #include <stdair/bom/BomManager.hpp>
00012 #include <stdair/bom/BomRoot.hpp>
00013 #include <stdair/bom/InventoryKey.hpp>
00014 #include <stdair/bom/FlightDateKey.hpp>
00015 #include <stdair/bom/SegmentDateKey.hpp>
00016 #include <stdair/bom/AirlineClassList.hpp>
00017 #include <stdair/bom/AirportPair.hpp>
00018 #include <stdair/bom/PosChannel.hpp>
00019 #include <stdair/bom/DatePeriod.hpp>
00020 #include <stdair/bom/TimePeriod.hpp>
00021 #include <stdair/bom/FareFeatures.hpp>
00022 #include <stdair/bom/BookingRequestStruct.hpp>
00023 #include <stdair/bom/TravelSolutionStruct.hpp>
00024 #include <stdair/service/Logger.hpp>
00025 #include <stdair/bom/key_types.hpp>
00026
00027 #include <simfqt/SIMFQT_Types.hpp>
00028 #include <simfqt/command/FareQuoter.hpp>
00029
00030 namespace SIMFQT {
00031
00032 bool FareQuoter::_atLeastOneAvailableDateRule = false;
00033 bool FareQuoter::_atLeastOneAvailablePosChannel = false;
00034 bool FareQuoter::_atLeastOneAvailableTimeRule = false;
00035 bool FareQuoter::_atLeastOneAvailableFeaturesRule = false;
00036 bool FareQuoter::_atLeastOneAvailableAirlineClassRule= false;
00037
00038
00039 FareQuoter::FareQuoter() {
00040 assert (false);
00041 }
00042
00043
00044 FareQuoter::FareQuoter(const FareQuoter&) {
00045 assert (false);
00046 }
00047
00048
00049 FareQuoter::~FareQuoter() {
00050 }
00051
00052
00053 void FareQuoter::reset() {
00054 _atLeastOneAvailableDateRule = false;
00055 _atLeastOneAvailablePosChannel = false;
00056 _atLeastOneAvailableTimeRule = false;
00057 _atLeastOneAvailableFeaturesRule = false;
00058 _atLeastOneAvailableAirlineClassRule = false;
00059 }
00060
00061
00062
00063 void FareQuoter::
00064 priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
00065 stdair::TravelSolutionList_T& ioTravelSolutionList,
00066 const stdair::BomRoot& iBomRoot) {
00067
00068
00069
00070 for (stdair::TravelSolutionList_T::iterator itTravelSolution =
00071 ioTravelSolutionList.begin();
00072 itTravelSolution != ioTravelSolutionList.end(); ++itTravelSolution) {
00073 reset();
00074
00075 stdair::TravelSolutionStruct& lTravelSolutionStruct = *itTravelSolution;
00076
00077 priceQuote (iBookingRequest, lTravelSolutionStruct, iBomRoot);
00078 }
00079 }
00080
00081
00082 void FareQuoter::
00083 priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
00084 stdair::TravelSolutionStruct& ioTravelSolution,
00085 const stdair::BomRoot& iBomRoot) {
00086
00087
00088
00089 const stdair::ParsedKey& lFirstSegmentKey =
00090 getFirstSPParsedKey(ioTravelSolution);
00091 const stdair::AirportCode_T& lOrigin = lFirstSegmentKey._boardingPoint;
00092
00093
00094
00095 const stdair::ParsedKey& lLastSegmentKey =
00096 getLastSPParsedKey(ioTravelSolution);
00097 const stdair::AirportCode_T& lDestination = lLastSegmentKey._offPoint;
00098
00099
00100 const stdair::AirportPairKey lAirportPairKey (lOrigin, lDestination);
00101
00102
00103
00104 const stdair::AirportPair* lAirportPair_ptr = stdair::BomManager::
00105 getObjectPtr<stdair::AirportPair> (iBomRoot, lAirportPairKey.toString());
00106
00107
00108
00109 if (lAirportPair_ptr == NULL) {
00110 STDAIR_LOG_ERROR ("No available fare rule for the "
00111 << "Origin-Destination pair: "
00112 << lAirportPairKey.toString());
00113 throw AirportPairNotFoundException ("No available fare rule for "
00114 "the Origin-Destination pair: "
00115 + lAirportPairKey.toString());
00116 }
00117
00118 assert(lAirportPair_ptr != NULL);
00119
00120
00121
00122 const stdair::AirportPair& lAirportPair = *lAirportPair_ptr;
00123 priceQuote(iBookingRequest, ioTravelSolution, lAirportPair);
00124
00125 if (_atLeastOneAvailableAirlineClassRule == false) {
00126 displayMissingFareRuleMessage(iBookingRequest, ioTravelSolution);
00127 }
00128 }
00129
00130
00131 void FareQuoter::
00132 priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
00133 stdair::TravelSolutionStruct& ioTravelSolution,
00134 const stdair::AirportPair& iAirportPair) {
00135
00136
00137 const stdair::ParsedKey lFirstSPParsedKey =
00138 getFirstSPParsedKey(ioTravelSolution);
00139
00140
00141 const stdair::FlightDateKey& lFlightDateKey =
00142 lFirstSPParsedKey.getFlightDateKey();
00143 const stdair::Date_T& lSPDate = lFlightDateKey.getDepartureDate();
00144
00145
00146 const stdair::DatePeriodList_T& lFareDatePeriodList =
00147 stdair::BomManager::getList<stdair::DatePeriod> (iAirportPair);
00148
00149
00150 for (stdair::DatePeriodList_T::const_iterator itDateRange =
00151 lFareDatePeriodList.begin();
00152 itDateRange != lFareDatePeriodList.end(); ++itDateRange) {
00153
00154 const stdair::DatePeriod* lCurrentFareDatePeriod_ptr = *itDateRange ;
00155 assert (lCurrentFareDatePeriod_ptr != NULL);
00156
00157
00158 const bool isDepartureDateValid =
00159 lCurrentFareDatePeriod_ptr->isDepartureDateValid (lSPDate);
00160
00161
00162
00163 if (isDepartureDateValid == true) {
00164 _atLeastOneAvailableDateRule = true;
00165 const stdair::DatePeriod& lCurrentFareDatePeriod =
00166 *lCurrentFareDatePeriod_ptr;
00167 priceQuote (iBookingRequest, ioTravelSolution,
00168 lCurrentFareDatePeriod, iAirportPair);
00169 }
00170 }
00171
00172 }
00173
00174
00175 void FareQuoter::
00176 priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
00177 stdair::TravelSolutionStruct& ioTravelSolution,
00178 const stdair::DatePeriod& iFareDatePeriod,
00179 const stdair::AirportPair& iAirportPair) {
00180
00181
00182 const stdair::CityCode_T& lPointOfSale = iBookingRequest.getPOS();
00183
00184
00185 const stdair::ChannelLabel_T& lChannel =
00186 iBookingRequest.getBookingChannel();
00187
00188
00189 const stdair::PosChannelKey lFarePosChannelKey (lPointOfSale, lChannel);
00190
00191
00192
00193 const stdair::PosChannelList_T lFarePosChannelList =
00194 stdair::BomManager::getList<stdair::PosChannel> (iFareDatePeriod);
00195
00196
00197 for (stdair::PosChannelList_T::const_iterator itPosChannel =
00198 lFarePosChannelList.begin();
00199 itPosChannel != lFarePosChannelList.end();
00200 ++itPosChannel) {
00201 const stdair::PosChannel* lCurrentFarePosChannel_ptr = *itPosChannel;
00202 assert (lCurrentFarePosChannel_ptr != NULL);
00203
00204
00205 const stdair::CityCode_T& lCurrentPointOfSale =
00206 lCurrentFarePosChannel_ptr->getPos();
00207 const stdair::ChannelLabel_T& lCurrentChannel =
00208 lCurrentFarePosChannel_ptr->getChannel();
00209
00210
00211 if (lCurrentPointOfSale == lPointOfSale &&
00212 lCurrentChannel == lChannel) {
00213 _atLeastOneAvailablePosChannel = true;
00214
00215
00216 const stdair::PosChannel& lFarePosChannel= *lCurrentFarePosChannel_ptr;
00217 priceQuote (iBookingRequest, ioTravelSolution, lFarePosChannel);
00218 }
00219 }
00220
00221 }
00222
00223
00224 void FareQuoter::
00225 priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
00226 stdair::TravelSolutionStruct& ioTravelSolution,
00227 const stdair::PosChannel& iFarePosChannel) {
00228
00229
00230 const stdair::ParsedKey lFirstSPParsedKey =
00231 getFirstSPParsedKey(ioTravelSolution);
00232
00233
00234 const stdair::Duration_T& lSPTime = lFirstSPParsedKey.getBoardingTime();
00235
00236
00237 const stdair::TimePeriodList_T& lFareTimePeriodList =
00238 stdair::BomManager::getList<stdair::TimePeriod> (iFarePosChannel);
00239
00240
00241 for (stdair::TimePeriodList_T::const_iterator itTimeRange =
00242 lFareTimePeriodList.begin();
00243 itTimeRange != lFareTimePeriodList.end();
00244 ++itTimeRange) {
00245 const stdair::TimePeriod* lCurrentFareTimePeriod_ptr = *itTimeRange ;
00246 assert (lCurrentFareTimePeriod_ptr != NULL);
00247
00248
00249 const bool isDepartureTimeValid =
00250 lCurrentFareTimePeriod_ptr->isDepartureTimeValid (lSPTime);
00251
00252
00253
00254 if (isDepartureTimeValid) {
00255 _atLeastOneAvailableTimeRule = true;
00256 const stdair::TimePeriod& lCurrentFareTimePeriod =
00257 *lCurrentFareTimePeriod_ptr;
00258 priceQuote (iBookingRequest, ioTravelSolution,
00259 lCurrentFareTimePeriod, iFarePosChannel);
00260 }
00261 }
00262
00263 }
00264
00265
00266 void FareQuoter::
00267 priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
00268 stdair::TravelSolutionStruct& ioTravelSolution,
00269 const stdair::TimePeriod& iFareTimePeriod,
00270 const stdair::PosChannel& iFarePosChannel) {
00271
00272
00273 const stdair::DayDuration_T& lStayDuration=
00274 iBookingRequest.getStayDuration();
00275
00276
00277 const stdair::TripType_T& lTripType =
00278 iBookingRequest.getTripType();
00279
00280
00281 const stdair::DateTime_T& lRequestDateTime =
00282 iBookingRequest.getRequestDateTime();
00283
00284
00285 const stdair::ParsedKey lFirstSPParsedKey =
00286 getFirstSPParsedKey(ioTravelSolution);
00287 const stdair::Date_T& lSPDate =
00288 lFirstSPParsedKey.getFlightDateKey().getDepartureDate();
00289
00290
00291 const stdair::Duration_T& lSPTime = lFirstSPParsedKey.getBoardingTime();
00292
00293
00294 const stdair::DateTime_T lSPDateTime (lSPDate, lSPTime);
00295
00296 bool isTripTypeValid = false;
00297 bool isStayDurationValid = false;
00298 bool isAdvancePurchaseValid = false;
00299
00300
00301 const stdair::FareFeaturesList_T& lFareFeaturesList =
00302 stdair::BomManager::getList<stdair::FareFeatures> (iFareTimePeriod);
00303
00304
00305 for (stdair::FareFeaturesList_T::const_iterator itFareFeatures =
00306 lFareFeaturesList.begin();
00307 itFareFeatures != lFareFeaturesList.end();
00308 ++itFareFeatures) {
00309 const stdair::FareFeatures* lCurrentFareFeatures_ptr =
00310 *itFareFeatures;
00311 assert (lCurrentFareFeatures_ptr != NULL);
00312
00313
00314
00315 isTripTypeValid =
00316 lCurrentFareFeatures_ptr->isTripTypeValid (lTripType);
00317
00318
00319 isStayDurationValid =
00320 lCurrentFareFeatures_ptr->isStayDurationValid (lStayDuration);
00321
00322
00323 isAdvancePurchaseValid = lCurrentFareFeatures_ptr->
00324 isAdvancePurchaseValid (lRequestDateTime,
00325 lSPDateTime);
00326
00327
00328 if (isStayDurationValid && isAdvancePurchaseValid && isTripTypeValid){
00329 _atLeastOneAvailableFeaturesRule = true;
00330
00331 stdair::FareOptionStruct lFareOption;
00332 const stdair::ChangeFees_T& lChangeFees =
00333 lCurrentFareFeatures_ptr->getChangeFees();
00334
00335 lFareOption.setChangeFees (lChangeFees);
00336 const stdair::NonRefundable_T& lNonRefundable =
00337 lCurrentFareFeatures_ptr->getRefundableOption();
00338
00339 lFareOption.setNonRefundable (lNonRefundable);
00340 const stdair::SaturdayStay_T& lSaturdayStay =
00341 lCurrentFareFeatures_ptr->getSaturdayStay();
00342
00343 lFareOption.setSaturdayStay (lSaturdayStay);
00344 const stdair::FareFeatures& lCurrentFareFeatures =
00345 *lCurrentFareFeatures_ptr;
00346 priceQuote (iBookingRequest, ioTravelSolution,
00347 lCurrentFareFeatures, iFarePosChannel,
00348 lFareOption);
00349 }
00350 }
00351
00352 }
00353
00354
00355
00356 void FareQuoter::
00357 priceQuote (const stdair::BookingRequestStruct& iBookingRequest,
00358 stdair::TravelSolutionStruct& ioTravelSolution,
00359 const stdair::FareFeatures& iFareFeatures,
00360 const stdair::PosChannel& iFarePosChannel,
00361 stdair::FareOptionStruct& iFareOption) {
00362
00363
00364 const stdair::ParsedKey lFirstSPParsedKey =
00365 getFirstSPParsedKey(ioTravelSolution);
00366
00367
00368 const stdair::SegmentPath_T& lSegmentPath =
00369 ioTravelSolution.getSegmentPath();
00370
00371
00372 const stdair::AirlineClassListList_T& lAirlineClassListList =
00373 stdair::BomManager::getList<stdair::AirlineClassList> (iFareFeatures);
00374
00375 bool lCorrectAirlineRule = false;
00376 bool lAtLeastOneDifferentAirline = false;
00377
00378
00379
00380 for (stdair::AirlineClassListList_T::const_iterator itAirlineClassList =
00381 lAirlineClassListList.begin();
00382 itAirlineClassList != lAirlineClassListList.end();
00383 ++itAirlineClassList) {
00384 const stdair::AirlineClassList* lCurrentAirlineClassList_ptr =
00385 *itAirlineClassList;
00386 assert (lCurrentAirlineClassList_ptr != NULL);
00387
00388 lCorrectAirlineRule = true;
00389 lAtLeastOneDifferentAirline = false;
00390
00391 const stdair::ClassList_StringList_T lClassList_StringList =
00392 lCurrentAirlineClassList_ptr->getAirlineCodeList();
00393
00394
00395 if (lClassList_StringList.size() == lSegmentPath.size()) {
00396
00397 stdair::SegmentPath_T::const_iterator itSegmentPath =
00398 lSegmentPath.begin();
00399
00400 stdair::ClassList_StringList_T::const_iterator itClassList_String =
00401 lClassList_StringList.begin();
00402
00403
00404 while (itSegmentPath != lSegmentPath.end()
00405 && lAtLeastOneDifferentAirline == false) {
00406
00407
00408 const std::string lSegmentDateKey = *itSegmentPath;
00409 const stdair::ParsedKey& lParsedKey =
00410 stdair::BomKeyManager::extractKeys (lSegmentDateKey);
00411 const stdair::InventoryKey& lInventoryKey =
00412 lParsedKey.getInventoryKey();
00413 const stdair::AirlineCode_T& lSegmentAirlineCode =
00414 lInventoryKey.getAirlineCode();
00415
00416
00417 const stdair::AirlineCode_T& lFareRuleAirlineCode =
00418 *itClassList_String;
00419
00420 if (lSegmentAirlineCode != lFareRuleAirlineCode) {
00421 lAtLeastOneDifferentAirline = true;
00422 }
00423 itSegmentPath++;
00424 itClassList_String++;
00425 }
00426
00427 } else {
00428
00429
00430 lCorrectAirlineRule = false;
00431 }
00432
00433
00434
00435 if (lAtLeastOneDifferentAirline == true) {
00436 lCorrectAirlineRule = false;
00437 }
00438
00439
00440
00441 if (lCorrectAirlineRule == true) {
00442 _atLeastOneAvailableAirlineClassRule = true;
00443
00444 const stdair::TripType_T& lTripType =
00445 iBookingRequest.getTripType();
00446
00447
00448 stdair::Fare_T lFare =
00449 lCurrentAirlineClassList_ptr->getFare();
00450
00451
00452 if (lTripType == "RI" || lTripType == "RO") {
00453 lFare /= 2;
00454 }
00455
00456 iFareOption.setFare (lFare);
00457
00458 const stdair::ClassList_StringList_T& lClassCodeList =
00459 lCurrentAirlineClassList_ptr->getClassCodeList();
00460 for (stdair::ClassList_StringList_T::const_iterator itClassCodeList =
00461 lClassCodeList.begin();
00462 itClassCodeList != lClassCodeList.end(); ++itClassCodeList ) {
00463 const stdair::ClassList_String_T& lClassCodeList = *itClassCodeList;
00464 iFareOption.addClassList (lClassCodeList);
00465 }
00466
00467
00468 ioTravelSolution.addFareOption (iFareOption);
00469
00470
00471 STDAIR_LOG_DEBUG ("Segment path: " << lFirstSPParsedKey.toString()
00472 << ". A corresponding fare option for the '"
00473 << lCurrentAirlineClassList_ptr->describeKey()
00474 << "' class is: " << iFareOption);
00475
00476 iFareOption.emptyClassList();
00477 }
00478 }
00479
00480 }
00481
00482
00483 stdair::ParsedKey FareQuoter::
00484 getFirstSPParsedKey (stdair::TravelSolutionStruct& ioTravelSolution) {
00485
00486
00487 const stdair::SegmentPath_T& lSegmentPath =
00488 ioTravelSolution.getSegmentPath();
00489
00490
00491 const stdair::NbOfSegments_T& lNbSegments = lSegmentPath.size();
00492
00493
00494 assert (lNbSegments >= 1);
00495
00496
00497 const std::string& lFirstSegmentDateKey = lSegmentPath.front();
00498
00499
00500 const stdair::ParsedKey& lFirstSegmentParsedKey =
00501 stdair::BomKeyManager::extractKeys (lFirstSegmentDateKey);
00502
00503 return lFirstSegmentParsedKey;
00504
00505 }
00506
00507
00508 stdair::ParsedKey FareQuoter::
00509 getLastSPParsedKey (stdair::TravelSolutionStruct& ioTravelSolution) {
00510
00511
00512 const stdair::SegmentPath_T& lSegmentPath =
00513 ioTravelSolution.getSegmentPath();
00514
00515
00516 const stdair::NbOfSegments_T& lNbSegments = lSegmentPath.size();
00517
00518
00519 assert (lNbSegments >= 1);
00520
00521
00522 const std::string& lLastSegmentDateKey = lSegmentPath.back();
00523
00524
00525 const stdair::ParsedKey& lLastSegmentParsedKey =
00526 stdair::BomKeyManager::extractKeys (lLastSegmentDateKey);
00527
00528 return lLastSegmentParsedKey;
00529
00530 }
00531
00532
00533 void FareQuoter::
00534 displayMissingFareRuleMessage (const stdair::BookingRequestStruct& iBookingRequest,
00535 stdair::TravelSolutionStruct& ioTravelSolution) {
00536
00537
00538
00539 const stdair::ParsedKey lFirstSPParsedKey =
00540 getFirstSPParsedKey(ioTravelSolution);
00541 const stdair::AirportCode_T& lOrigin = lFirstSPParsedKey._boardingPoint;
00542
00543
00544
00545 const stdair::ParsedKey& lLastSegmentKey =
00546 getLastSPParsedKey(ioTravelSolution);
00547 const stdair::AirportCode_T& lDestination = lLastSegmentKey._offPoint;
00548
00549
00550 const stdair::AirportPairKey lAirportPairKey (lOrigin, lDestination);
00551
00552
00553 const stdair::FlightDateKey& lFlightDateKey =
00554 lFirstSPParsedKey.getFlightDateKey();
00555
00556
00557 const stdair::CityCode_T& lPointOfSale = iBookingRequest.getPOS();
00558
00559 const stdair::ChannelLabel_T& lChannel =
00560 iBookingRequest.getBookingChannel();
00561
00562 const stdair::PosChannelKey lFarePosChannelKey (lPointOfSale, lChannel);
00563
00564
00565 const stdair::DateTime_T& lRequestDateTime =
00566 iBookingRequest.getRequestDateTime();
00567
00568
00569
00570 if (_atLeastOneAvailableDateRule == false) {
00571 const stdair::SegmentDateKey lSegmentDateKey =
00572 lFirstSPParsedKey.getSegmentKey();
00573 STDAIR_LOG_ERROR ("No available fare rule corresponding to the "
00574 "flight date " << lFlightDateKey.toString()
00575 << " and the Origin-Destination pair: "
00576 << lSegmentDateKey.toString());
00577 throw FlightDateNotFoundException ("No available fare rule for the "
00578 "flight date "
00579 + lFlightDateKey.toString()
00580 + " and the Origin-Destination pair: "
00581 + lSegmentDateKey.toString());
00582 }
00583
00584
00585 else if (_atLeastOneAvailablePosChannel == false) {
00586 STDAIR_LOG_ERROR ("No available fare rule corresponding to the "
00587 "point of sale " << lPointOfSale
00588 << ", to the channel " << lChannel
00589 << ", to the flight date "
00590 << lFlightDateKey.toString()
00591 << " and to the Origin-Destination pair: "
00592 << lAirportPairKey.toString());
00593 throw PosOrChannelNotFoundException ("No available fare rule for the "
00594 "point of sale " + lPointOfSale
00595 + ", the channel " + lChannel
00596 + ", the flight date "
00597 + lFlightDateKey.toString()
00598 + " and the Origin-Destination pair: "
00599 + lAirportPairKey.toString());
00600 }
00601
00602
00603 else if (_atLeastOneAvailableTimeRule == false) {
00604 STDAIR_LOG_ERROR ("No available fare rule corresponding to '"
00605 << lFirstSPParsedKey.toString() << "' (parsed key) and to '"
00606 << lFarePosChannelKey.toString() << "' (POS and channel)");
00607 throw FlightTimeNotFoundException ("No available fare rule corresponding "
00608 "to '" + lFirstSPParsedKey.toString()
00609 + "' (parsed key) and to '"
00610 + lFarePosChannelKey.toString()
00611 + "' (POS and channel)");
00612 }
00613
00614
00615 else if (_atLeastOneAvailableFeaturesRule == false) {
00616
00617 const stdair::DayDuration_T& lStayDuration=
00618 iBookingRequest.getStayDuration();
00619 std::ostringstream lStayDurationStream;
00620 lStayDurationStream << lStayDuration;
00621 const std::string lStayDurationString (lStayDurationStream.str());
00622
00623
00624 const stdair::TripType_T& lTripType =
00625 iBookingRequest.getTripType();
00626
00627 STDAIR_LOG_ERROR ("No available fare rule corresponding to a "
00628 "trip type " << lTripType
00629 << ", to a stay duration of " << lStayDurationString
00630 << ", to a request date time of " << lRequestDateTime
00631 << ", to '" << lFirstSPParsedKey.toString()
00632 << "' (parsed key) and to '"
00633 << lFarePosChannelKey << "' (POS and channel)");
00634 throw FeaturesNotFoundException ("No available fare rule corresponding to a "
00635 "trip type " + lTripType
00636 + ", to a stay duration of "
00637 + lStayDurationString
00638 + ", to a request date time of "
00639 + boost::posix_time::to_simple_string(lRequestDateTime)
00640 + ", to '" + lFirstSPParsedKey.toString()
00641 + "' (parsed key) and to '"
00642 + lFarePosChannelKey.toString()
00643 + "' (POS and channel)");
00644 }
00645 assert (_atLeastOneAvailableAirlineClassRule == false);
00646
00647
00648 STDAIR_LOG_ERROR ("No available fare rule corresponding to '"
00649 << lFirstSPParsedKey .toString() << "' (parsed key), to '"
00650 << iBookingRequest.describe()
00651 << "' (booking request) and to '"
00652 << lFarePosChannelKey.toString() << "' (POS and channel)");
00653 throw AirlineNotFoundException ("No available fare rule corresponding to '"
00654 + lFirstSPParsedKey .toString()
00655 + "' (parsed key), to '"
00656 + iBookingRequest.describe()
00657 + "' (booking request) and to '"
00658 + lFarePosChannelKey.toString()
00659 + "' (POS and channel)");
00660 }
00661 }
00662