$treeview $search $mathjax
00001 // ////////////////////////////////////////////////////////////////////// 00002 // Import section 00003 // ////////////////////////////////////////////////////////////////////// 00004 // STL 00005 #include <cassert> 00006 #include <sstream> 00007 // StdAir 00008 #include <stdair/basic/BasConst_BomDisplay.hpp> 00009 #include <stdair/basic/BasConst_Request.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 // SimFQT 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 // Do an independent price quote for each travel solution related to the 00070 // booking request. 00071 for (stdair::TravelSolutionList_T::iterator itTravelSolution = 00072 ioTravelSolutionList.begin(); 00073 itTravelSolution != ioTravelSolutionList.end(); ++itTravelSolution) { 00074 reset(); 00075 // Select a travel solution. 00076 stdair::TravelSolutionStruct& lTravelSolutionStruct = *itTravelSolution; 00077 // Price quote the travel solution into question. 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 // Get the origin of the first segment in order to get the origin of 00089 // the solution. 00090 const stdair::ParsedKey& lFirstSegmentKey = 00091 getFirstSPParsedKey(ioTravelSolution); 00092 const stdair::AirportCode_T& lOrigin = lFirstSegmentKey._boardingPoint; 00093 00094 // Get the destination of the last segment in order to get the 00095 // destination of the solution. 00096 const stdair::ParsedKey& lLastSegmentKey = 00097 getLastSPParsedKey(ioTravelSolution); 00098 const stdair::AirportCode_T& lDestination = lLastSegmentKey._offPoint; 00099 00100 // Construct the Airport pair stream of the segment path. 00101 const stdair::AirportPairKey lAirportPairKey (lOrigin, lDestination); 00102 00103 // Search for the fare rules having the same origin and destination airports 00104 // as the travel solution 00105 const stdair::AirportPair* lAirportPair_ptr = stdair::BomManager:: 00106 getObjectPtr<stdair::AirportPair> (iBomRoot, lAirportPairKey.toString()); 00107 00108 // If no fare rule has the same origin and destination airports, the pricing 00109 // is not possible, throw an exception. 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 // Sanity check. 00119 assert(lAirportPair_ptr != NULL); 00120 00121 // Fare rule(s) with the same origin and destination airports exist(s), now 00122 // the date range need to be checked. 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 // Get the first segment path parsed key. 00138 const stdair::ParsedKey lFirstSPParsedKey = 00139 getFirstSPParsedKey(ioTravelSolution); 00140 00141 // Get the date of the first segment date key. 00142 const stdair::FlightDateKey& lFlightDateKey = 00143 lFirstSPParsedKey.getFlightDateKey(); 00144 const stdair::Date_T& lSPDate = lFlightDateKey.getDepartureDate(); 00145 00146 // Get the list of the fare date ranges. 00147 const stdair::DatePeriodList_T& lFareDatePeriodList = 00148 stdair::BomManager::getList<stdair::DatePeriod> (iAirportPair); 00149 00150 // Browse the list of the fare rules date range. 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 // Select the fare rules having a corresponding date range. 00159 const bool isDepartureDateValid = 00160 lCurrentFareDatePeriod_ptr->isDepartureDateValid (lSPDate); 00161 00162 // If a fare rule has a corresponding date range, its channel and position 00163 // need to be checked. 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 // Get the point-of-sale of the booking request. 00183 const stdair::CityCode_T& lPointOfSale = iBookingRequest.getPOS(); 00184 00185 // Get the booking request channel. 00186 const stdair::ChannelLabel_T& lChannel = 00187 iBookingRequest.getBookingChannel(); 00188 00189 // Construct the corresponding POS-channel primary key. 00190 const stdair::PosChannelKey lFarePosChannelKey (lPointOfSale, lChannel); 00191 00192 // Search for the fare rules having the same point-of-sale and channel as 00193 // the travel solution. 00194 const stdair::PosChannelList_T lFarePosChannelList = 00195 stdair::BomManager::getList<stdair::PosChannel> (iFareDatePeriod); 00196 00197 // Browse the list of the fare rules pos channel. 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 // Get the point-of-sale and channel of the current fare rule. 00206 const stdair::CityCode_T& lCurrentPointOfSale = 00207 lCurrentFarePosChannel_ptr->getPos(); 00208 const stdair::ChannelLabel_T& lCurrentChannel = 00209 lCurrentFarePosChannel_ptr->getChannel(); 00210 00211 // Select the fare rules having a corresponding pos channel. 00212 if (lCurrentPointOfSale == lPointOfSale || lCurrentPointOfSale == stdair::DEFAULT_POS) { 00213 if (lCurrentChannel == lChannel || lCurrentChannel == stdair::DEFAULT_CHANNEL) { 00214 _atLeastOneAvailablePosChannel = true; 00215 // Fare rule(s) with the same point-of-sale and channel exist(s), now 00216 // the time range need to be checked. 00217 const stdair::PosChannel& lFarePosChannel= *lCurrentFarePosChannel_ptr; 00218 STDAIR_LOG_DEBUG (lCurrentPointOfSale + " " + lCurrentChannel); 00219 priceQuote (iBookingRequest, ioTravelSolution, lFarePosChannel); 00220 } 00221 } 00222 } 00223 00224 } 00225 00226 // ////////////////////////////////////////////////////////////////////// 00227 void FareQuoter:: 00228 priceQuote (const stdair::BookingRequestStruct& iBookingRequest, 00229 stdair::TravelSolutionStruct& ioTravelSolution, 00230 const stdair::PosChannel& iFarePosChannel) { 00231 00232 // Get the first segment path parsed key. 00233 const stdair::ParsedKey lFirstSPParsedKey = 00234 getFirstSPParsedKey(ioTravelSolution); 00235 00236 // Get the segment boarding time of the segment path. 00237 const stdair::Duration_T& lSPTime = lFirstSPParsedKey.getBoardingTime(); 00238 00239 // Get the list of the fare rules time period. 00240 const stdair::TimePeriodList_T& lFareTimePeriodList = 00241 stdair::BomManager::getList<stdair::TimePeriod> (iFarePosChannel); 00242 00243 // Browse the list of the fare rules time range. 00244 for (stdair::TimePeriodList_T::const_iterator itTimeRange = 00245 lFareTimePeriodList.begin(); 00246 itTimeRange != lFareTimePeriodList.end(); 00247 ++itTimeRange) { 00248 const stdair::TimePeriod* lCurrentFareTimePeriod_ptr = *itTimeRange ; 00249 assert (lCurrentFareTimePeriod_ptr != NULL); 00250 00251 // Select the fare rules having a corresponding time range. 00252 const bool isDepartureTimeValid = 00253 lCurrentFareTimePeriod_ptr->isDepartureTimeValid (lSPTime); 00254 00255 // If a fare rule has a corresponding time range, its advanced purchase, 00256 // trip type and minimum stay duration need to be checked. 00257 if (isDepartureTimeValid) { 00258 _atLeastOneAvailableTimeRule = true; 00259 const stdair::TimePeriod& lCurrentFareTimePeriod = 00260 *lCurrentFareTimePeriod_ptr; 00261 priceQuote (iBookingRequest, ioTravelSolution, 00262 lCurrentFareTimePeriod, iFarePosChannel); 00263 } 00264 } 00265 00266 } 00267 00268 // ////////////////////////////////////////////////////////////////////// 00269 void FareQuoter:: 00270 priceQuote (const stdair::BookingRequestStruct& iBookingRequest, 00271 stdair::TravelSolutionStruct& ioTravelSolution, 00272 const stdair::TimePeriod& iFareTimePeriod, 00273 const stdair::PosChannel& iFarePosChannel) { 00274 00275 // Get the stay duration of the booking request. 00276 const stdair::DayDuration_T& lStayDuration= 00277 iBookingRequest.getStayDuration(); 00278 00279 // Get the booking request trip type. 00280 const stdair::TripType_T& lTripType = 00281 iBookingRequest.getTripType(); 00282 00283 // Get the booking request date time. 00284 const stdair::DateTime_T& lRequestDateTime = 00285 iBookingRequest.getRequestDateTime(); 00286 00287 // Get the referenced departure date of the segment path. 00288 const stdair::ParsedKey lFirstSPParsedKey = 00289 getFirstSPParsedKey(ioTravelSolution); 00290 const stdair::Date_T& lSPDate = 00291 lFirstSPParsedKey.getFlightDateKey().getDepartureDate(); 00292 00293 // Get the segment boarding time of the segment path. 00294 const stdair::Duration_T& lSPTime = lFirstSPParsedKey.getBoardingTime(); 00295 00296 // Construct the date-time type correponding to the flight date 00297 const stdair::DateTime_T lSPDateTime (lSPDate, lSPTime); 00298 00299 bool isTripTypeValid = false; 00300 bool isStayDurationValid = false; 00301 bool isAdvancePurchaseValid = false; 00302 00303 // Get the list of the fare features (if such list exists: the POS 00304 // and channel couple can be only present in a yield rule). 00305 const bool hasFareFeaturesList = 00306 stdair::BomManager::hasList<stdair::FareFeatures> (iFareTimePeriod); 00307 if (hasFareFeaturesList == false) { 00308 return; 00309 } 00310 assert (hasFareFeaturesList == true); 00311 const stdair::FareFeaturesList_T& lFareFeaturesList = 00312 stdair::BomManager::getList<stdair::FareFeatures> (iFareTimePeriod); 00313 00314 // Browse the list of the fare rules features. 00315 for (stdair::FareFeaturesList_T::const_iterator itFareFeatures = 00316 lFareFeaturesList.begin(); 00317 itFareFeatures != lFareFeaturesList.end(); 00318 ++itFareFeatures) { 00319 const stdair::FareFeatures* lCurrentFareFeatures_ptr = 00320 *itFareFeatures; 00321 assert (lCurrentFareFeatures_ptr != NULL); 00322 00323 // Does the current fare features correspond to a correct trip 00324 // type? 00325 isTripTypeValid = 00326 lCurrentFareFeatures_ptr->isTripTypeValid (lTripType); 00327 // Does the current fare features correspond to a correct stay 00328 // duration? 00329 isStayDurationValid = 00330 lCurrentFareFeatures_ptr->isStayDurationValid (lStayDuration); 00331 // Does the current fare features correspond to a correct advanced 00332 // purchase? 00333 isAdvancePurchaseValid = lCurrentFareFeatures_ptr-> 00334 isAdvancePurchaseValid (lRequestDateTime, 00335 lSPDateTime); 00336 00337 // Search for the fare rules having corresponding features. 00338 if (isStayDurationValid && isAdvancePurchaseValid && isTripTypeValid){ 00339 _atLeastOneAvailableFeaturesRule = true; 00340 // Create a fare structure for the travel solution. 00341 stdair::FareOptionStruct lFareOption; 00342 const stdair::ChangeFees_T& lChangeFees = 00343 lCurrentFareFeatures_ptr->getChangeFees(); 00344 // Set the fare change fees. 00345 lFareOption.setChangeFees (lChangeFees); 00346 const stdair::NonRefundable_T& lNonRefundable = 00347 lCurrentFareFeatures_ptr->getRefundableOption(); 00348 // Set the fare refundable option. 00349 lFareOption.setNonRefundable (lNonRefundable); 00350 const stdair::SaturdayStay_T& lSaturdayStay = 00351 lCurrentFareFeatures_ptr->getSaturdayStay(); 00352 // Set the fare saturday night stay option. 00353 lFareOption.setSaturdayStay (lSaturdayStay); 00354 const stdair::FareFeatures& lCurrentFareFeatures = 00355 *lCurrentFareFeatures_ptr; 00356 priceQuote (iBookingRequest, ioTravelSolution, 00357 lCurrentFareFeatures, iFarePosChannel, 00358 lFareOption); 00359 } 00360 } 00361 00362 } 00363 00364 00365 // ////////////////////////////////////////////////////////////////////// 00366 void FareQuoter:: 00367 priceQuote (const stdair::BookingRequestStruct& iBookingRequest, 00368 stdair::TravelSolutionStruct& ioTravelSolution, 00369 const stdair::FareFeatures& iFareFeatures, 00370 const stdair::PosChannel& iFarePosChannel, 00371 stdair::FareOptionStruct& iFareOption) { 00372 00373 // Get the segment-path of the travel solution. 00374 const stdair::SegmentPath_T& lSegmentPath = 00375 ioTravelSolution.getSegmentPath(); 00376 00377 // Get the list of the fare rules. 00378 const stdair::AirlineClassListList_T& lAirlineClassListList = 00379 stdair::BomManager::getList<stdair::AirlineClassList> (iFareFeatures); 00380 00381 bool lCorrectAirlineRule = false; 00382 bool lAtLeastOneDifferentAirline = false; 00383 00384 // Browse the list of airline code list and search for the fare rules 00385 // having a corresponding airline list. 00386 for (stdair::AirlineClassListList_T::const_iterator itAirlineClassList = 00387 lAirlineClassListList.begin(); 00388 itAirlineClassList != lAirlineClassListList.end(); 00389 ++itAirlineClassList) { 00390 const stdair::AirlineClassList* lCurrentAirlineClassList_ptr = 00391 *itAirlineClassList; 00392 assert (lCurrentAirlineClassList_ptr != NULL); 00393 00394 lCorrectAirlineRule = true; 00395 lAtLeastOneDifferentAirline = false; 00396 00397 const stdair::ClassList_StringList_T lClassList_StringList = 00398 lCurrentAirlineClassList_ptr->getAirlineCodeList(); 00399 00400 // Compare the segment path airline list with the fare rule airline list. 00401 if (lClassList_StringList.size() == lSegmentPath.size()) { 00402 // If the two sizes are equal, we need to compare the airline codes. 00403 stdair::SegmentPath_T::const_iterator itSegmentPath = 00404 lSegmentPath.begin(); 00405 00406 stdair::ClassList_StringList_T::const_iterator itClassList_String = 00407 lClassList_StringList.begin(); 00408 // Browse the segment path airline code list (while the segment path 00409 // airline list is equal to the fare rule airline list). 00410 while (itSegmentPath != lSegmentPath.end() 00411 && lAtLeastOneDifferentAirline == false) { 00412 00413 // Get the segment airline code. 00414 const std::string lSegmentDateKey = *itSegmentPath; 00415 const stdair::ParsedKey& lParsedKey = 00416 stdair::BomKeyManager::extractKeys (lSegmentDateKey); 00417 const stdair::InventoryKey& lInventoryKey = 00418 lParsedKey.getInventoryKey(); 00419 const stdair::AirlineCode_T& lSegmentAirlineCode = 00420 lInventoryKey.getAirlineCode(); 00421 00422 // Get the fare rule airline code. 00423 const stdair::AirlineCode_T& lFareRuleAirlineCode = 00424 *itClassList_String; 00425 00426 if (lSegmentAirlineCode != lFareRuleAirlineCode) { 00427 lAtLeastOneDifferentAirline = true; 00428 } 00429 itSegmentPath++; 00430 itClassList_String++; 00431 } 00432 00433 } else { 00434 // If the two sizes are different, the fare rule does not match the 00435 // travel solution into question. 00436 lCorrectAirlineRule = false; 00437 } 00438 00439 // If one segment airline code and one fare rule airline code are 00440 // different then the fare rule does not match the travel solution. 00441 if (lAtLeastOneDifferentAirline == true) { 00442 lCorrectAirlineRule = false; 00443 } 00444 00445 // If the current fare rule is a match, add the fare option structure 00446 // to the travel solution into question. 00447 if (lCorrectAirlineRule == true) { 00448 _atLeastOneAvailableAirlineClassRule = true; 00449 // Get the booking request trip type. 00450 const stdair::TripType_T& lTripType = 00451 iBookingRequest.getTripType(); 00452 00453 // Get the travel fare. 00454 stdair::Fare_T lFare = 00455 lCurrentAirlineClassList_ptr->getFare(); 00456 // If the trip into question is the inbound or outbound part of a round trip, 00457 // the applicable fare is a half RT fare. 00458 if (lTripType == "RI" || lTripType == "RO") { 00459 lFare /= 2; 00460 } 00461 // Set the travel fare option. 00462 iFareOption.setFare (lFare); 00463 // Copy the class path list into the fare option. 00464 const stdair::ClassList_StringList_T& lClassCodeList = 00465 lCurrentAirlineClassList_ptr->getClassCodeList(); 00466 for (stdair::ClassList_StringList_T::const_iterator itClassCodeList = 00467 lClassCodeList.begin(); 00468 itClassCodeList != lClassCodeList.end(); ++itClassCodeList ) { 00469 const stdair::ClassList_String_T& lClassCodeList = *itClassCodeList; 00470 iFareOption.addClassList (lClassCodeList); 00471 } 00472 00473 // Add the fare option to the travel solution into question. 00474 ioTravelSolution.addFareOption (iFareOption); 00475 00476 // DEBUG 00477 STDAIR_LOG_DEBUG (ioTravelSolution.describeSegmentPath() 00478 << ". A corresponding fare option for the '" 00479 << lCurrentAirlineClassList_ptr->describeKey() 00480 << "' class is: " << iFareOption); 00481 00482 iFareOption.emptyClassList(); 00483 } 00484 } 00485 00486 } 00487 00488 // ////////////////////////////////////////////////////////////////////// 00489 stdair::ParsedKey FareQuoter:: 00490 getFirstSPParsedKey (stdair::TravelSolutionStruct& ioTravelSolution) { 00491 00492 // Get the segment-path of the travel solution. 00493 const stdair::SegmentPath_T& lSegmentPath = 00494 ioTravelSolution.getSegmentPath(); 00495 00496 // Get the number of segments of the travel solution. 00497 const stdair::NbOfSegments_T& lNbSegments = lSegmentPath.size(); 00498 00499 // Sanity check: there is at least one segment in the travel solution. 00500 assert (lNbSegments >= 1); 00501 00502 // Get the first segment of the travel solution. 00503 const std::string& lFirstSegmentDateKey = lSegmentPath.front(); 00504 00505 // Get the parsed key of the first segment of the travel solution. 00506 const stdair::ParsedKey& lFirstSegmentParsedKey = 00507 stdair::BomKeyManager::extractKeys (lFirstSegmentDateKey); 00508 00509 return lFirstSegmentParsedKey; 00510 00511 } 00512 00513 // ////////////////////////////////////////////////////////////////////// 00514 stdair::ParsedKey FareQuoter:: 00515 getLastSPParsedKey (stdair::TravelSolutionStruct& ioTravelSolution) { 00516 00517 // Get the segment-path of the travel solution. 00518 const stdair::SegmentPath_T& lSegmentPath = 00519 ioTravelSolution.getSegmentPath(); 00520 00521 // Get the number of segments of the travel solution. 00522 const stdair::NbOfSegments_T& lNbSegments = lSegmentPath.size(); 00523 00524 // Sanity check: there is at least one segment in the travel solution. 00525 assert (lNbSegments >= 1); 00526 00527 // Get the last segment of the travel solution. 00528 const std::string& lLastSegmentDateKey = lSegmentPath.back(); 00529 00530 // Get the parsed key of the last segment of the travel solution. 00531 const stdair::ParsedKey& lLastSegmentParsedKey = 00532 stdair::BomKeyManager::extractKeys (lLastSegmentDateKey); 00533 00534 return lLastSegmentParsedKey; 00535 00536 } 00537 00538 // ////////////////////////////////////////////////////////////////////// 00539 void FareQuoter:: 00540 displayMissingFareRuleMessage (const stdair::BookingRequestStruct& iBookingRequest, 00541 stdair::TravelSolutionStruct& ioTravelSolution) { 00542 00543 // Get the origin of the first segment in order to get the origin of 00544 // the solution. 00545 const stdair::ParsedKey lFirstSPParsedKey = 00546 getFirstSPParsedKey(ioTravelSolution); 00547 const stdair::AirportCode_T& lOrigin = lFirstSPParsedKey._boardingPoint; 00548 00549 // Get the destination of the last segment in order to get the 00550 // destination of the solution. 00551 const stdair::ParsedKey& lLastSegmentKey = 00552 getLastSPParsedKey(ioTravelSolution); 00553 const stdair::AirportCode_T& lDestination = lLastSegmentKey._offPoint; 00554 00555 // Construct the Airport pair stream of the segment path. 00556 const stdair::AirportPairKey lAirportPairKey (lOrigin, lDestination); 00557 00558 // Get the date of the first segment date key. 00559 const stdair::FlightDateKey& lFlightDateKey = 00560 lFirstSPParsedKey.getFlightDateKey(); 00561 00562 // Get the point-of-sale of the booking request. 00563 const stdair::CityCode_T& lPointOfSale = iBookingRequest.getPOS(); 00564 // Get the booking request channel. 00565 const stdair::ChannelLabel_T& lChannel = 00566 iBookingRequest.getBookingChannel(); 00567 // Construct the corresponding POS-channel primary key. 00568 const stdair::PosChannelKey lFarePosChannelKey (lPointOfSale, lChannel); 00569 00570 // Get the booking request date time. 00571 const stdair::DateTime_T& lRequestDateTime = 00572 iBookingRequest.getRequestDateTime(); 00573 00574 // If no fare rule has a corresponding date range, the pricing is not 00575 // possible, throw an exception. 00576 if (_atLeastOneAvailableDateRule == false) { 00577 const stdair::SegmentDateKey lSegmentDateKey = 00578 lFirstSPParsedKey.getSegmentKey(); 00579 STDAIR_LOG_ERROR ("No available fare rule corresponding to the " 00580 "flight date " << lFlightDateKey.toString() 00581 << " and the Origin-Destination pair: " 00582 << lSegmentDateKey.toString()); 00583 throw FlightDateNotFoundException ("No available fare rule for the " 00584 "flight date " 00585 + lFlightDateKey.toString() 00586 + " and the Origin-Destination pair: " 00587 + lSegmentDateKey.toString()); 00588 } 00589 // If no fare rule has a corresponding pos channel, the pricing is not possible, 00590 // throw an exception. 00591 else if (_atLeastOneAvailablePosChannel == false) { 00592 STDAIR_LOG_ERROR ("No available fare rule corresponding to the " 00593 "point of sale " << lPointOfSale 00594 << ", to the channel " << lChannel 00595 << ", to the flight date " 00596 << lFlightDateKey.toString() 00597 << " and to the Origin-Destination pair: " 00598 << lAirportPairKey.toString()); 00599 throw PosOrChannelNotFoundException ("No available fare rule for the " 00600 "point of sale " + lPointOfSale 00601 + ", the channel " + lChannel 00602 + ", the flight date " 00603 + lFlightDateKey.toString() 00604 + " and the Origin-Destination pair: " 00605 + lAirportPairKey.toString()); 00606 } 00607 // If no fare rule has a corresponding time range, the pricing is not possible, 00608 // throw an exception. 00609 else if (_atLeastOneAvailableTimeRule == false) { 00610 STDAIR_LOG_ERROR ("No available fare rule corresponding to '" 00611 << lFirstSPParsedKey.toString() << "' (parsed key) and to '" 00612 << lFarePosChannelKey.toString() << "' (POS and channel)"); 00613 throw FlightTimeNotFoundException ("No available fare rule corresponding " 00614 "to '" + lFirstSPParsedKey.toString() 00615 + "' (parsed key) and to '" 00616 + lFarePosChannelKey.toString() 00617 + "' (POS and channel)"); 00618 } 00619 // If no fare rule matches the advance purchase, trip type and stay 00620 // duration criterion, the pricing is not possible, throw an exception. 00621 else if (_atLeastOneAvailableFeaturesRule == false) { 00622 // Get the stay duration of the booking request. 00623 const stdair::DayDuration_T& lStayDuration= 00624 iBookingRequest.getStayDuration(); 00625 std::ostringstream lStayDurationStream; 00626 lStayDurationStream << lStayDuration; 00627 const std::string lStayDurationString (lStayDurationStream.str()); 00628 00629 // Get the booking request trip type. 00630 const stdair::TripType_T& lTripType = 00631 iBookingRequest.getTripType(); 00632 00633 STDAIR_LOG_ERROR ("No available fare rule corresponding to a " 00634 "trip type " << lTripType 00635 << ", to a stay duration of " << lStayDurationString 00636 << ", to a request date time of " << lRequestDateTime 00637 << ", to '" << lFirstSPParsedKey.toString() 00638 << "' (parsed key) and to '" 00639 << lFarePosChannelKey << "' (POS and channel)"); 00640 throw FeaturesNotFoundException ("No available fare rule corresponding to a " 00641 "trip type " + lTripType 00642 + ", to a stay duration of " 00643 + lStayDurationString 00644 + ", to a request date time of " 00645 + boost::posix_time::to_simple_string(lRequestDateTime) 00646 + ", to '" + lFirstSPParsedKey.toString() 00647 + "' (parsed key) and to '" 00648 + lFarePosChannelKey.toString() 00649 + "' (POS and channel)"); 00650 } 00651 assert (_atLeastOneAvailableAirlineClassRule == false); 00652 // If no fare rule matches the airline class path, the pricing is not 00653 // possible, throw an exception. 00654 STDAIR_LOG_ERROR ("No available fare rule corresponding to '" 00655 << lFirstSPParsedKey .toString() << "' (parsed key), to '" 00656 << iBookingRequest.describe() 00657 << "' (booking request) and to '" 00658 << lFarePosChannelKey.toString() << "' (POS and channel)"); 00659 throw AirlineNotFoundException ("No available fare rule corresponding to '" 00660 + lFirstSPParsedKey .toString() 00661 + "' (parsed key), to '" 00662 + iBookingRequest.describe() 00663 + "' (booking request) and to '" 00664 + lFarePosChannelKey.toString() 00665 + "' (POS and channel)"); 00666 } 00667 } 00668