$treeview $search $mathjax
AirInv Logo  1.00.0
$projectbrief
$projectbrief
$searchbox

InventoryManager.cpp

Go to the documentation of this file.
00001 // //////////////////////////////////////////////////////////////////////
00002 // Import section
00003 // //////////////////////////////////////////////////////////////////////
00004 // STL
00005 #include <exception>
00006 #include <algorithm> // To use min
00007 // Boost
00008 #include <boost/make_shared.hpp>
00009 // StdAir
00010 #include <stdair/basic/BasConst_Inventory.hpp>
00011 #include <stdair/basic/BasConst_BomDisplay.hpp>
00012 #include <stdair/bom/BomManager.hpp>
00013 #include <stdair/bom/BomKeyManager.hpp> 
00014 #include <stdair/bom/BomRoot.hpp>
00015 #include <stdair/bom/Inventory.hpp>
00016 #include <stdair/bom/FlightDate.hpp>
00017 #include <stdair/bom/SegmentDate.hpp>
00018 #include <stdair/bom/SegmentCabin.hpp>
00019 #include <stdair/bom/LegDate.hpp>
00020 #include <stdair/bom/LegCabin.hpp>
00021 #include <stdair/bom/FareFamily.hpp>
00022 #include <stdair/bom/BookingClass.hpp>
00023 #include <stdair/bom/SegmentSnapshotTable.hpp>
00024 #include <stdair/bom/TravelSolutionStruct.hpp>
00025 #include <stdair/bom/FareOptionStruct.hpp>
00026 #include <stdair/bom/EventStruct.hpp>
00027 #include <stdair/bom/SnapshotStruct.hpp>
00028 #include <stdair/bom/RMEventStruct.hpp>
00029 #include <stdair/bom/FareFamily.hpp> // Contains the definition of FareFamilyList_T
00030 #include <stdair/bom/BookingClass.hpp> //
00031 #include <stdair/bom/BomRetriever.hpp>
00032 #include <stdair/factory/FacBomManager.hpp>
00033 #include <stdair/factory/FacBom.hpp>
00034 #include <stdair/service/Logger.hpp>// SEvMgr
00035 #include <sevmgr/SEVMGR_Service.hpp>
00036 // AirInv
00037 #include <airinv/AIRINV_Types.hpp>
00038 #include <airinv/bom/BomRootHelper.hpp>
00039 #include <airinv/bom/InventoryHelper.hpp>
00040 #include <airinv/bom/FlightDateHelper.hpp>
00041 #include <airinv/bom/SegmentCabinHelper.hpp>
00042 #include <airinv/command/InventoryManager.hpp>
00043 
00044 namespace AIRINV {
00045 
00046   // ////////////////////////////////////////////////////////////////////
00047   void InventoryManager::
00048   calculateAvailability (const stdair::BomRoot& iBomRoot,
00049                          stdair::TravelSolutionStruct& ioTravelSolution) {
00050 
00051     stdair::PartnershipTechnique::EN_PartnershipTechnique lENPartnershipTechnique =
00052       stdair::PartnershipTechnique::NONE;
00053     
00054     // Browse the list of segments and get the availability for the
00055     // children classes.
00056     const stdair::SegmentPath_T& lSegmentPath =
00057       ioTravelSolution.getSegmentPath();
00058     for (stdair::SegmentPath_T::const_iterator itSK = lSegmentPath.begin();
00059          itSK != lSegmentPath.end(); ++itSK) {
00060       const std::string& lSegmentKey = *itSK;
00061       const stdair::InventoryKey lInvKey =
00062         stdair::BomKeyManager::extractInventoryKey (lSegmentKey);
00063       stdair::Inventory& lInventory =
00064         stdair::BomManager::getObject<stdair::Inventory>(iBomRoot,
00065                                                          lInvKey.toString());
00066 
00067       lENPartnershipTechnique = lInventory.getPartnershipTechnique();
00068       
00069       switch (lENPartnershipTechnique) {
00070 
00071       case stdair::PartnershipTechnique::NONE:{
00072         InventoryHelper::calculateAvailability (lInventory, lSegmentKey,
00073                                                 ioTravelSolution);
00074         break;
00075       }
00076       default:{
00077         InventoryHelper::getYieldAndBidPrice (lInventory, lSegmentKey,
00078                                               ioTravelSolution);
00079         break;
00080       }
00081       }
00082       
00083     }
00084 
00085     switch (lENPartnershipTechnique) {
00086     case stdair::PartnershipTechnique::NONE:{
00087       // Compute the availabitliy for each fare option using the AU's.
00088       calculateAvailabilityByAU (ioTravelSolution);
00089       break;
00090     }
00091     case stdair::PartnershipTechnique::RAE_DA:
00092     case stdair::PartnershipTechnique::RAE_YP:{ 
00093       // 1. Compute the availability for each fare option using RAE
00094       calculateAvailabilityByRAE (ioTravelSolution);
00095       break;
00096     }
00097     case stdair::PartnershipTechnique::IBP_DA:
00098     case stdair::PartnershipTechnique::IBP_YP:{
00099       // 2. Compute the availability for each fare option using protective IBP
00100       calculateAvailabilityByProtectiveIBP (ioTravelSolution);
00101       break;
00102     }
00103     case stdair::PartnershipTechnique::IBP_YP_U:
00104     case stdair::PartnershipTechnique::RMC:
00105     case stdair::PartnershipTechnique::A_RMC:{
00106       // 3. Compute the availability for each fare option using IBP
00107       calculateAvailabilityByIBP (ioTravelSolution);
00108       break;
00109     }
00110     default: {
00111       assert (false);
00112       break;
00113     }
00114     }
00115 
00116   }
00117 
00118   // ////////////////////////////////////////////////////////////////////
00119   void InventoryManager::
00120   calculateAvailabilityByAU (stdair::TravelSolutionStruct& ioTravelSolution) {
00121 
00122     // MODIF: segment path string for availability display
00123     std::ostringstream oStr;
00124     const stdair::SegmentPath_T& lSP = ioTravelSolution.getSegmentPath();
00125     for (stdair::SegmentPath_T::const_iterator itSP = lSP.begin();
00126          itSP != lSP.end(); itSP++) {
00127       oStr << *itSP << ";";
00128     }
00129 
00130     // Browse the fare options
00131     stdair::FareOptionList_T& lFOList = ioTravelSolution.getFareOptionListRef();
00132     for (stdair::FareOptionList_T::iterator itFO = lFOList.begin();
00133          itFO != lFOList.end(); ++itFO) {
00134 
00135       stdair::FareOptionStruct& lFO = *itFO;
00136       
00137       // Check the availability
00138       const stdair::ClassList_StringList_T& lClassPath = lFO.getClassPath();
00139       
00140       const stdair::ClassAvailabilityMapHolder_T& lClassAvailabilityMapHolder =
00141         ioTravelSolution.getClassAvailabilityMapHolder();
00142       
00143       // Initialise the flag stating whether the availability is enough
00144       stdair::Availability_T lAvl =
00145         std::numeric_limits<stdair::Availability_T>::max();
00146       
00147       // Sanity check: the travel solution must contain two lists,
00148       // one for the booking class availabilities, the other for the
00149       // fare options.
00150       assert (lClassAvailabilityMapHolder.empty() == false
00151               && lClassPath.empty() == false);
00152       
00153       // List of booking class availability maps (one map per segment)
00154       stdair::ClassAvailabilityMapHolder_T::const_iterator itCAMH =
00155         lClassAvailabilityMapHolder.begin();
00156       
00157       // List of fare options
00158       stdair::ClassList_StringList_T::const_iterator itClassList =
00159         lClassPath.begin();
00160       
00161       // Browse both lists at the same time, i.e., one element per segment
00162       for (; itCAMH != lClassAvailabilityMapHolder.end()
00163              && itClassList != lClassPath.end(); ++itCAMH, ++itClassList) {
00164         
00165         // Retrieve the booking class list for the current segment
00166         const stdair::ClassList_String_T& lCurrentClassList = *itClassList;
00167         assert (lCurrentClassList.size() > 0);
00168         
00169         // TODO: instead of just extracting the first booking class,
00170         //       perform a choice on the full list of classes.
00171         // Extract one booking class key (class code)
00172         stdair::ClassCode_T lFirstClass;
00173         lFirstClass.append (lCurrentClassList, 0, 1);
00174         
00175         // Retrieve the booking class map for the current segment
00176         const stdair::ClassAvailabilityMap_T& lClassAvlMap = *itCAMH;
00177         
00178         // Retrieve the availability of the chosen booking class
00179         const stdair::ClassAvailabilityMap_T::const_iterator itClassAvl =
00180           lClassAvlMap.find (lFirstClass);
00181         
00182         if (itClassAvl == lClassAvlMap.end()) {
00183           // DEBUG
00184           STDAIR_LOG_DEBUG ("No availability has been set up for the class '"
00185                             << lFirstClass << "'. Travel solution: "
00186                             << ioTravelSolution.display());
00187         }
00188         assert (itClassAvl != lClassAvlMap.end());
00189         
00190         const stdair::Availability_T& lCurrentAvl = itClassAvl->second;
00191         if (lAvl > lCurrentAvl) {
00192           lAvl = lCurrentAvl;
00193         }
00194       }
00195       
00196       lFO.setAvailability (lAvl);
00197 
00198       //MODIF: availability display
00199       STDAIR_LOG_DEBUG ("Fare option " << lFO.describe() << ", "
00200                         << "Availability " << lFO.getAvailability() << ", "
00201                         << "Segment Path " << oStr.str());
00202     }
00203   }
00204 
00205   // \todo: the following code must be either re-written or removed.
00206   //        There is indeed a lot of code duplication.
00207   // ////////////////////////////////////////////////////////////////////
00208   void InventoryManager::
00209   calculateAvailabilityByRAE (stdair::TravelSolutionStruct& ioTravelSolution) {
00210     
00211     std::ostringstream oStr;
00212     const stdair::SegmentPath_T& lSP = ioTravelSolution.getSegmentPath();
00213     for (stdair::SegmentPath_T::const_iterator itSP = lSP.begin();
00214          itSP != lSP.end(); itSP++) {
00215       oStr << *itSP << ";";
00216     }
00217 
00218     //Retrieve bid price vector and yield maps
00219     const stdair::ClassYieldMapHolder_T& lClassYieldMapHolder =
00220       ioTravelSolution.getClassYieldMapHolder();
00221     const stdair::ClassBpvMapHolder_T& lClassBpvMapHolder =
00222       ioTravelSolution.getClassBpvMapHolder();
00223 
00224     //Retrieve the list of fare options and browse it
00225     stdair::FareOptionList_T& lFOList = ioTravelSolution.getFareOptionListRef();
00226     for (stdair::FareOptionList_T::iterator itFO = lFOList.begin();
00227          itFO != lFOList.end(); ++itFO) {
00228 
00229       stdair::FareOptionStruct& lFO = *itFO;
00230   
00231       stdair::ClassYieldMapHolder_T::const_iterator itCYM =
00232         lClassYieldMapHolder.begin();
00233       stdair::ClassBpvMapHolder_T::const_iterator itCBPM =
00234         lClassBpvMapHolder.begin();
00235 
00236       const stdair::ClassList_StringList_T& lClassPath = lFO.getClassPath();
00237 
00238       
00239       // Sanity checks
00240       assert (lClassPath.size() == lClassYieldMapHolder.size());
00241       assert (lClassPath.size() == lClassBpvMapHolder.size());
00242 
00243       // Browse class path, class-yield maps, class-(bid price vector) maps.
00244       // Each iteration corresponds to one segment.
00245 
00246       std::ostringstream oCPStr;
00247       for (stdair::ClassList_StringList_T::const_iterator itCL =
00248              lClassPath.begin();
00249            itCL != lClassPath.end(); ++itCL, ++itCYM, ++itCBPM) {
00250 
00251         // Class path determination
00252         if (itCL == lClassPath.begin()) {
00253           oCPStr << *itCL;
00254           
00255         } else {
00256           oCPStr << "-" << *itCL;
00257         }
00258 
00259         const stdair::ClassList_String_T& lCL = *itCL;
00260         stdair::ClassCode_T lCC;
00261         lCC.append (lCL, 0, 1);
00262 
00263         const stdair::ClassYieldMap_T& lCYM = *itCYM;
00264         stdair::ClassYieldMap_T::const_iterator itCCCYM = lCYM.find (lCC);
00265         assert (itCCCYM != lCYM.end());
00266 
00267         const stdair::ClassBpvMap_T& lCBPM = *itCBPM;
00268         stdair::ClassBpvMap_T::const_iterator itCCCBPM = lCBPM.find (lCC);
00269         assert (itCCCBPM != lCBPM.end());
00270 
00271         const stdair::BidPriceVector_T* lBidPriceVector_ptr = itCCCBPM->second;
00272         assert (lBidPriceVector_ptr != NULL);
00273                 
00274         // Initialization of fare option availability
00275         if (itCL == lClassPath.begin()) {
00276           lFO.setAvailability (lBidPriceVector_ptr->size());
00277         }
00278 
00279         // Availability update
00280         if (lFO.getAvailability() > 0) {
00281           
00282           //Segment availability calculation
00283           stdair::BidPriceVector_T lReverseBPV (lBidPriceVector_ptr->size());
00284           std::reverse_copy (lBidPriceVector_ptr->begin(),
00285                              lBidPriceVector_ptr->end(),
00286                              lReverseBPV.begin());
00287 
00288           const stdair::YieldValue_T& lYield = itCCCYM->second;
00289           stdair::BidPriceVector_T::const_iterator lBidPrice =
00290             std::upper_bound (lReverseBPV.begin(), lReverseBPV.end(), lYield);
00291 
00292           const stdair::Availability_T lAvl = lBidPrice - lReverseBPV.begin();
00293 
00294           // Availability update
00295           lFO.setAvailability (std::min (lFO.getAvailability(), lAvl));
00296         }
00297       }
00298                
00299       // DEBUG
00300       STDAIR_LOG_DEBUG ("Fare option: " << lFO.describe() << ", "
00301                         << "Availability: " << lFO.getAvailability() << ", "
00302                         << "Segment Path: " << oStr.str() << ", ");
00303     }
00304   }
00305   
00306   // \todo: the following code must be either re-written or removed.
00307   //        There is indeed a lot of code duplication.
00308   // ////////////////////////////////////////////////////////////////////
00309   void InventoryManager::
00310   calculateAvailabilityByIBP (stdair::TravelSolutionStruct& ioTravelSolution) {
00311     std::ostringstream oStr;
00312 
00313     // Yield valuation coefficient for multi-segment travel solutions   
00314     double alpha = 1.0;
00315 
00316     const stdair::SegmentPath_T& lSP = ioTravelSolution.getSegmentPath();
00317     for (stdair::SegmentPath_T::const_iterator itSP = lSP.begin();
00318          itSP != lSP.end(); itSP++) {
00319       oStr << *itSP << ";";
00320     }
00321 
00322     //Retrieve bid price vector and yield maps
00323     const stdair::ClassYieldMapHolder_T& lClassYieldMapHolder =
00324       ioTravelSolution.getClassYieldMapHolder();
00325     const stdair::ClassBpvMapHolder_T& lClassBpvMapHolder =
00326       ioTravelSolution.getClassBpvMapHolder();
00327 
00328     // Retrieve the list of fare options and browse it
00329     stdair::FareOptionList_T& lFOList = ioTravelSolution.getFareOptionListRef();
00330     for (stdair::FareOptionList_T::iterator itFO = lFOList.begin();
00331          itFO != lFOList.end(); ++itFO) {
00332 
00333       stdair::FareOptionStruct& lFO = *itFO;
00334   
00335       stdair::ClassYieldMapHolder_T::const_iterator itCYM =
00336         lClassYieldMapHolder.begin();
00337       stdair::ClassBpvMapHolder_T::const_iterator itCBPM =
00338         lClassBpvMapHolder.begin();
00339 
00340       const stdair::ClassList_StringList_T& lClassPath = lFO.getClassPath();
00341 
00342       // Sanity checks
00343       assert (lClassPath.size() == lClassYieldMapHolder.size());
00344       assert (lClassPath.size() == lClassBpvMapHolder.size());
00345 
00346       // Yield is taken to be equal to fare (connecting flights)
00347 
00348       // \todo: take yield instead
00349       stdair::YieldValue_T lTotalYield = lFO.getFare();
00350       // Bid price initialisation
00351       stdair::BidPrice_T lTotalBidPrice = 0;
00352 
00353       // Browse class path, class-yield maps, class-(bid price vector) maps.
00354       // Each iteration corresponds to one segment.
00355 
00356       std::ostringstream oCPStr;
00357       for (stdair::ClassList_StringList_T::const_iterator itCL =
00358              lClassPath.begin();
00359            itCL != lClassPath.end(); ++itCL, ++itCYM, ++itCBPM) {
00360 
00361         // Class path determination
00362         if (itCL == lClassPath.begin()) {
00363           oCPStr << *itCL;
00364 
00365         } else {
00366           oCPStr << "-" << *itCL;
00367         }
00368 
00369         const stdair::ClassList_String_T& lCL = *itCL;
00370         stdair::ClassCode_T lCC;
00371         lCC.append (lCL, 0, 1);
00372 
00373         const stdair::ClassYieldMap_T& lCYM = *itCYM;
00374         stdair::ClassYieldMap_T::const_iterator itCCCYM = lCYM.find (lCC);
00375         assert (itCCCYM != lCYM.end());
00376 
00377         const stdair::ClassBpvMap_T& lCBPM = *itCBPM;
00378         stdair::ClassBpvMap_T::const_iterator itCCCBPM = lCBPM.find (lCC);
00379         assert (itCCCBPM != lCBPM.end());
00380 
00381         const stdair::BidPriceVector_T* lBidPriceVector_ptr = itCCCBPM->second;
00382         assert (lBidPriceVector_ptr != NULL);
00383                 
00384         //Initialization of fare option availability
00385         if (itCL == lClassPath.begin()) {
00386           lFO.setAvailability (lBidPriceVector_ptr->size());
00387         }
00388 
00389         // Availability update
00390         if (lFO.getAvailability() > 0) {
00391           //Segment availability calculation
00392           stdair::BidPriceVector_T lReverseBPV (lBidPriceVector_ptr->size());
00393           std::reverse_copy (lBidPriceVector_ptr->begin(),
00394                              lBidPriceVector_ptr->end(), lReverseBPV.begin());
00395 
00396           const stdair::YieldValue_T& lYield = itCCCYM->second;
00397           stdair::BidPriceVector_T::const_iterator lBidPrice =
00398             std::upper_bound (lReverseBPV.begin(), lReverseBPV.end(), lYield);
00399 
00400           const stdair::Availability_T lAvl = lBidPrice - lReverseBPV.begin();
00401 
00402           // Availability update
00403           lFO.setAvailability (std::min(lFO.getAvailability(), lAvl));
00404         }
00405 
00406         // Total bid price calculation
00407         if (lBidPriceVector_ptr->size() > 0) {
00408           lTotalBidPrice += lBidPriceVector_ptr->back();          
00409 
00410         } else {
00411           lTotalBidPrice = std::numeric_limits<stdair::BidPrice_T>::max();
00412         }
00413 
00414         // Total yield calculation (has been replaced by total fare).
00415         //lTotalYield += lYield;
00416       }
00417       // Multi-segment bid price control
00418 
00419       if (lClassPath.size() > 1) {
00420         if (lFO.getAvailability() > 0) {
00421           const stdair::Availability_T lAvl =
00422             alpha * lTotalYield >= lTotalBidPrice;
00423           lFO.setAvailability (lAvl * lFO.getAvailability());
00424 
00425         } else {
00426           const stdair::Availability_T lAvl =
00427             alpha * lTotalYield >= lTotalBidPrice;
00428           lFO.setAvailability (lAvl);
00429         }
00430       
00431         // DEBUG
00432         STDAIR_LOG_DEBUG ("Class: " << oCPStr.str()
00433                           << ", " << "Yield: " << alpha*lTotalYield << ", "
00434                           << "Bid price: " << lTotalBidPrice << ", "
00435                           << "Remaining capacity: " << "Undefined" << " "
00436                           << "Segment date: " << oStr.str());
00437       }
00438          
00439       // DEBUG
00440       STDAIR_LOG_DEBUG ("Fare option " << lFO.describe() << ", "
00441                         << "Availability " << lFO.getAvailability() << ", "
00442                         << "Segment Path " << oStr.str() << ", ");
00443     }
00444   }
00445 
00446   // \todo: the following code must be either re-written or removed.
00447   //        There is indeed a lot of code duplication.
00448   // ////////////////////////////////////////////////////////////////////
00449   void InventoryManager::
00450   calculateAvailabilityByProtectiveIBP (stdair::TravelSolutionStruct& ioTravelSolution) {
00451     std::ostringstream oStr;
00452 
00453     // Yield valuation coefficient for multi-segment travel solutions   
00454     double alpha = 1.0;
00455 
00456     const stdair::SegmentPath_T& lSP = ioTravelSolution.getSegmentPath();
00457     for (stdair::SegmentPath_T::const_iterator itSP = lSP.begin();
00458          itSP != lSP.end(); itSP++) {
00459       oStr << *itSP << ";";
00460     }
00461 
00462     //Retrieve bid price vector and yield maps
00463     const stdair::ClassYieldMapHolder_T& lClassYieldMapHolder =
00464       ioTravelSolution.getClassYieldMapHolder();
00465     const stdair::ClassBpvMapHolder_T& lClassBpvMapHolder =
00466       ioTravelSolution.getClassBpvMapHolder();
00467 
00468     //Retrieve the list of fare options and browse it
00469     stdair::FareOptionList_T& lFOList = ioTravelSolution.getFareOptionListRef();
00470     for (stdair::FareOptionList_T::iterator itFO = lFOList.begin();
00471          itFO != lFOList.end(); ++itFO) {
00472 
00473       stdair::FareOptionStruct& lFO = *itFO;
00474   
00475       stdair::ClassYieldMapHolder_T::const_iterator itCYM =
00476         lClassYieldMapHolder.begin();
00477       stdair::ClassBpvMapHolder_T::const_iterator itCBPM =
00478         lClassBpvMapHolder.begin();
00479 
00480       const stdair::ClassList_StringList_T& lClassPath = lFO.getClassPath();
00481 
00482       // Sanity checks
00483       assert (lClassPath.size() == lClassYieldMapHolder.size());
00484       assert (lClassPath.size() == lClassBpvMapHolder.size());
00485 
00486       // Yield is taken to be equal to fare (connecting flights)
00487       // TODO : take yield instead
00488       stdair::YieldValue_T lTotalYield = lFO.getFare();
00489       // Bid price initialisation
00490       stdair::BidPrice_T lTotalBidPrice = 0;
00491       // Maximal bid price initialisation
00492       stdair::BidPrice_T lMaxBidPrice = 0;
00493 
00494       //Browse class path, class-yield maps, class-(bid price vector) maps.
00495       //Each iteration corresponds to one segment.
00496 
00497       std::ostringstream oCPStr;
00498       for (stdair::ClassList_StringList_T::const_iterator itCL =
00499              lClassPath.begin();
00500            itCL != lClassPath.end(); ++itCL, ++itCYM, ++itCBPM) {
00501 
00502         // Class path determination
00503         if (itCL == lClassPath.begin()) {
00504           oCPStr << *itCL;
00505 
00506         } else {
00507           oCPStr << "-" << *itCL;
00508         }
00509 
00510         const stdair::ClassList_String_T& lCL = *itCL;
00511         stdair::ClassCode_T lCC;
00512         lCC.append (lCL, 0, 1);
00513 
00514         const stdair::ClassYieldMap_T& lCYM = *itCYM;
00515         stdair::ClassYieldMap_T::const_iterator itCCCYM = lCYM.find (lCC);
00516         assert (itCCCYM != lCYM.end());
00517 
00518         const stdair::YieldValue_T& lYield = itCCCYM->second;
00519         const stdair::ClassBpvMap_T& lCBPM = *itCBPM;
00520         stdair::ClassBpvMap_T::const_iterator itCCCBPM = lCBPM.find (lCC);
00521         assert (itCCCBPM != lCBPM.end());
00522 
00523         const stdair::BidPriceVector_T* lBidPriceVector_ptr = itCCCBPM->second;
00524         assert (lBidPriceVector_ptr != NULL);
00525                 
00526         // Initialization of fare option availability
00527         if (itCL == lClassPath.begin()) {
00528           lFO.setAvailability (lBidPriceVector_ptr->size());
00529         }
00530 
00531         // Availability update
00532         if (lFO.getAvailability() > 0) {
00533           
00534           //Segment availability calculation
00535           stdair::BidPriceVector_T lReverseBPV (lBidPriceVector_ptr->size());
00536           std::reverse_copy (lBidPriceVector_ptr->begin(),
00537                              lBidPriceVector_ptr->end(), lReverseBPV.begin());
00538 
00539           stdair::BidPriceVector_T::const_iterator lBidPrice =
00540             std::upper_bound (lReverseBPV.begin(), lReverseBPV.end(), lYield);
00541 
00542           const stdair::Availability_T lAvl = lBidPrice - lReverseBPV.begin();
00543           
00544           // Availability update
00545           lFO.setAvailability (std::min(lFO.getAvailability(), lAvl));
00546      
00547         }
00548 
00549         // Total bid price calculation
00550         if (lBidPriceVector_ptr->size() > 0) {
00551           lTotalBidPrice += lBidPriceVector_ptr->back();
00552 
00553           if (lMaxBidPrice < lBidPriceVector_ptr->back()) {
00554             lMaxBidPrice = lBidPriceVector_ptr->back();
00555           }
00556           
00557         } else {
00558           lTotalBidPrice = std::numeric_limits<stdair::BidPrice_T>::max();
00559         }
00560 
00561         // Total yield calculation (has been replaced by total fare).
00562         //lTotalYield += lYield;
00563       }
00564       // Multi-segment bid price control
00565 
00566       // Protective IBP (maximin): guarantees the minimal yield for each airline
00567       // Proration factors are all equal to 1/{number of partners}.
00568 
00569       lTotalBidPrice = std::max (lMaxBidPrice * lClassPath.size(),
00570                                  lTotalBidPrice);
00571 
00572       if (lClassPath.size() > 1) {
00573         if (lFO.getAvailability() > 0) {
00574           const stdair::Availability_T lAvl =
00575             alpha * lTotalYield >= lTotalBidPrice;
00576           lFO.setAvailability (lAvl * lFO.getAvailability());
00577 
00578         } else {
00579           const stdair::Availability_T lAvl =
00580             alpha * lTotalYield >= lTotalBidPrice;
00581           lFO.setAvailability (lAvl);
00582         }
00583       
00584         // DEBUG
00585         STDAIR_LOG_DEBUG ("Class: " << oCPStr.str()
00586                           << ", " << "Yield: " << alpha*lTotalYield << ", "
00587                           << "Bid price: " << lTotalBidPrice << ", "
00588                           << "Remaining capacity: " << "Undefined" << " "
00589                           << "Segment date: " << oStr.str());
00590       }
00591 
00592       // DEBUG         
00593       STDAIR_LOG_DEBUG ("Fare option " << lFO.describe() << ", "
00594                         << "Availability " << lFO.getAvailability() << ", "
00595                         << "Segment Path " << oStr.str() << ", ");
00596     }
00597   }
00598   
00599   //MODIF
00600   // ////////////////////////////////////////////////////////////////////
00601   void InventoryManager::setDefaultBidPriceVector (stdair::BomRoot& ioBomRoot) {
00602 
00603     const stdair::InventoryList_T& lInvList =
00604       stdair::BomManager::getList<stdair::Inventory> (ioBomRoot);
00605     for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
00606          itInv != lInvList.end(); ++itInv) {
00607       stdair::Inventory* lCurrentInv_ptr = *itInv;
00608       assert (lCurrentInv_ptr != NULL);
00609 
00610       // Set the default bid price for own cabins.
00611       setDefaultBidPriceVector (*lCurrentInv_ptr);
00612 
00613       // Check if the inventory contains images of partner inventories.
00614       // If so, set the default bid price for their cabins.
00615       if (stdair::BomManager::hasList<stdair::Inventory> (*lCurrentInv_ptr)) {
00616         const stdair::InventoryList_T& lPartnerInvList =
00617           stdair::BomManager::getList<stdair::Inventory> (*lCurrentInv_ptr);
00618 
00619         for (stdair::InventoryList_T::const_iterator itPartnerInv =
00620                lPartnerInvList.begin();
00621              itPartnerInv != lPartnerInvList.end(); ++itPartnerInv) {
00622           stdair::Inventory* lCurrentPartnerInv_ptr = *itPartnerInv;
00623           assert (lCurrentPartnerInv_ptr != NULL);
00624 
00625           setDefaultBidPriceVector (*lCurrentPartnerInv_ptr);
00626         }
00627       }            
00628     }     
00629   }
00630 
00631   // ////////////////////////////////////////////////////////////////////
00632   void InventoryManager::
00633   setDefaultBidPriceVector (stdair::Inventory& ioInventory) {
00634 
00635     const stdair::FlightDateList_T& lFlightDateList =
00636       stdair::BomManager::getList<stdair::FlightDate> (ioInventory);
00637     for (stdair::FlightDateList_T::const_iterator itFlightDate =
00638            lFlightDateList.begin();
00639          itFlightDate != lFlightDateList.end(); ++itFlightDate) {
00640       stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate;
00641       assert (lCurrentFlightDate_ptr != NULL);
00642 
00643       // Check if the flight date holds a list of leg dates.
00644       // If so retrieve it and initialise the bid price vectors of their cabins.
00645       if (stdair::BomManager::hasList<stdair::LegDate> (*lCurrentFlightDate_ptr)) {
00646         const stdair::LegDateList_T& lLegDateList =
00647           stdair::BomManager::getList<stdair::LegDate> (*lCurrentFlightDate_ptr);
00648         for (stdair::LegDateList_T::const_iterator itLegDate =
00649                lLegDateList.begin();
00650              itLegDate != lLegDateList.end(); ++itLegDate) {
00651           stdair::LegDate* lCurrentLegDate_ptr = *itLegDate;
00652           assert (lCurrentLegDate_ptr != NULL);
00653           
00654           const stdair::LegCabinList_T& lLegCabinList =
00655             stdair::BomManager::getList<stdair::LegCabin> (*lCurrentLegDate_ptr);
00656           for (stdair::LegCabinList_T::const_iterator itLegCabin =
00657                  lLegCabinList.begin();
00658                itLegCabin != lLegCabinList.end(); ++itLegCabin) {
00659             stdair::LegCabin* lCurrentLegCabin_ptr = *itLegCabin;
00660             assert (lCurrentLegCabin_ptr != NULL);
00661 
00662             const stdair::CabinCapacity_T& lCabinCapacity =
00663               lCurrentLegCabin_ptr->getPhysicalCapacity();
00664             lCurrentLegCabin_ptr->emptyBidPriceVector();
00665 
00666             stdair::BidPriceVector_T& lBPV =
00667               lCurrentLegCabin_ptr->getBidPriceVector();
00668 
00669             //for (stdair::CabinCapacity_T k = 0;k!=lCabinCapacity;k++) {lBPV.push_back(400 + 300/sqrt(k+1));}
00670             for (stdair::CabinCapacity_T k = 0; k != lCabinCapacity; k++) {
00671               lBPV.push_back (400);
00672             }
00673 
00674             lCurrentLegCabin_ptr->setPreviousBidPrice (lBPV.back());
00675             lCurrentLegCabin_ptr->setCurrentBidPrice (lBPV.back());          
00676           }
00677         }
00678       }
00679     }
00680   }   
00681   
00682   // ////////////////////////////////////////////////////////////////////
00683   bool InventoryManager::sell (stdair::Inventory& ioInventory,
00684                                const std::string& iSegmentDateKey,
00685                                const stdair::ClassCode_T& iClassCode,
00686                                const stdair::PartySize_T& iPartySize) {
00687 
00688     // Make the sale within the inventory.
00689     return InventoryHelper::sell (ioInventory, iSegmentDateKey,
00690                                   iClassCode, iPartySize);
00691   }
00692   
00693   // ////////////////////////////////////////////////////////////////////
00694   bool InventoryManager::sell (const stdair::BookingClassID_T& iClassID,
00695                                const stdair::PartySize_T& iPartySize) {
00696 
00697     // Make the sale within the inventory.
00698     return InventoryHelper::sell (iClassID, iPartySize);
00699   }
00700 
00701   // ////////////////////////////////////////////////////////////////////
00702   bool InventoryManager::cancel (stdair::Inventory& ioInventory,
00703                                  const std::string& iSegmentDateKey,
00704                                  const stdair::ClassCode_T& iClassCode,
00705                                  const stdair::PartySize_T& iPartySize) {
00706     
00707     // Make the cancellation within the inventory.
00708     return InventoryHelper::cancel (ioInventory, iSegmentDateKey,
00709                                     iClassCode, iPartySize);
00710   }
00711   
00712   // ////////////////////////////////////////////////////////////////////
00713   bool InventoryManager::cancel (const stdair::BookingClassID_T& iClassID,
00714                                  const stdair::PartySize_T& iPartySize) {
00715 
00716     // Make the cancellation within the inventory.
00717     return InventoryHelper::cancel (iClassID, iPartySize);
00718   }
00719 
00720   // ////////////////////////////////////////////////////////////////////
00721   void InventoryManager::
00722   updateBookingControls (stdair::FlightDate& ioFlightDate) {
00723 
00724     // Forward the call to FlightDateHelper.
00725     FlightDateHelper::updateBookingControls (ioFlightDate);
00726   }
00727 
00728   // ////////////////////////////////////////////////////////////////////
00729   void InventoryManager::
00730   recalculateAvailability (stdair::FlightDate& ioFlightDate) {
00731 
00732     // Forward the call to FlightDateHelper.
00733     FlightDateHelper::recalculateAvailability (ioFlightDate);
00734   }
00735 
00736   // ////////////////////////////////////////////////////////////////////
00737   void InventoryManager::takeSnapshots(const stdair::Inventory& iInventory,
00738                                        const stdair::DateTime_T& iSnapshotTime){
00739 
00740     // Make the snapshots within the inventory
00741     InventoryHelper::takeSnapshots (iInventory, iSnapshotTime);
00742   } 
00743     
00744   // ////////////////////////////////////////////////////////////////////
00745   void InventoryManager::
00746   createDirectAccesses (const stdair::BomRoot& iBomRoot) {
00747 
00748     // Browse the list of inventories and create direct accesses
00749     // within each inventory.
00750     const stdair::InventoryList_T& lInvList =
00751       stdair::BomManager::getList<stdair::Inventory> (iBomRoot);
00752     for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
00753          itInv != lInvList.end(); ++itInv) {
00754       stdair::Inventory* lCurrentInv_ptr = *itInv;
00755       assert (lCurrentInv_ptr != NULL);
00756 
00757       createDirectAccesses (iBomRoot, *lCurrentInv_ptr);
00758     }
00759 
00760     // Browse the list of inventories and create partner accesses
00761     // within each inventory.
00762     for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
00763          itInv != lInvList.end(); ++itInv) {
00764       stdair::Inventory* lCurrentInv_ptr = *itInv;
00765       assert (lCurrentInv_ptr != NULL);
00766       
00767       createPartnerAccesses (iBomRoot, *lCurrentInv_ptr);
00768     }
00769 
00770     // Fill some attributes of segment-date with the routing legs.
00771     BomRootHelper::fillFromRouting (iBomRoot);  
00772   }
00773 
00774   // ////////////////////////////////////////////////////////////////////
00775   void InventoryManager::
00776   createDirectAccesses (const stdair::BomRoot& iBomRoot,
00777                         stdair::Inventory& ioInventory) {
00778 
00779     // Browse the list of flight-dates and create direct accesses
00780     // within each flight-date.
00781     const stdair::FlightDateList_T& lFlightDateList = 
00782       stdair::BomManager::getList<stdair::FlightDate> (ioInventory);
00783     for (stdair::FlightDateList_T::const_iterator itFlightDate = 
00784            lFlightDateList.begin();
00785          itFlightDate != lFlightDateList.end(); ++itFlightDate) {
00786       stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate;
00787       assert (lCurrentFlightDate_ptr != NULL);
00788 
00789       createDirectAccesses (iBomRoot, ioInventory, *lCurrentFlightDate_ptr);
00790     }
00791     
00792     // Browse the list of inventories and create direct accesses
00793     // within each inventory.
00794     const bool hasInventoryList =
00795       stdair::BomManager::hasList<stdair::Inventory> (ioInventory);
00796     if (hasInventoryList == true) {
00797       const stdair::InventoryList_T& lInvList =
00798         stdair::BomManager::getList<stdair::Inventory> (ioInventory);
00799       for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
00800            itInv != lInvList.end(); ++itInv) {
00801         stdair::Inventory* lCurrentInv_ptr = *itInv;
00802         assert (lCurrentInv_ptr != NULL);
00803 
00804         createDirectAccesses (iBomRoot, *lCurrentInv_ptr);
00805       }
00806     }
00807   } 
00808 
00809   // ////////////////////////////////////////////////////////////////////
00810   void InventoryManager::
00811   createDirectAccesses (const stdair::BomRoot& ioBomRoot,
00812                          stdair::Inventory& ioInventory,
00813                          stdair::FlightDate& ioFlightDate) {
00814 
00815     bool areSegmentAndRoutingLegLinked = false;
00816 
00817     // Browse the list of segment-dates and create direct accesses
00818     // within each segment-date.
00819     const stdair::SegmentDateList_T& lSegmentDateList = 
00820       stdair::BomManager::getList<stdair::SegmentDate> (ioFlightDate);
00821     for (stdair::SegmentDateList_T::const_iterator itSegmentDate = 
00822            lSegmentDateList.begin();
00823          itSegmentDate != lSegmentDateList.end(); ++itSegmentDate) {
00824 
00825       stdair::SegmentDate* lCurrentSegmentDate_ptr = *itSegmentDate;
00826       assert (lCurrentSegmentDate_ptr != NULL); 
00827 
00828       // Get the routing leg keys list
00829       const stdair::RoutingLegKeyList_T& lRoutingLegKeyList = 
00830         lCurrentSegmentDate_ptr->getLegKeyList ();
00831 
00832       // Browse the list of routing leg keys and try to create direct accesses
00833       // with each corresponding leg date.
00834       for (stdair::RoutingLegKeyList_T::const_iterator itRoutingLegKey = 
00835            lRoutingLegKeyList.begin();
00836          itRoutingLegKey != lRoutingLegKeyList.end(); ++itRoutingLegKey) {
00837 
00838         // Try to retrieve the routing LegDate within the flight date
00839         stdair::LegDate* lLegDate_ptr = stdair::BomRetriever::
00840           retrieveOperatingLegDateFromLongKey (ioFlightDate, *itRoutingLegKey);
00841         
00842         if (lLegDate_ptr != NULL) {
00843 
00844           // Link the SegmentDate and LegDate together
00845           stdair::FacBomManager::addToListAndMap (*lCurrentSegmentDate_ptr,
00846                                                   *lLegDate_ptr);
00847           stdair::FacBomManager::addToListAndMap (*lLegDate_ptr,
00848                                                   *lCurrentSegmentDate_ptr);
00849           areSegmentAndRoutingLegLinked = true;
00850         }
00851       }
00852       if (areSegmentAndRoutingLegLinked == true) {
00853         createDirectAccesses (*lCurrentSegmentDate_ptr);
00854       }
00855     }
00856   }
00857 
00858   // ////////////////////////////////////////////////////////////////////
00859   void InventoryManager::
00860   createDirectAccesses (stdair::SegmentDate& ioSegmentDate) {
00861 
00862     // Browse the list of segment-cabins and create direct accesses
00863     // within each segment-cabin.
00864     const stdair::SegmentCabinList_T& lSegmentCabinList = 
00865       stdair::BomManager::getList<stdair::SegmentCabin> (ioSegmentDate);
00866     for (stdair::SegmentCabinList_T::const_iterator itSegmentCabin = 
00867            lSegmentCabinList.begin();
00868          itSegmentCabin != lSegmentCabinList.end(); ++itSegmentCabin) {
00869 
00870       //
00871       stdair::SegmentCabin* lCurrentSegmentCabin_ptr = *itSegmentCabin;
00872       assert (lCurrentSegmentCabin_ptr != NULL);
00873 
00874       //
00875       const stdair::CabinCode_T& lCabinCode =
00876           lCurrentSegmentCabin_ptr->getCabinCode();
00877       
00878       // Iterate on the routing legs
00879       const stdair::LegDateList_T& lLegDateList =
00880         stdair::BomManager::getList<stdair::LegDate> (ioSegmentDate);
00881       for (stdair::LegDateList_T::const_iterator itLegDate =
00882              lLegDateList.begin();
00883            itLegDate != lLegDateList.end(); ++itLegDate) {
00884 
00885         const stdair::LegDate* lCurrentLegDate_ptr = *itLegDate;        
00886         assert (lCurrentLegDate_ptr != NULL);
00887 
00888         // Retrieve the LegCabin getting the same class of service
00889         // (cabin code) as the SegmentCabin.
00890         stdair::LegCabin& lLegCabin = stdair::BomManager::
00891           getObject<stdair::LegCabin> (*lCurrentLegDate_ptr, lCabinCode);
00892 
00903         stdair::FacBomManager::addToListAndMap (*lCurrentSegmentCabin_ptr,
00904                                                 lLegCabin,
00905                                                 lLegCabin.getFullerKey());
00906 
00917         stdair::FacBomManager::
00918           addToListAndMap (lLegCabin, *lCurrentSegmentCabin_ptr,
00919                            lCurrentSegmentCabin_ptr->getFullerKey());
00920       }      
00921     }
00922   }
00923 
00924   // ////////////////////////////////////////////////////////////////////
00925   void InventoryManager::
00926   createPartnerAccesses (const stdair::BomRoot& iBomRoot,
00927                         stdair::Inventory& ioInventory) {
00928 
00929     // Browse the list of flight-dates and create partner accesses
00930     // within each flight-date.
00931     const stdair::FlightDateList_T& lFlightDateList = 
00932       stdair::BomManager::getList<stdair::FlightDate> (ioInventory);
00933     for (stdair::FlightDateList_T::const_iterator itFlightDate = 
00934            lFlightDateList.begin();
00935          itFlightDate != lFlightDateList.end(); ++itFlightDate) {
00936       stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate;
00937       assert (lCurrentFlightDate_ptr != NULL);
00938 
00939       createPartnerAccesses (iBomRoot, ioInventory, *lCurrentFlightDate_ptr);
00940     }
00941   }
00942 
00943   // ////////////////////////////////////////////////////////////////////
00944   void InventoryManager::
00945   createPartnerAccesses (const stdair::BomRoot& ioBomRoot,
00946                          stdair::Inventory& ioInventory,
00947                          stdair::FlightDate& ioFlightDate) {
00948 
00949     // Browse the list of segment-dates and create partner accesses
00950     // within each segment-date.
00951     const stdair::SegmentDateList_T& lSegmentDateList = 
00952       stdair::BomManager::getList<stdair::SegmentDate> (ioFlightDate);
00953     for (stdair::SegmentDateList_T::const_iterator itSegmentDate = 
00954            lSegmentDateList.begin();
00955          itSegmentDate != lSegmentDateList.end(); ++itSegmentDate) {
00956 
00957       stdair::SegmentDate* lCurrentSegmentDate_ptr = *itSegmentDate;
00958       assert (lCurrentSegmentDate_ptr != NULL); 
00959 
00960       // Get the routing leg keys list
00961       const stdair::RoutingLegKeyList_T& lRoutingLegKeyList = 
00962         lCurrentSegmentDate_ptr->getLegKeyList ();
00963 
00964       // Browse the list of routing leg keys and try to create partner accesses
00965       // with each corresponding leg date.
00966       for (stdair::RoutingLegKeyList_T::const_iterator itRoutingLegKey = 
00967            lRoutingLegKeyList.begin();
00968          itRoutingLegKey != lRoutingLegKeyList.end(); ++itRoutingLegKey) {
00969 
00970         // Try to retrieve the LegDate getting that Boarding Point within the
00971         // flight date
00972         stdair::LegDate* lLegDate_ptr = stdair::BomRetriever::
00973           retrieveOperatingLegDateFromLongKey (ioFlightDate, *itRoutingLegKey);
00974 
00975         // If there is no LegDate getting that Boarding Point within the flight
00976         // date, the segment is operating by a partner
00977         if (lLegDate_ptr == NULL) {
00978 
00979           // Retrieve the (unique) operating LegDate getting that Boarding Point
00980           // within the partner inventory
00981           std::ostringstream lRoutingSegmentKey;
00982           lRoutingSegmentKey << *itRoutingLegKey << ";"
00983                              << lCurrentSegmentDate_ptr->getOffPoint();
00984           
00985           stdair::SegmentDate* lPartnerOperatingSegmentDate_ptr =
00986             stdair::BomRetriever::
00987             retrievePartnerSegmentDateFromLongKey (ioInventory,
00988                                                    lRoutingSegmentKey.str());
00989           assert (lPartnerOperatingSegmentDate_ptr != NULL);
00990 
00991           // Link the current segment date with its operating one
00992           stdair::FacBomManager::linkWithOperating (*lCurrentSegmentDate_ptr,
00993                                                     *lPartnerOperatingSegmentDate_ptr);
00994 
00995           stdair::SegmentDate* lOperatingSegmentDate_ptr =
00996             stdair::BomRetriever::
00997             retrieveSegmentDateFromLongKey (ioBomRoot,
00998                                             lRoutingSegmentKey.str());
00999           assert(lOperatingSegmentDate_ptr != NULL);
01000 
01001           stdair::Inventory* lInventory_ptr =
01002             stdair::BomRetriever::
01003             retrieveInventoryFromLongKey (ioBomRoot, *itRoutingLegKey);
01004           assert (lInventory_ptr != NULL);
01005 
01006           std::ostringstream lRoutingSegment;
01007           lRoutingSegment << ioFlightDate.getAirlineCode() << ";"
01008                           << ioFlightDate.describeKey() << ";"
01009                           << lCurrentSegmentDate_ptr->getBoardingPoint() << ";"
01010                           << lCurrentSegmentDate_ptr->getOffPoint();
01011 
01012           stdair::SegmentDate* lPartnerMarketingSegmentDate_ptr =
01013             stdair::BomRetriever::
01014             retrievePartnerSegmentDateFromLongKey (*lInventory_ptr, lRoutingSegment.str());
01015           assert(lPartnerMarketingSegmentDate_ptr  != NULL);
01016 
01017           stdair::FacBomManager::addToList (*lOperatingSegmentDate_ptr, *lPartnerMarketingSegmentDate_ptr);
01018 
01019         }
01020       }
01021     }
01022   }
01023 
01024     
01025   // ////////////////////////////////////////////////////////////////////
01026   void InventoryManager::
01027   buildSimilarSegmentCabinSets (const stdair::BomRoot& iBomRoot) {
01028     // Browse the list of inventories and create direct accesses
01029     // within each inventory.
01030     const stdair::InventoryList_T& lInvList =
01031       stdair::BomManager::getList<stdair::Inventory> (iBomRoot);
01032     for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
01033          itInv != lInvList.end(); ++itInv) {
01034       stdair::Inventory* lCurrentInv_ptr = *itInv;
01035       assert (lCurrentInv_ptr != NULL);
01036 
01037       buildSimilarSegmentCabinSets (*lCurrentInv_ptr);
01038     }
01039   }
01040     
01041   // ////////////////////////////////////////////////////////////////////
01042   void InventoryManager::
01043   buildSimilarSegmentCabinSets (stdair::Inventory& ioInventory) {
01044     // For instance, we consider two flight-dates are
01045     // similar if they have the same flight number and the same
01046     // day-of-the-week departure.
01047 
01048     // Browse the segment-cabin list and build the sets of segment-cabin
01049     // which have the same flight number and origin-destination
01050     SimilarSegmentCabinSetMap_T lSSCSM;
01051 
01052     // Browsing the flight-date list
01053     const stdair::FlightDateList_T& lFlightDateList =
01054       stdair::BomManager::getList<stdair::FlightDate> (ioInventory);
01055     for (stdair::FlightDateList_T::const_iterator itFD= lFlightDateList.begin();
01056          itFD != lFlightDateList.end(); ++itFD) {
01057       const stdair::FlightDate* lFD_ptr = *itFD;
01058       assert (lFD_ptr != NULL);
01059       const stdair::FlightNumber_T& lFlightNumber = lFD_ptr->getFlightNumber();
01060 
01061       // Browsing the segment-date list and retrieve the departure
01062       // date, the origine and the destination of the segment
01063       const stdair::SegmentDateList_T& lSegmentDateList =
01064         stdair::BomManager::getList<stdair::SegmentDate> (*lFD_ptr);
01065       for (stdair::SegmentDateList_T::const_iterator itSD =
01066              lSegmentDateList.begin(); itSD != lSegmentDateList.end(); ++itSD) {
01067         const stdair::SegmentDate* lSD_ptr = *itSD;
01068         assert (lSD_ptr != NULL);
01069 
01070         const stdair::Date_T& lDepartureDate = lSD_ptr->getBoardingDate();
01071         const stdair::AirportCode_T& lOrigin = lSD_ptr->getBoardingPoint();
01072         const stdair::AirportCode_T& lDestination = lSD_ptr->getOffPoint();
01073 
01074         // Browsing the segment-cabin list and retrieve the cabin code and
01075         // build the corresponding key map.
01076         const stdair::SegmentCabinList_T& lSegmentCabinList =
01077           stdair::BomManager::getList<stdair::SegmentCabin> (*lSD_ptr);
01078         for (stdair::SegmentCabinList_T::const_iterator itSC =
01079                lSegmentCabinList.begin();
01080              itSC != lSegmentCabinList.end(); ++itSC) {
01081           stdair::SegmentCabin* lSC_ptr = *itSC;
01082           assert (lSC_ptr != NULL);
01083 
01084           std::ostringstream oStr;
01085           oStr << lFlightNumber << lDepartureDate.day_of_week()
01086                << lOrigin << lDestination << lSC_ptr->getCabinCode();
01087           const std::string lMapKey = oStr.str();
01088 
01089           // Add the segment cabin to the similar segment cabin set map.
01090           SimilarSegmentCabinSetMap_T::iterator itSSCS = lSSCSM.find (lMapKey);
01091           if (itSSCS == lSSCSM.end()) {
01092             DepartureDateSegmentCabinMap_T lDDSCMap;
01093             lDDSCMap.insert (DepartureDateSegmentCabinMap_T::
01094                              value_type (lDepartureDate, lSC_ptr));
01095             lSSCSM.insert (SimilarSegmentCabinSetMap_T::
01096                            value_type (lMapKey, lDDSCMap));
01097           } else {
01098             DepartureDateSegmentCabinMap_T& lDDSCMap = itSSCS->second;
01099             lDDSCMap.insert (DepartureDateSegmentCabinMap_T::
01100                              value_type (lDepartureDate, lSC_ptr));
01101           }
01102         }
01103       }
01104     }
01105 
01106     // Initialise the segment data table.
01107     stdair::TableID_T lTableID = 1;
01108     for (SimilarSegmentCabinSetMap_T::const_iterator itSSCS = lSSCSM.begin();
01109          itSSCS != lSSCSM.end(); ++itSSCS, ++lTableID) {
01110       const DepartureDateSegmentCabinMap_T& lDDSCMap = itSSCS->second;
01111 
01112       buildSegmentSnapshotTable (ioInventory, lTableID, lDDSCMap);
01113     }    
01114   }
01115 
01116   // ////////////////////////////////////////////////////////////////////
01117   void InventoryManager::
01118   buildSegmentSnapshotTable (stdair::Inventory& ioInventory,
01119                              const stdair::TableID_T& iTableID,
01120                              const DepartureDateSegmentCabinMap_T& iDDSCMap) {
01121     // Build an empty segment data table.
01122     const stdair::SegmentSnapshotTableKey lKey (iTableID);
01123     stdair::SegmentSnapshotTable& lSegmentSnapshotTable =
01124       stdair::FacBom<stdair::SegmentSnapshotTable>::instance().create (lKey);
01125     stdair::FacBomManager::addToListAndMap (ioInventory, lSegmentSnapshotTable);
01126 
01127     // Build the value type index map.
01128     DepartureDateSegmentCabinMap_T::const_iterator itDDSC = iDDSCMap.begin();
01129     assert (itDDSC != iDDSCMap.end());
01130     const stdair::SegmentCabin* lSegmentCabin_ptr = itDDSC->second;
01131     
01132     // Browse the booking class list and build the value type for the classes
01133     // as well as for the cabin (Q-equivalent).
01134     stdair::ClassIndexMap_T lClassIndexMap;
01135     stdair::ClassIndex_T lClassIndex = 0;
01136     std::ostringstream lSCMapKey;
01137     lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
01138               << lSegmentCabin_ptr->describeKey();
01139     lClassIndexMap.insert (stdair::ClassIndexMap_T::
01140                                value_type (lSCMapKey.str(), lClassIndex));
01141     ++lClassIndex;
01142     
01143     // Browse the booking class list
01144     const stdair::BookingClassList_T& lBCList =
01145       stdair::BomManager::getList<stdair::BookingClass>(*lSegmentCabin_ptr);
01146     for (stdair::BookingClassList_T::const_iterator itBC= lBCList.begin();
01147          itBC != lBCList.end(); ++itBC) {
01148       const stdair::BookingClass* lBookingClass_ptr = *itBC;
01149       assert (lBookingClass_ptr != NULL);
01150       lClassIndexMap.
01151         insert (stdair::ClassIndexMap_T::
01152                 value_type(lBookingClass_ptr->describeKey(),lClassIndex));
01153       ++lClassIndex;
01154     }
01155 
01156     // Build the segment-cabin index map
01157     stdair::SegmentCabinIndexMap_T lSegmentCabinIndexMap;
01158     stdair::SegmentDataID_T lSegmentDataID = 0;
01159     for (; itDDSC != iDDSCMap.end(); ++itDDSC, ++lSegmentDataID) {
01160       stdair::SegmentCabin* lCurrentSC_ptr = itDDSC->second;
01161       assert (lCurrentSC_ptr != NULL);
01162       lSegmentCabinIndexMap.
01163         insert (stdair::SegmentCabinIndexMap_T::value_type (lCurrentSC_ptr,
01164                                                             lSegmentDataID));
01165 
01166       // Added the data table to the segment-cabin.
01167       lCurrentSC_ptr->setSegmentSnapshotTable (lSegmentSnapshotTable);
01168     }
01169 
01170     // Initialise the segment data table.
01171     lSegmentSnapshotTable.initSnapshotBlocks(lSegmentCabinIndexMap,
01172                                              lClassIndexMap);
01173   }
01174 
01175   // ////////////////////////////////////////////////////////////////////
01176   void InventoryManager::initSnapshotEvents (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr,
01177                                              const stdair::Date_T& iStartDate,
01178                                              const stdair::Date_T& iEndDate) {
01179     const stdair::Duration_T lTimeZero (0, 0, 0);
01180     const stdair::Duration_T lOneDayDuration (24, 0, 0);
01181     const stdair::DateTime_T lBeginSnapshotTime (iStartDate, lTimeZero);
01182     const stdair::DateTime_T lEndSnapshotTime (iEndDate, lTimeZero);
01183 
01184     // TODO: remove the defaut airline code.
01185     stdair::NbOfEvents_T lNbOfSnapshots = 0.0;
01186     for (stdair::DateTime_T lSnapshotTime = lBeginSnapshotTime;
01187          lSnapshotTime < lEndSnapshotTime; lSnapshotTime += lOneDayDuration) {
01188       // Create the snapshot event structure
01189       stdair::SnapshotPtr_T lSnapshotStruct =
01190         boost::make_shared<stdair::SnapshotStruct>(stdair::DEFAULT_AIRLINE_CODE,
01191                                                    lSnapshotTime);
01192       // Create the event structure
01193       stdair::EventStruct lEventStruct (stdair::EventType::SNAPSHOT,
01194                                         lSnapshotStruct);
01195 
01203     ioSEVMGR_ServicePtr->addEvent (lEventStruct);
01204     ++lNbOfSnapshots;
01205     }
01206 
01207     // Update the status of snap shots within the event queue.
01208     ioSEVMGR_ServicePtr->addStatus (stdair::EventType::SNAPSHOT, lNbOfSnapshots);
01209   }
01210 
01211   // ////////////////////////////////////////////////////////////////////
01212   void InventoryManager::
01213   initRMEvents (const stdair::Inventory& iInventory,
01214                 stdair::RMEventList_T& ioRMEventList,
01215                 const stdair::Date_T& iStartDate,
01216                 const stdair::Date_T& iEndDate) {
01217     const stdair::Duration_T lTimeZero (0, 0, 0);
01218     const stdair::Duration_T lTime (0, 0, 10);
01219     const stdair::Duration_T lOneDayDuration (24, 0, 0);
01220     const stdair::DateTime_T lEarliestEventTime (iStartDate, lTimeZero);
01221     const stdair::DateTime_T lLatestEventTime (iEndDate, lTimeZero);
01222 
01223     const stdair::AirlineCode_T& lAirlineCode = iInventory.getAirlineCode();
01224 
01225     // Browse the list of flight-dates and initialise the RM events for
01226     // each flight-date.
01227     const stdair::FlightDateList_T& lFDList =
01228       stdair::BomManager::getList<stdair::FlightDate> (iInventory);
01229     for (stdair::FlightDateList_T::const_iterator itFD = lFDList.begin();
01230          itFD != lFDList.end(); ++itFD) {
01231       const stdair::FlightDate* lFD_ptr = *itFD;
01232       assert (lFD_ptr != NULL);
01233 
01234       // Retrive the departure date and initialise the RM events with
01235       // the data collection points of the inventory.
01236       const stdair::Date_T& lDepartureDate = lFD_ptr->getDepartureDate();
01237       const stdair::DateTime_T lDepatureDateTime (lDepartureDate, lTime);
01238       for (stdair::DCPList_T::const_iterator itDCP =
01239              stdair::DEFAULT_DCP_LIST.begin();
01240            itDCP != stdair::DEFAULT_DCP_LIST.end(); ++itDCP) {
01241         const stdair::DCP_T& lDCP = *itDCP;
01242 
01243         // Create the event time and check if it is in the validate interval
01244         const stdair::DateTime_T lEventTime =
01245           lDepatureDateTime - lOneDayDuration * lDCP;
01246         if (lEventTime >= lEarliestEventTime && lEventTime <= lLatestEventTime){
01247           const stdair::KeyDescription_T lKeyDes = lFD_ptr->describeKey();
01248           stdair::RMEventStruct lRMEvent (lAirlineCode, lKeyDes, lEventTime);
01249           ioRMEventList.push_back (lRMEvent);
01250         }
01251       }      
01252     }
01253   }
01254 
01255   // ////////////////////////////////////////////////////////////////////
01256   void InventoryManager::
01257   addRMEventsToEventQueue (SEVMGR::SEVMGR_ServicePtr_T ioSEVMGR_ServicePtr,
01258                            stdair::RMEventList_T& ioRMEventList) {
01259     // Browse the RM event list and add them to the queue.
01260     for (stdair::RMEventList_T::iterator itRMEvent = ioRMEventList.begin();
01261          itRMEvent != ioRMEventList.end(); ++itRMEvent) {
01262       stdair::RMEventStruct& lRMEvent = *itRMEvent;
01263       stdair::RMEventPtr_T lRMEventPtr =
01264         boost::make_shared<stdair::RMEventStruct> (lRMEvent);
01265       stdair::EventStruct lEventStruct (stdair::EventType::RM, lRMEventPtr);
01266       ioSEVMGR_ServicePtr->addEvent (lEventStruct);
01267     }
01268 
01269     // Update the status of RM events within the event queue. 
01270     const stdair::Count_T lRMEventListSize = ioRMEventList.size();
01271     ioSEVMGR_ServicePtr->addStatus (stdair::EventType::RM, lRMEventListSize);  
01272 
01273   }
01274 
01275   // ////////////////////////////////////////////////////////////////////
01276   void InventoryManager::
01277   initialiseYieldBasedNestingStructures (const stdair::BomRoot& iBomRoot) {
01278     // DEBUG
01279     STDAIR_LOG_DEBUG ("Initialise the yield-based nesting structure for "
01280                       << "all segment-cabins");
01281     
01282     // Browse the list of inventories
01283     const stdair::InventoryList_T& lInvList =
01284       stdair::BomManager::getList<stdair::Inventory> (iBomRoot);
01285     
01286     // Browse the inventories
01287     for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
01288          itInv != lInvList.end(); ++itInv) {
01289       stdair::Inventory* lCurrentInv_ptr = *itInv;
01290       assert (lCurrentInv_ptr != NULL);
01291       const stdair::FlightDateList_T& lFlightDateList =
01292         stdair::BomManager::getList<stdair::FlightDate> (*lCurrentInv_ptr);
01293       
01294       // Browse the flight dates
01295       for (stdair::FlightDateList_T::const_iterator itFD =
01296              lFlightDateList.begin(); itFD != lFlightDateList.end(); ++itFD) {
01297         const stdair::FlightDate* lFD_ptr = *itFD;
01298         assert (lFD_ptr != NULL);
01299         const stdair::SegmentDateList_T& lSegmentDateList =
01300           stdair::BomManager::getList<stdair::SegmentDate> (*lFD_ptr);
01301         
01302         // Browse the segment dates
01303         for (stdair::SegmentDateList_T::const_iterator itSD =
01304              lSegmentDateList.begin(); itSD != lSegmentDateList.end(); ++itSD) {
01305           const stdair::SegmentDate* lSD_ptr = *itSD;
01306           assert (lSD_ptr != NULL);
01307           const stdair::SegmentCabinList_T& lSegmentCabinList =
01308             stdair::BomManager::getList<stdair::SegmentCabin> (*lSD_ptr);
01309           
01310           // Browse the segment cabins
01311           for (stdair::SegmentCabinList_T::const_iterator itSC =
01312                lSegmentCabinList.begin(); itSC != lSegmentCabinList.end();
01313                ++itSC) {
01314             stdair::SegmentCabin* lSC_ptr = *itSC;
01315             assert (lSC_ptr != NULL);
01316             
01317             // Initialise the nesting structure of the segment cabin
01318             SegmentCabinHelper::initYieldBasedNestingStructure (*lSC_ptr);
01319           }
01320         }
01321       }
01322     }
01323   }
01324   
01325   // ////////////////////////////////////////////////////////////////////
01326   void InventoryManager::
01327   initialiseListsOfUsablePolicies (const stdair::BomRoot& iBomRoot) {
01328     // Browse the list of inventories
01329     const stdair::InventoryList_T& lInvList =
01330       stdair::BomManager::getList<stdair::Inventory> (iBomRoot);
01331     
01332     // Browse the inventories
01333     for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
01334          itInv != lInvList.end(); ++itInv) {
01335       stdair::Inventory* lCurrentInv_ptr = *itInv;
01336       assert (lCurrentInv_ptr != NULL);
01337 
01338       // Create the policies if the optimisation method uses Marginal
01339       // Revenue Transformation
01340       stdair::PreOptimisationMethod::EN_PreOptimisationMethod lPreOptMethod =
01341         lCurrentInv_ptr->getPreOptimisationMethod();
01342 
01343       if (lPreOptMethod == stdair::PreOptimisationMethod::MRT) {
01344         const stdair::FlightDateList_T& lFlightDateList =
01345           stdair::BomManager::getList<stdair::FlightDate> (*lCurrentInv_ptr);
01346       
01347         // Browse the flight dates
01348         for (stdair::FlightDateList_T::const_iterator itFD =
01349                lFlightDateList.begin(); itFD != lFlightDateList.end(); ++itFD) {
01350           const stdair::FlightDate* lFD_ptr = *itFD;
01351           assert (lFD_ptr != NULL);
01352           const stdair::SegmentDateList_T& lSegmentDateList =
01353             stdair::BomManager::getList<stdair::SegmentDate> (*lFD_ptr);
01354         
01355           // Browse the segment dates
01356           for (stdair::SegmentDateList_T::const_iterator itSD =
01357                  lSegmentDateList.begin();
01358                itSD != lSegmentDateList.end(); ++itSD) {
01359             const stdair::SegmentDate* lSD_ptr = *itSD;
01360             assert (lSD_ptr != NULL);
01361             const stdair::SegmentCabinList_T& lSegmentCabinList =
01362               stdair::BomManager::getList<stdair::SegmentCabin> (*lSD_ptr);
01363           
01364             // Browse the segment cabins
01365             for (stdair::SegmentCabinList_T::const_iterator itSC =
01366                    lSegmentCabinList.begin(); itSC != lSegmentCabinList.end();
01367                  ++itSC) {
01368               stdair::SegmentCabin* lSC_ptr = *itSC;
01369               assert (lSC_ptr != NULL);
01370 
01371               if (lSC_ptr->getFareFamilyStatus() == true) {
01372                 // Initialise the nesting structure of the segment cabin
01373                 SegmentCabinHelper::initListOfUsablePolicies (*lSC_ptr);
01374               }
01375             }
01376           }
01377         }
01378       }
01379     }
01380   }
01381 
01382 }