8 #include <stdair/basic/BasConst_BomDisplay.hpp>
9 #include <stdair/basic/BasConst_Request.hpp>
10 #include <stdair/bom/BomKeyManager.hpp>
11 #include <stdair/bom/ParsedKey.hpp>
12 #include <stdair/bom/BomManager.hpp>
13 #include <stdair/bom/BomRoot.hpp>
14 #include <stdair/bom/InventoryKey.hpp>
15 #include <stdair/bom/FlightDateKey.hpp>
16 #include <stdair/bom/SegmentDateKey.hpp>
17 #include <stdair/bom/AirlineClassList.hpp>
18 #include <stdair/bom/AirportPair.hpp>
19 #include <stdair/bom/PosChannel.hpp>
20 #include <stdair/bom/DatePeriod.hpp>
21 #include <stdair/bom/TimePeriod.hpp>
22 #include <stdair/bom/FareFeatures.hpp>
23 #include <stdair/bom/BookingRequestStruct.hpp>
24 #include <stdair/bom/TravelSolutionStruct.hpp>
25 #include <stdair/service/Logger.hpp>
26 #include <stdair/bom/key_types.hpp>
33 bool FareQuoter::_atLeastOneAvailableDateRule =
false;
34 bool FareQuoter::_atLeastOneAvailablePosChannel =
false;
35 bool FareQuoter::_atLeastOneAvailableTimeRule =
false;
36 bool FareQuoter::_atLeastOneAvailableFeaturesRule =
false;
37 bool FareQuoter::_atLeastOneAvailableAirlineClassRule=
false;
40 FareQuoter::FareQuoter() {
45 FareQuoter::FareQuoter(
const FareQuoter&) {
50 FareQuoter::~FareQuoter() {
54 void FareQuoter::reset() {
55 _atLeastOneAvailableDateRule =
false;
56 _atLeastOneAvailablePosChannel =
false;
57 _atLeastOneAvailableTimeRule =
false;
58 _atLeastOneAvailableFeaturesRule =
false;
59 _atLeastOneAvailableAirlineClassRule =
false;
65 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
66 stdair::TravelSolutionList_T& ioTravelSolutionList,
67 const stdair::BomRoot& iBomRoot) {
71 for (stdair::TravelSolutionList_T::iterator itTravelSolution =
72 ioTravelSolutionList.begin();
73 itTravelSolution != ioTravelSolutionList.end(); ++itTravelSolution) {
76 stdair::TravelSolutionStruct& lTravelSolutionStruct = *itTravelSolution;
78 priceQuote (iBookingRequest, lTravelSolutionStruct, iBomRoot);
84 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
85 stdair::TravelSolutionStruct& ioTravelSolution,
86 const stdair::BomRoot& iBomRoot) {
90 const stdair::ParsedKey& lFirstSegmentKey =
91 getFirstSPParsedKey(ioTravelSolution);
92 const stdair::AirportCode_T& lOrigin = lFirstSegmentKey._boardingPoint;
96 const stdair::ParsedKey& lLastSegmentKey =
97 getLastSPParsedKey(ioTravelSolution);
98 const stdair::AirportCode_T& lDestination = lLastSegmentKey._offPoint;
101 const stdair::AirportPairKey lAirportPairKey (lOrigin, lDestination);
105 const stdair::AirportPair* lAirportPair_ptr = stdair::BomManager::
106 getObjectPtr<stdair::AirportPair> (iBomRoot, lAirportPairKey.toString());
110 if (lAirportPair_ptr == NULL) {
111 STDAIR_LOG_ERROR (
"No available fare rule for the "
112 <<
"Origin-Destination pair: "
113 << lAirportPairKey.toString());
114 throw AirportPairNotFoundException (
"No available fare rule for "
115 "the Origin-Destination pair: "
116 + lAirportPairKey.toString());
119 assert(lAirportPair_ptr != NULL);
123 const stdair::AirportPair& lAirportPair = *lAirportPair_ptr;
124 priceQuote(iBookingRequest, ioTravelSolution, lAirportPair);
126 if (_atLeastOneAvailableAirlineClassRule ==
false) {
127 displayMissingFareRuleMessage(iBookingRequest, ioTravelSolution);
133 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
134 stdair::TravelSolutionStruct& ioTravelSolution,
135 const stdair::AirportPair& iAirportPair) {
138 const stdair::ParsedKey lFirstSPParsedKey =
139 getFirstSPParsedKey(ioTravelSolution);
142 const stdair::FlightDateKey& lFlightDateKey =
143 lFirstSPParsedKey.getFlightDateKey();
144 const stdair::Date_T& lSPDate = lFlightDateKey.getDepartureDate();
147 const stdair::DatePeriodList_T& lFareDatePeriodList =
148 stdair::BomManager::getList<stdair::DatePeriod> (iAirportPair);
151 for (stdair::DatePeriodList_T::const_iterator itDateRange =
152 lFareDatePeriodList.begin();
153 itDateRange != lFareDatePeriodList.end(); ++itDateRange) {
155 const stdair::DatePeriod* lCurrentFareDatePeriod_ptr = *itDateRange ;
156 assert (lCurrentFareDatePeriod_ptr != NULL);
159 const bool isDepartureDateValid =
160 lCurrentFareDatePeriod_ptr->isDepartureDateValid (lSPDate);
164 if (isDepartureDateValid ==
true) {
165 _atLeastOneAvailableDateRule =
true;
166 const stdair::DatePeriod& lCurrentFareDatePeriod =
167 *lCurrentFareDatePeriod_ptr;
168 priceQuote (iBookingRequest, ioTravelSolution,
169 lCurrentFareDatePeriod, iAirportPair);
177 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
178 stdair::TravelSolutionStruct& ioTravelSolution,
179 const stdair::DatePeriod& iFareDatePeriod,
180 const stdair::AirportPair& iAirportPair) {
183 const stdair::CityCode_T& lPointOfSale = iBookingRequest.getPOS();
186 const stdair::ChannelLabel_T& lChannel =
187 iBookingRequest.getBookingChannel();
190 const stdair::PosChannelKey lFarePosChannelKey (lPointOfSale, lChannel);
194 const stdair::PosChannelList_T lFarePosChannelList =
195 stdair::BomManager::getList<stdair::PosChannel> (iFareDatePeriod);
198 for (stdair::PosChannelList_T::const_iterator itPosChannel =
199 lFarePosChannelList.begin();
200 itPosChannel != lFarePosChannelList.end();
202 const stdair::PosChannel* lCurrentFarePosChannel_ptr = *itPosChannel;
203 assert (lCurrentFarePosChannel_ptr != NULL);
206 const stdair::CityCode_T& lCurrentPointOfSale =
207 lCurrentFarePosChannel_ptr->getPos();
208 const stdair::ChannelLabel_T& lCurrentChannel =
209 lCurrentFarePosChannel_ptr->getChannel();
212 if (lCurrentPointOfSale == lPointOfSale || lCurrentPointOfSale == stdair::DEFAULT_POS) {
213 if (lCurrentChannel == lChannel || lCurrentChannel == stdair::DEFAULT_CHANNEL) {
214 _atLeastOneAvailablePosChannel =
true;
217 const stdair::PosChannel& lFarePosChannel= *lCurrentFarePosChannel_ptr;
218 STDAIR_LOG_DEBUG (lCurrentPointOfSale +
" " + lCurrentChannel);
219 priceQuote (iBookingRequest, ioTravelSolution, lFarePosChannel);
228 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
229 stdair::TravelSolutionStruct& ioTravelSolution,
230 const stdair::PosChannel& iFarePosChannel) {
233 const stdair::ParsedKey lFirstSPParsedKey =
234 getFirstSPParsedKey(ioTravelSolution);
237 const stdair::Duration_T& lSPTime = lFirstSPParsedKey.getBoardingTime();
240 const stdair::TimePeriodList_T& lFareTimePeriodList =
241 stdair::BomManager::getList<stdair::TimePeriod> (iFarePosChannel);
244 for (stdair::TimePeriodList_T::const_iterator itTimeRange =
245 lFareTimePeriodList.begin();
246 itTimeRange != lFareTimePeriodList.end();
248 const stdair::TimePeriod* lCurrentFareTimePeriod_ptr = *itTimeRange ;
249 assert (lCurrentFareTimePeriod_ptr != NULL);
252 const bool isDepartureTimeValid =
253 lCurrentFareTimePeriod_ptr->isDepartureTimeValid (lSPTime);
257 if (isDepartureTimeValid) {
258 _atLeastOneAvailableTimeRule =
true;
259 const stdair::TimePeriod& lCurrentFareTimePeriod =
260 *lCurrentFareTimePeriod_ptr;
261 priceQuote (iBookingRequest, ioTravelSolution,
262 lCurrentFareTimePeriod, iFarePosChannel);
270 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
271 stdair::TravelSolutionStruct& ioTravelSolution,
272 const stdair::TimePeriod& iFareTimePeriod,
273 const stdair::PosChannel& iFarePosChannel) {
276 const stdair::DayDuration_T& lStayDuration=
277 iBookingRequest.getStayDuration();
280 const stdair::TripType_T& lTripType =
281 iBookingRequest.getTripType();
284 const stdair::DateTime_T& lRequestDateTime =
285 iBookingRequest.getRequestDateTime();
288 const stdair::ParsedKey lFirstSPParsedKey =
289 getFirstSPParsedKey(ioTravelSolution);
290 const stdair::Date_T& lSPDate =
291 lFirstSPParsedKey.getFlightDateKey().getDepartureDate();
294 const stdair::Duration_T& lSPTime = lFirstSPParsedKey.getBoardingTime();
297 const stdair::DateTime_T lSPDateTime (lSPDate, lSPTime);
299 bool isTripTypeValid =
false;
300 bool isStayDurationValid =
false;
301 bool isAdvancePurchaseValid =
false;
305 const bool hasFareFeaturesList =
306 stdair::BomManager::hasList<stdair::FareFeatures> (iFareTimePeriod);
307 if (hasFareFeaturesList ==
false) {
310 assert (hasFareFeaturesList ==
true);
311 const stdair::FareFeaturesList_T& lFareFeaturesList =
312 stdair::BomManager::getList<stdair::FareFeatures> (iFareTimePeriod);
315 for (stdair::FareFeaturesList_T::const_iterator itFareFeatures =
316 lFareFeaturesList.begin();
317 itFareFeatures != lFareFeaturesList.end();
319 const stdair::FareFeatures* lCurrentFareFeatures_ptr =
321 assert (lCurrentFareFeatures_ptr != NULL);
326 lCurrentFareFeatures_ptr->isTripTypeValid (lTripType);
329 isStayDurationValid =
330 lCurrentFareFeatures_ptr->isStayDurationValid (lStayDuration);
333 isAdvancePurchaseValid = lCurrentFareFeatures_ptr->
334 isAdvancePurchaseValid (lRequestDateTime,
338 if (isStayDurationValid && isAdvancePurchaseValid && isTripTypeValid){
339 _atLeastOneAvailableFeaturesRule =
true;
341 stdair::FareOptionStruct lFareOption;
342 const stdair::ChangeFees_T& lChangeFees =
343 lCurrentFareFeatures_ptr->getChangeFees();
345 lFareOption.setChangeFees (lChangeFees);
346 const stdair::NonRefundable_T& lNonRefundable =
347 lCurrentFareFeatures_ptr->getRefundableOption();
349 lFareOption.setNonRefundable (lNonRefundable);
350 const stdair::SaturdayStay_T& lSaturdayStay =
351 lCurrentFareFeatures_ptr->getSaturdayStay();
353 lFareOption.setSaturdayStay (lSaturdayStay);
354 const stdair::FareFeatures& lCurrentFareFeatures =
355 *lCurrentFareFeatures_ptr;
356 priceQuote (iBookingRequest, ioTravelSolution,
357 lCurrentFareFeatures, iFarePosChannel,
367 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
368 stdair::TravelSolutionStruct& ioTravelSolution,
369 const stdair::FareFeatures& iFareFeatures,
370 const stdair::PosChannel& iFarePosChannel,
371 stdair::FareOptionStruct& iFareOption) {
374 const stdair::SegmentPath_T& lSegmentPath =
375 ioTravelSolution.getSegmentPath();
378 const stdair::AirlineClassListList_T& lAirlineClassListList =
379 stdair::BomManager::getList<stdair::AirlineClassList> (iFareFeatures);
381 bool lCorrectAirlineRule =
false;
382 bool lAtLeastOneDifferentAirline =
false;
386 for (stdair::AirlineClassListList_T::const_iterator itAirlineClassList =
387 lAirlineClassListList.begin();
388 itAirlineClassList != lAirlineClassListList.end();
389 ++itAirlineClassList) {
390 const stdair::AirlineClassList* lCurrentAirlineClassList_ptr =
392 assert (lCurrentAirlineClassList_ptr != NULL);
394 lCorrectAirlineRule =
true;
395 lAtLeastOneDifferentAirline =
false;
397 const stdair::ClassList_StringList_T lClassList_StringList =
398 lCurrentAirlineClassList_ptr->getAirlineCodeList();
401 if (lClassList_StringList.size() == lSegmentPath.size()) {
403 stdair::SegmentPath_T::const_iterator itSegmentPath =
404 lSegmentPath.begin();
406 stdair::ClassList_StringList_T::const_iterator itClassList_String =
407 lClassList_StringList.begin();
410 while (itSegmentPath != lSegmentPath.end()
411 && lAtLeastOneDifferentAirline ==
false) {
414 const std::string lSegmentDateKey = *itSegmentPath;
415 const stdair::ParsedKey& lParsedKey =
416 stdair::BomKeyManager::extractKeys (lSegmentDateKey);
417 const stdair::InventoryKey& lInventoryKey =
418 lParsedKey.getInventoryKey();
419 const stdair::AirlineCode_T& lSegmentAirlineCode =
420 lInventoryKey.getAirlineCode();
423 const stdair::AirlineCode_T& lFareRuleAirlineCode =
426 if (lSegmentAirlineCode != lFareRuleAirlineCode) {
427 lAtLeastOneDifferentAirline =
true;
430 itClassList_String++;
436 lCorrectAirlineRule =
false;
441 if (lAtLeastOneDifferentAirline ==
true) {
442 lCorrectAirlineRule =
false;
447 if (lCorrectAirlineRule ==
true) {
448 _atLeastOneAvailableAirlineClassRule =
true;
450 const stdair::TripType_T& lTripType =
451 iBookingRequest.getTripType();
454 stdair::Fare_T lFare =
455 lCurrentAirlineClassList_ptr->getFare();
458 if (lTripType ==
"RI" || lTripType ==
"RO") {
462 iFareOption.setFare (lFare);
464 const stdair::ClassList_StringList_T& lClassCodeList =
465 lCurrentAirlineClassList_ptr->getClassCodeList();
466 for (stdair::ClassList_StringList_T::const_iterator itClassCodeList =
467 lClassCodeList.begin();
468 itClassCodeList != lClassCodeList.end(); ++itClassCodeList ) {
469 const stdair::ClassList_String_T& lClassCodeList = *itClassCodeList;
470 iFareOption.addClassList (lClassCodeList);
474 ioTravelSolution.addFareOption (iFareOption);
477 STDAIR_LOG_DEBUG (ioTravelSolution.describeSegmentPath()
478 <<
". A corresponding fare option for the '"
479 << lCurrentAirlineClassList_ptr->describeKey()
480 <<
"' class is: " << iFareOption);
482 iFareOption.emptyClassList();
489 stdair::ParsedKey FareQuoter::
490 getFirstSPParsedKey (stdair::TravelSolutionStruct& ioTravelSolution) {
493 const stdair::SegmentPath_T& lSegmentPath =
494 ioTravelSolution.getSegmentPath();
497 const stdair::NbOfSegments_T& lNbSegments = lSegmentPath.size();
500 assert (lNbSegments >= 1);
503 const std::string& lFirstSegmentDateKey = lSegmentPath.front();
506 const stdair::ParsedKey& lFirstSegmentParsedKey =
507 stdair::BomKeyManager::extractKeys (lFirstSegmentDateKey);
509 return lFirstSegmentParsedKey;
514 stdair::ParsedKey FareQuoter::
515 getLastSPParsedKey (stdair::TravelSolutionStruct& ioTravelSolution) {
518 const stdair::SegmentPath_T& lSegmentPath =
519 ioTravelSolution.getSegmentPath();
522 const stdair::NbOfSegments_T& lNbSegments = lSegmentPath.size();
525 assert (lNbSegments >= 1);
528 const std::string& lLastSegmentDateKey = lSegmentPath.back();
531 const stdair::ParsedKey& lLastSegmentParsedKey =
532 stdair::BomKeyManager::extractKeys (lLastSegmentDateKey);
534 return lLastSegmentParsedKey;
540 displayMissingFareRuleMessage (
const stdair::BookingRequestStruct& iBookingRequest,
541 stdair::TravelSolutionStruct& ioTravelSolution) {
545 const stdair::ParsedKey lFirstSPParsedKey =
546 getFirstSPParsedKey(ioTravelSolution);
547 const stdair::AirportCode_T& lOrigin = lFirstSPParsedKey._boardingPoint;
551 const stdair::ParsedKey& lLastSegmentKey =
552 getLastSPParsedKey(ioTravelSolution);
553 const stdair::AirportCode_T& lDestination = lLastSegmentKey._offPoint;
556 const stdair::AirportPairKey lAirportPairKey (lOrigin, lDestination);
559 const stdair::FlightDateKey& lFlightDateKey =
560 lFirstSPParsedKey.getFlightDateKey();
563 const stdair::CityCode_T& lPointOfSale = iBookingRequest.getPOS();
565 const stdair::ChannelLabel_T& lChannel =
566 iBookingRequest.getBookingChannel();
568 const stdair::PosChannelKey lFarePosChannelKey (lPointOfSale, lChannel);
571 const stdair::DateTime_T& lRequestDateTime =
572 iBookingRequest.getRequestDateTime();
576 if (_atLeastOneAvailableDateRule ==
false) {
577 const stdair::SegmentDateKey lSegmentDateKey =
578 lFirstSPParsedKey.getSegmentKey();
579 STDAIR_LOG_ERROR (
"No available fare rule corresponding to the "
580 "flight date " << lFlightDateKey.toString()
581 <<
" and the Origin-Destination pair: "
582 << lSegmentDateKey.toString());
583 throw FlightDateNotFoundException (
"No available fare rule for the "
585 + lFlightDateKey.toString()
586 +
" and the Origin-Destination pair: "
587 + lSegmentDateKey.toString());
591 else if (_atLeastOneAvailablePosChannel ==
false) {
592 STDAIR_LOG_ERROR (
"No available fare rule corresponding to the "
593 "point of sale " << lPointOfSale
594 <<
", to the channel " << lChannel
595 <<
", to the flight date "
596 << lFlightDateKey.toString()
597 <<
" and to the Origin-Destination pair: "
598 << lAirportPairKey.toString());
599 throw PosOrChannelNotFoundException (
"No available fare rule for the "
600 "point of sale " + lPointOfSale
601 +
", the channel " + lChannel
602 +
", the flight date "
603 + lFlightDateKey.toString()
604 +
" and the Origin-Destination pair: "
605 + lAirportPairKey.toString());
609 else if (_atLeastOneAvailableTimeRule ==
false) {
610 STDAIR_LOG_ERROR (
"No available fare rule corresponding to '"
611 << lFirstSPParsedKey.toString() <<
"' (parsed key) and to '"
612 << lFarePosChannelKey.toString() <<
"' (POS and channel)");
613 throw FlightTimeNotFoundException (
"No available fare rule corresponding "
614 "to '" + lFirstSPParsedKey.toString()
615 +
"' (parsed key) and to '"
616 + lFarePosChannelKey.toString()
617 +
"' (POS and channel)");
621 else if (_atLeastOneAvailableFeaturesRule ==
false) {
623 const stdair::DayDuration_T& lStayDuration=
624 iBookingRequest.getStayDuration();
625 std::ostringstream lStayDurationStream;
626 lStayDurationStream << lStayDuration;
627 const std::string lStayDurationString (lStayDurationStream.str());
630 const stdair::TripType_T& lTripType =
631 iBookingRequest.getTripType();
633 STDAIR_LOG_ERROR (
"No available fare rule corresponding to a "
634 "trip type " << lTripType
635 <<
", to a stay duration of " << lStayDurationString
636 <<
", to a request date time of " << lRequestDateTime
637 <<
", to '" << lFirstSPParsedKey.toString()
638 <<
"' (parsed key) and to '"
639 << lFarePosChannelKey <<
"' (POS and channel)");
640 throw FeaturesNotFoundException (
"No available fare rule corresponding to a "
641 "trip type " + lTripType
642 +
", to a stay duration of "
643 + lStayDurationString
644 +
", to a request date time of "
645 + boost::posix_time::to_simple_string(lRequestDateTime)
646 +
", to '" + lFirstSPParsedKey.toString()
647 +
"' (parsed key) and to '"
648 + lFarePosChannelKey.toString()
649 +
"' (POS and channel)");
651 assert (_atLeastOneAvailableAirlineClassRule ==
false);
654 STDAIR_LOG_ERROR (
"No available fare rule corresponding to '"
655 << lFirstSPParsedKey .toString() <<
"' (parsed key), to '"
656 << iBookingRequest.describe()
657 <<
"' (booking request) and to '"
658 << lFarePosChannelKey.toString() <<
"' (POS and channel)");
659 throw AirlineNotFoundException (
"No available fare rule corresponding to '"
660 + lFirstSPParsedKey .toString()
661 +
"' (parsed key), to '"
662 + iBookingRequest.describe()
663 +
"' (booking request) and to '"
664 + lFarePosChannelKey.toString()
665 +
"' (POS and channel)");