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