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>
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;
39 FareQuoter::FareQuoter() {
44 FareQuoter::FareQuoter(
const FareQuoter&) {
49 FareQuoter::~FareQuoter() {
53 void FareQuoter::reset() {
54 _atLeastOneAvailableDateRule =
false;
55 _atLeastOneAvailablePosChannel =
false;
56 _atLeastOneAvailableTimeRule =
false;
57 _atLeastOneAvailableFeaturesRule =
false;
58 _atLeastOneAvailableAirlineClassRule =
false;
64 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
65 stdair::TravelSolutionList_T& ioTravelSolutionList,
66 const stdair::BomRoot& iBomRoot) {
70 for (stdair::TravelSolutionList_T::iterator itTravelSolution =
71 ioTravelSolutionList.begin();
72 itTravelSolution != ioTravelSolutionList.end(); ++itTravelSolution) {
75 stdair::TravelSolutionStruct& lTravelSolutionStruct = *itTravelSolution;
77 priceQuote (iBookingRequest, lTravelSolutionStruct, iBomRoot);
83 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
84 stdair::TravelSolutionStruct& ioTravelSolution,
85 const stdair::BomRoot& iBomRoot) {
89 const stdair::ParsedKey& lFirstSegmentKey =
90 getFirstSPParsedKey(ioTravelSolution);
91 const stdair::AirportCode_T& lOrigin = lFirstSegmentKey._boardingPoint;
95 const stdair::ParsedKey& lLastSegmentKey =
96 getLastSPParsedKey(ioTravelSolution);
97 const stdair::AirportCode_T& lDestination = lLastSegmentKey._offPoint;
100 const stdair::AirportPairKey lAirportPairKey (lOrigin, lDestination);
104 const stdair::AirportPair* lAirportPair_ptr = stdair::BomManager::
105 getObjectPtr<stdair::AirportPair> (iBomRoot, lAirportPairKey.toString());
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());
118 assert(lAirportPair_ptr != NULL);
122 const stdair::AirportPair& lAirportPair = *lAirportPair_ptr;
123 priceQuote(iBookingRequest, ioTravelSolution, lAirportPair);
125 if (_atLeastOneAvailableAirlineClassRule ==
false) {
126 displayMissingFareRuleMessage(iBookingRequest, ioTravelSolution);
132 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
133 stdair::TravelSolutionStruct& ioTravelSolution,
134 const stdair::AirportPair& iAirportPair) {
137 const stdair::ParsedKey lFirstSPParsedKey =
138 getFirstSPParsedKey(ioTravelSolution);
141 const stdair::FlightDateKey& lFlightDateKey =
142 lFirstSPParsedKey.getFlightDateKey();
143 const stdair::Date_T& lSPDate = lFlightDateKey.getDepartureDate();
146 const stdair::DatePeriodList_T& lFareDatePeriodList =
147 stdair::BomManager::getList<stdair::DatePeriod> (iAirportPair);
150 for (stdair::DatePeriodList_T::const_iterator itDateRange =
151 lFareDatePeriodList.begin();
152 itDateRange != lFareDatePeriodList.end(); ++itDateRange) {
154 const stdair::DatePeriod* lCurrentFareDatePeriod_ptr = *itDateRange ;
155 assert (lCurrentFareDatePeriod_ptr != NULL);
158 const bool isDepartureDateValid =
159 lCurrentFareDatePeriod_ptr->isDepartureDateValid (lSPDate);
163 if (isDepartureDateValid ==
true) {
164 _atLeastOneAvailableDateRule =
true;
165 const stdair::DatePeriod& lCurrentFareDatePeriod =
166 *lCurrentFareDatePeriod_ptr;
167 priceQuote (iBookingRequest, ioTravelSolution,
168 lCurrentFareDatePeriod, iAirportPair);
176 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
177 stdair::TravelSolutionStruct& ioTravelSolution,
178 const stdair::DatePeriod& iFareDatePeriod,
179 const stdair::AirportPair& iAirportPair) {
182 const stdair::CityCode_T& lPointOfSale = iBookingRequest.getPOS();
185 const stdair::ChannelLabel_T& lChannel =
186 iBookingRequest.getBookingChannel();
189 const stdair::PosChannelKey lFarePosChannelKey (lPointOfSale, lChannel);
193 const stdair::PosChannelList_T lFarePosChannelList =
194 stdair::BomManager::getList<stdair::PosChannel> (iFareDatePeriod);
197 for (stdair::PosChannelList_T::const_iterator itPosChannel =
198 lFarePosChannelList.begin();
199 itPosChannel != lFarePosChannelList.end();
201 const stdair::PosChannel* lCurrentFarePosChannel_ptr = *itPosChannel;
202 assert (lCurrentFarePosChannel_ptr != NULL);
205 const stdair::CityCode_T& lCurrentPointOfSale =
206 lCurrentFarePosChannel_ptr->getPos();
207 const stdair::ChannelLabel_T& lCurrentChannel =
208 lCurrentFarePosChannel_ptr->getChannel();
211 if (lCurrentPointOfSale == lPointOfSale &&
212 lCurrentChannel == lChannel) {
213 _atLeastOneAvailablePosChannel =
true;
216 const stdair::PosChannel& lFarePosChannel= *lCurrentFarePosChannel_ptr;
217 priceQuote (iBookingRequest, ioTravelSolution, lFarePosChannel);
225 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
226 stdair::TravelSolutionStruct& ioTravelSolution,
227 const stdair::PosChannel& iFarePosChannel) {
230 const stdair::ParsedKey lFirstSPParsedKey =
231 getFirstSPParsedKey(ioTravelSolution);
234 const stdair::Duration_T& lSPTime = lFirstSPParsedKey.getBoardingTime();
237 const stdair::TimePeriodList_T& lFareTimePeriodList =
238 stdair::BomManager::getList<stdair::TimePeriod> (iFarePosChannel);
241 for (stdair::TimePeriodList_T::const_iterator itTimeRange =
242 lFareTimePeriodList.begin();
243 itTimeRange != lFareTimePeriodList.end();
245 const stdair::TimePeriod* lCurrentFareTimePeriod_ptr = *itTimeRange ;
246 assert (lCurrentFareTimePeriod_ptr != NULL);
249 const bool isDepartureTimeValid =
250 lCurrentFareTimePeriod_ptr->isDepartureTimeValid (lSPTime);
254 if (isDepartureTimeValid) {
255 _atLeastOneAvailableTimeRule =
true;
256 const stdair::TimePeriod& lCurrentFareTimePeriod =
257 *lCurrentFareTimePeriod_ptr;
258 priceQuote (iBookingRequest, ioTravelSolution,
259 lCurrentFareTimePeriod, iFarePosChannel);
267 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
268 stdair::TravelSolutionStruct& ioTravelSolution,
269 const stdair::TimePeriod& iFareTimePeriod,
270 const stdair::PosChannel& iFarePosChannel) {
273 const stdair::DayDuration_T& lStayDuration=
274 iBookingRequest.getStayDuration();
277 const stdair::TripType_T& lTripType =
278 iBookingRequest.getTripType();
281 const stdair::DateTime_T& lRequestDateTime =
282 iBookingRequest.getRequestDateTime();
285 const stdair::ParsedKey lFirstSPParsedKey =
286 getFirstSPParsedKey(ioTravelSolution);
287 const stdair::Date_T& lSPDate =
288 lFirstSPParsedKey.getFlightDateKey().getDepartureDate();
291 const stdair::Duration_T& lSPTime = lFirstSPParsedKey.getBoardingTime();
294 const stdair::DateTime_T lSPDateTime (lSPDate, lSPTime);
296 bool isTripTypeValid =
false;
297 bool isStayDurationValid =
false;
298 bool isAdvancePurchaseValid =
false;
301 const stdair::FareFeaturesList_T& lFareFeaturesList =
302 stdair::BomManager::getList<stdair::FareFeatures> (iFareTimePeriod);
305 for (stdair::FareFeaturesList_T::const_iterator itFareFeatures =
306 lFareFeaturesList.begin();
307 itFareFeatures != lFareFeaturesList.end();
309 const stdair::FareFeatures* lCurrentFareFeatures_ptr =
311 assert (lCurrentFareFeatures_ptr != NULL);
316 lCurrentFareFeatures_ptr->isTripTypeValid (lTripType);
319 isStayDurationValid =
320 lCurrentFareFeatures_ptr->isStayDurationValid (lStayDuration);
323 isAdvancePurchaseValid = lCurrentFareFeatures_ptr->
324 isAdvancePurchaseValid (lRequestDateTime,
328 if (isStayDurationValid && isAdvancePurchaseValid && isTripTypeValid){
329 _atLeastOneAvailableFeaturesRule =
true;
331 stdair::FareOptionStruct lFareOption;
332 const stdair::ChangeFees_T& lChangeFees =
333 lCurrentFareFeatures_ptr->getChangeFees();
335 lFareOption.setChangeFees (lChangeFees);
336 const stdair::NonRefundable_T& lNonRefundable =
337 lCurrentFareFeatures_ptr->getRefundableOption();
339 lFareOption.setNonRefundable (lNonRefundable);
340 const stdair::SaturdayStay_T& lSaturdayStay =
341 lCurrentFareFeatures_ptr->getSaturdayStay();
343 lFareOption.setSaturdayStay (lSaturdayStay);
344 const stdair::FareFeatures& lCurrentFareFeatures =
345 *lCurrentFareFeatures_ptr;
346 priceQuote (iBookingRequest, ioTravelSolution,
347 lCurrentFareFeatures, iFarePosChannel,
357 priceQuote (
const stdair::BookingRequestStruct& iBookingRequest,
358 stdair::TravelSolutionStruct& ioTravelSolution,
359 const stdair::FareFeatures& iFareFeatures,
360 const stdair::PosChannel& iFarePosChannel,
361 stdair::FareOptionStruct& iFareOption) {
364 const stdair::ParsedKey lFirstSPParsedKey =
365 getFirstSPParsedKey(ioTravelSolution);
368 const stdair::SegmentPath_T& lSegmentPath =
369 ioTravelSolution.getSegmentPath();
372 const stdair::AirlineClassListList_T& lAirlineClassListList =
373 stdair::BomManager::getList<stdair::AirlineClassList> (iFareFeatures);
375 bool lCorrectAirlineRule =
false;
376 bool lAtLeastOneDifferentAirline =
false;
380 for (stdair::AirlineClassListList_T::const_iterator itAirlineClassList =
381 lAirlineClassListList.begin();
382 itAirlineClassList != lAirlineClassListList.end();
383 ++itAirlineClassList) {
384 const stdair::AirlineClassList* lCurrentAirlineClassList_ptr =
386 assert (lCurrentAirlineClassList_ptr != NULL);
388 lCorrectAirlineRule =
true;
389 lAtLeastOneDifferentAirline =
false;
391 const stdair::ClassList_StringList_T lClassList_StringList =
392 lCurrentAirlineClassList_ptr->getAirlineCodeList();
395 if (lClassList_StringList.size() == lSegmentPath.size()) {
397 stdair::SegmentPath_T::const_iterator itSegmentPath =
398 lSegmentPath.begin();
400 stdair::ClassList_StringList_T::const_iterator itClassList_String =
401 lClassList_StringList.begin();
404 while (itSegmentPath != lSegmentPath.end()
405 && lAtLeastOneDifferentAirline ==
false) {
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();
417 const stdair::AirlineCode_T& lFareRuleAirlineCode =
420 if (lSegmentAirlineCode != lFareRuleAirlineCode) {
421 lAtLeastOneDifferentAirline =
true;
424 itClassList_String++;
430 lCorrectAirlineRule =
false;
435 if (lAtLeastOneDifferentAirline ==
true) {
436 lCorrectAirlineRule =
false;
441 if (lCorrectAirlineRule ==
true) {
442 _atLeastOneAvailableAirlineClassRule =
true;
444 const stdair::TripType_T& lTripType =
445 iBookingRequest.getTripType();
448 stdair::Fare_T lFare =
449 lCurrentAirlineClassList_ptr->getFare();
452 if (lTripType ==
"RI" || lTripType ==
"RO") {
456 iFareOption.setFare (lFare);
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);
468 ioTravelSolution.addFareOption (iFareOption);
471 STDAIR_LOG_DEBUG (
"Segment path: " << lFirstSPParsedKey.toString()
472 <<
". A corresponding fare option for the '"
473 << lCurrentAirlineClassList_ptr->describeKey()
474 <<
"' class is: " << iFareOption);
476 iFareOption.emptyClassList();
483 stdair::ParsedKey FareQuoter::
484 getFirstSPParsedKey (stdair::TravelSolutionStruct& ioTravelSolution) {
487 const stdair::SegmentPath_T& lSegmentPath =
488 ioTravelSolution.getSegmentPath();
491 const stdair::NbOfSegments_T& lNbSegments = lSegmentPath.size();
494 assert (lNbSegments >= 1);
497 const std::string& lFirstSegmentDateKey = lSegmentPath.front();
500 const stdair::ParsedKey& lFirstSegmentParsedKey =
501 stdair::BomKeyManager::extractKeys (lFirstSegmentDateKey);
503 return lFirstSegmentParsedKey;
508 stdair::ParsedKey FareQuoter::
509 getLastSPParsedKey (stdair::TravelSolutionStruct& ioTravelSolution) {
512 const stdair::SegmentPath_T& lSegmentPath =
513 ioTravelSolution.getSegmentPath();
516 const stdair::NbOfSegments_T& lNbSegments = lSegmentPath.size();
519 assert (lNbSegments >= 1);
522 const std::string& lLastSegmentDateKey = lSegmentPath.back();
525 const stdair::ParsedKey& lLastSegmentParsedKey =
526 stdair::BomKeyManager::extractKeys (lLastSegmentDateKey);
528 return lLastSegmentParsedKey;
534 displayMissingFareRuleMessage (
const stdair::BookingRequestStruct& iBookingRequest,
535 stdair::TravelSolutionStruct& ioTravelSolution) {
539 const stdair::ParsedKey lFirstSPParsedKey =
540 getFirstSPParsedKey(ioTravelSolution);
541 const stdair::AirportCode_T& lOrigin = lFirstSPParsedKey._boardingPoint;
545 const stdair::ParsedKey& lLastSegmentKey =
546 getLastSPParsedKey(ioTravelSolution);
547 const stdair::AirportCode_T& lDestination = lLastSegmentKey._offPoint;
550 const stdair::AirportPairKey lAirportPairKey (lOrigin, lDestination);
553 const stdair::FlightDateKey& lFlightDateKey =
554 lFirstSPParsedKey.getFlightDateKey();
557 const stdair::CityCode_T& lPointOfSale = iBookingRequest.getPOS();
559 const stdair::ChannelLabel_T& lChannel =
560 iBookingRequest.getBookingChannel();
562 const stdair::PosChannelKey lFarePosChannelKey (lPointOfSale, lChannel);
565 const stdair::DateTime_T& lRequestDateTime =
566 iBookingRequest.getRequestDateTime();
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 "
579 + lFlightDateKey.toString()
580 +
" and the Origin-Destination pair: "
581 + lSegmentDateKey.toString());
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());
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)");
615 else if (_atLeastOneAvailableFeaturesRule ==
false) {
617 const stdair::DayDuration_T& lStayDuration=
618 iBookingRequest.getStayDuration();
619 std::ostringstream lStayDurationStream;
620 lStayDurationStream << lStayDuration;
621 const std::string lStayDurationString (lStayDurationStream.str());
624 const stdair::TripType_T& lTripType =
625 iBookingRequest.getTripType();
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)");
645 assert (_atLeastOneAvailableAirlineClassRule ==
false);
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)");