AirInv Logo  0.1.2
C++ Simulated Airline Inventory Management System library
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/GuillotineBlock.hpp>
00024 #include <stdair/bom/TravelSolutionStruct.hpp>
00025 #include <stdair/bom/FareOptionStruct.hpp>
00026 #include <stdair/bom/EventStruct.hpp>
00027 #include <stdair/bom/EventQueue.hpp>
00028 #include <stdair/bom/SnapshotStruct.hpp>
00029 #include <stdair/bom/RMEventStruct.hpp>
00030 #include <stdair/factory/FacBomManager.hpp>
00031 #include <stdair/factory/FacBom.hpp>
00032 #include <stdair/service/Logger.hpp>
00033 #include <stdair/bom/FareFamily.hpp> // Contains the definition of FareFamilyList_T
00034 #include <stdair/bom/BookingClass.hpp> //
00035 // AirInv
00036 #include <airinv/AIRINV_Types.hpp>
00037 #include <airinv/bom/BomRootHelper.hpp>
00038 #include <airinv/bom/InventoryHelper.hpp>
00039 #include <airinv/bom/FlightDateHelper.hpp>
00040 #include <airinv/command/InventoryManager.hpp>
00041 
00042 namespace AIRINV {
00043 
00044   // ////////////////////////////////////////////////////////////////////
00045   void InventoryManager::
00046   calculateAvailability (const stdair::BomRoot& iBomRoot,
00047                          stdair::TravelSolutionStruct& ioTravelSolution,
00048                          const stdair::PartnershipTechnique& iPartnershipTechnique) {
00049 
00050     const stdair::PartnershipTechnique::EN_PartnershipTechnique& lPartnershipTechnique =
00051       iPartnershipTechnique.getTechnique();
00052     
00053     // Browse the list of segments and get the availability for the
00054     // children classes.
00055     const stdair::SegmentPath_T& lSegmentPath =
00056       ioTravelSolution.getSegmentPath();
00057     for (stdair::SegmentPath_T::const_iterator itSK = lSegmentPath.begin();
00058          itSK != lSegmentPath.end(); ++itSK) {
00059       const std::string& lSegmentKey = *itSK;
00060       const stdair::InventoryKey lInvKey =
00061         stdair::BomKeyManager::extractInventoryKey (lSegmentKey);
00062       stdair::Inventory& lInventory =
00063         stdair::BomManager::getObject<stdair::Inventory>(iBomRoot,
00064                                                          lInvKey.toString());
00065 
00066       switch (lPartnershipTechnique) {
00067 
00068       case stdair::PartnershipTechnique::NONE:{
00069         InventoryHelper::calculateAvailability (lInventory, lSegmentKey,
00070                                                 ioTravelSolution);
00071         break;
00072       }
00073       default:{
00074         InventoryHelper::getYieldAndBidPrice (lInventory, lSegmentKey,
00075                                               ioTravelSolution);
00076         break;
00077       }
00078       }
00079     }
00080 
00081     switch (lPartnershipTechnique) {
00082     case stdair::PartnershipTechnique::NONE:{
00083       // Compute the availabitliy for each fare option using the AU's.
00084       calculateAvailabilityByAU (ioTravelSolution);
00085       break;
00086     }
00087     case stdair::PartnershipTechnique::RAE_DA:
00088     case stdair::PartnershipTechnique::RAE_YP:{ 
00089       // 1. Compute the availability for each fare option using RAE
00090       calculateAvailabilityByRAE (ioTravelSolution);
00091       break;
00092     }
00093     case stdair::PartnershipTechnique::IBP_DA:
00094     case stdair::PartnershipTechnique::IBP_YP:{
00095       // 2. Compute the availability for each fare option using protective IBP
00096       calculateAvailabilityByProtectiveIBP (ioTravelSolution);
00097       break;
00098     }
00099     case stdair::PartnershipTechnique::IBP_YP_U:
00100     case stdair::PartnershipTechnique::RMC:
00101     case stdair::PartnershipTechnique::A_RMC:{
00102       // 3. Compute the availability for each fare option using IBP
00103       calculateAvailabilityByIBP (ioTravelSolution);
00104       break;
00105     }
00106     default: {
00107       assert (false);
00108       break;
00109     }
00110     }
00111   }
00112 
00113   // ////////////////////////////////////////////////////////////////////
00114   void InventoryManager::
00115   calculateAvailabilityByAU (stdair::TravelSolutionStruct& ioTravelSolution) {
00116 
00117     // MODIF: segment path string for availability display
00118     std::ostringstream oStr;
00119     const stdair::SegmentPath_T& lSP = ioTravelSolution.getSegmentPath();
00120     for (stdair::SegmentPath_T::const_iterator itSP = lSP.begin();
00121          itSP != lSP.end(); itSP++) {
00122       oStr << *itSP << ";";
00123     }
00124 
00125     // Browse the fare options
00126     stdair::FareOptionList_T& lFOList = ioTravelSolution.getFareOptionListRef();
00127     for (stdair::FareOptionList_T::iterator itFO = lFOList.begin();
00128          itFO != lFOList.end(); ++itFO) {
00129 
00130       stdair::FareOptionStruct& lFO = *itFO;
00131       
00132       // Check the availability
00133       const stdair::ClassList_StringList_T& lClassPath = lFO.getClassPath();
00134       
00135       const stdair::ClassAvailabilityMapHolder_T& lClassAvailabilityMapHolder =
00136         ioTravelSolution.getClassAvailabilityMapHolder();
00137       
00138       // Initialise the flag stating whether the availability is enough
00139       stdair::Availability_T lAvl =
00140         std::numeric_limits<stdair::Availability_T>::max();
00141       
00142       // Sanity check: the travel solution must contain two lists,
00143       // one for the booking class availabilities, the other for the
00144       // fare options.
00145       assert (lClassAvailabilityMapHolder.empty() == false
00146               && lClassPath.empty() == false);
00147       
00148       // List of booking class availability maps (one map per segment)
00149       stdair::ClassAvailabilityMapHolder_T::const_iterator itCAMH =
00150         lClassAvailabilityMapHolder.begin();
00151       
00152       // List of fare options
00153       stdair::ClassList_StringList_T::const_iterator itClassList =
00154         lClassPath.begin();
00155       
00156       // Browse both lists at the same time, i.e., one element per segment
00157       for (; itCAMH != lClassAvailabilityMapHolder.end()
00158              && itClassList != lClassPath.end(); ++itCAMH, ++itClassList) {
00159         
00160         // Retrieve the booking class list for the current segment
00161         const stdair::ClassList_String_T& lCurrentClassList = *itClassList;
00162         assert (lCurrentClassList.size() > 0);
00163         
00164         // TODO: instead of just extracting the first booking class,
00165         //       perform a choice on the full list of classes.
00166         // Extract one booking class key (class code)
00167         stdair::ClassCode_T lFirstClass;
00168         lFirstClass.append (lCurrentClassList, 0, 1);
00169         
00170         // Retrieve the booking class map for the current segment
00171         const stdair::ClassAvailabilityMap_T& lClassAvlMap = *itCAMH;
00172         
00173         // Retrieve the availability of the chosen booking class
00174         const stdair::ClassAvailabilityMap_T::const_iterator itClassAvl =
00175           lClassAvlMap.find (lFirstClass);
00176         
00177         if (itClassAvl == lClassAvlMap.end()) {
00178           // DEBUG
00179           STDAIR_LOG_DEBUG ("No availability has been set up for the class '"
00180                             << lFirstClass << "'. Travel solution: "
00181                             << ioTravelSolution.display());
00182         }
00183         assert (itClassAvl != lClassAvlMap.end());
00184         
00185         const stdair::Availability_T& lCurrentAvl = itClassAvl->second;
00186         if (lAvl > lCurrentAvl) {
00187           lAvl = lCurrentAvl;
00188         }
00189       }
00190       
00191       lFO.setAvailability (lAvl);
00192 
00193       //MODIF: availability display
00194       STDAIR_LOG_DEBUG ("Fare option " << lFO.describe() << ", "
00195                         << "Availability " << lFO.getAvailability() << ", "
00196                         << "Segment Path " << oStr.str());
00197     }
00198   }
00199 
00200   // \todo: the following code must be either re-written or removed.
00201   //        There is indeed a lot of code duplication.
00202   // ////////////////////////////////////////////////////////////////////
00203   void InventoryManager::
00204   calculateAvailabilityByRAE (stdair::TravelSolutionStruct& ioTravelSolution) {
00205     
00206     std::ostringstream oStr;
00207     const stdair::SegmentPath_T& lSP = ioTravelSolution.getSegmentPath();
00208     for (stdair::SegmentPath_T::const_iterator itSP = lSP.begin();
00209          itSP != lSP.end(); itSP++) {
00210       oStr << *itSP << ";";
00211     }
00212 
00213     //Retrieve bid price vector and yield maps
00214     const stdair::ClassYieldMapHolder_T& lClassYieldMapHolder =
00215       ioTravelSolution.getClassYieldMapHolder();
00216     const stdair::ClassBpvMapHolder_T& lClassBpvMapHolder =
00217       ioTravelSolution.getClassBpvMapHolder();
00218 
00219     //Retrieve the list of fare options and browse it
00220     stdair::FareOptionList_T& lFOList = ioTravelSolution.getFareOptionListRef();
00221     for (stdair::FareOptionList_T::iterator itFO = lFOList.begin();
00222          itFO != lFOList.end(); ++itFO) {
00223 
00224       stdair::FareOptionStruct& lFO = *itFO;
00225   
00226       stdair::ClassYieldMapHolder_T::const_iterator itCYM =
00227         lClassYieldMapHolder.begin();
00228       stdair::ClassBpvMapHolder_T::const_iterator itCBPM =
00229         lClassBpvMapHolder.begin();
00230 
00231       const stdair::ClassList_StringList_T& lClassPath = lFO.getClassPath();
00232 
00233       
00234       // Sanity checks
00235       assert (lClassPath.size() == lClassYieldMapHolder.size());
00236       assert (lClassPath.size() == lClassBpvMapHolder.size());
00237 
00238       // Browse class path, class-yield maps, class-(bid price vector) maps.
00239       // Each iteration corresponds to one segment.
00240 
00241       std::ostringstream oCPStr;
00242       for (stdair::ClassList_StringList_T::const_iterator itCL =
00243              lClassPath.begin();
00244            itCL != lClassPath.end(); ++itCL, ++itCYM, ++itCBPM) {
00245 
00246         // Class path determination
00247         if (itCL == lClassPath.begin()) {
00248           oCPStr << *itCL;
00249           
00250         } else {
00251           oCPStr << "-" << *itCL;
00252         }
00253 
00254         const stdair::ClassList_String_T& lCL = *itCL;
00255         stdair::ClassCode_T lCC;
00256         lCC.append (lCL, 0, 1);
00257 
00258         const stdair::ClassYieldMap_T& lCYM = *itCYM;
00259         stdair::ClassYieldMap_T::const_iterator itCCCYM = lCYM.find (lCC);
00260         assert (itCCCYM != lCYM.end());
00261 
00262         const stdair::ClassBpvMap_T& lCBPM = *itCBPM;
00263         stdair::ClassBpvMap_T::const_iterator itCCCBPM = lCBPM.find (lCC);
00264         assert (itCCCBPM != lCBPM.end());
00265 
00266         const stdair::BidPriceVector_T* lBidPriceVector_ptr = itCCCBPM->second;
00267         assert (lBidPriceVector_ptr != NULL);
00268                 
00269         // Initialization of fare option availability
00270         if (itCL == lClassPath.begin()) {
00271           lFO.setAvailability (lBidPriceVector_ptr->size());
00272         }
00273 
00274         // Availability update
00275         if (lFO.getAvailability() > 0) {
00276           
00277           //Segment availability calculation
00278           stdair::BidPriceVector_T lReverseBPV (lBidPriceVector_ptr->size());
00279           std::reverse_copy (lBidPriceVector_ptr->begin(),
00280                              lBidPriceVector_ptr->end(),
00281                              lReverseBPV.begin());
00282 
00283           const stdair::YieldValue_T& lYield = itCCCYM->second;
00284           stdair::BidPriceVector_T::const_iterator lBidPrice =
00285             std::upper_bound (lReverseBPV.begin(), lReverseBPV.end(), lYield);
00286 
00287           const stdair::Availability_T lAvl = lBidPrice - lReverseBPV.begin();
00288 
00289           // Availability update
00290           lFO.setAvailability (std::min (lFO.getAvailability(), lAvl));
00291         }
00292       }
00293                
00294       // DEBUG
00295       STDAIR_LOG_DEBUG ("Fare option: " << lFO.describe() << ", "
00296                         << "Availability: " << lFO.getAvailability() << ", "
00297                         << "Segment Path: " << oStr.str() << ", ");
00298     }
00299   }
00300   
00301   // \todo: the following code must be either re-written or removed.
00302   //        There is indeed a lot of code duplication.
00303   // ////////////////////////////////////////////////////////////////////
00304   void InventoryManager::
00305   calculateAvailabilityByIBP (stdair::TravelSolutionStruct& ioTravelSolution) {
00306     std::ostringstream oStr;
00307 
00308     // Yield valuation coefficient for multi-segment travel solutions   
00309     double alpha = 1.0;
00310 
00311     const stdair::SegmentPath_T& lSP = ioTravelSolution.getSegmentPath();
00312     for (stdair::SegmentPath_T::const_iterator itSP = lSP.begin();
00313          itSP != lSP.end(); itSP++) {
00314       oStr << *itSP << ";";
00315     }
00316 
00317     //Retrieve bid price vector and yield maps
00318     const stdair::ClassYieldMapHolder_T& lClassYieldMapHolder =
00319       ioTravelSolution.getClassYieldMapHolder();
00320     const stdair::ClassBpvMapHolder_T& lClassBpvMapHolder =
00321       ioTravelSolution.getClassBpvMapHolder();
00322 
00323     // Retrieve the list of fare options and browse it
00324     stdair::FareOptionList_T& lFOList = ioTravelSolution.getFareOptionListRef();
00325     for (stdair::FareOptionList_T::iterator itFO = lFOList.begin();
00326          itFO != lFOList.end(); ++itFO) {
00327 
00328       stdair::FareOptionStruct& lFO = *itFO;
00329   
00330       stdair::ClassYieldMapHolder_T::const_iterator itCYM =
00331         lClassYieldMapHolder.begin();
00332       stdair::ClassBpvMapHolder_T::const_iterator itCBPM =
00333         lClassBpvMapHolder.begin();
00334 
00335       const stdair::ClassList_StringList_T& lClassPath = lFO.getClassPath();
00336 
00337       // Sanity checks
00338       assert (lClassPath.size() == lClassYieldMapHolder.size());
00339       assert (lClassPath.size() == lClassBpvMapHolder.size());
00340 
00341       // Yield is taken to be equal to fare (connecting flights)
00342 
00343       // \todo: take yield instead
00344       stdair::YieldValue_T lTotalYield = lFO.getFare();
00345       // Bid price initialisation
00346       stdair::BidPrice_T lTotalBidPrice = 0;
00347 
00348       // Browse class path, class-yield maps, class-(bid price vector) maps.
00349       // Each iteration corresponds to one segment.
00350 
00351       std::ostringstream oCPStr;
00352       for (stdair::ClassList_StringList_T::const_iterator itCL =
00353              lClassPath.begin();
00354            itCL != lClassPath.end(); ++itCL, ++itCYM, ++itCBPM) {
00355 
00356         // Class path determination
00357         if (itCL == lClassPath.begin()) {
00358           oCPStr << *itCL;
00359 
00360         } else {
00361           oCPStr << "-" << *itCL;
00362         }
00363 
00364         const stdair::ClassList_String_T& lCL = *itCL;
00365         stdair::ClassCode_T lCC;
00366         lCC.append (lCL, 0, 1);
00367 
00368         const stdair::ClassYieldMap_T& lCYM = *itCYM;
00369         stdair::ClassYieldMap_T::const_iterator itCCCYM = lCYM.find (lCC);
00370         assert (itCCCYM != lCYM.end());
00371 
00372         const stdair::ClassBpvMap_T& lCBPM = *itCBPM;
00373         stdair::ClassBpvMap_T::const_iterator itCCCBPM = lCBPM.find (lCC);
00374         assert (itCCCBPM != lCBPM.end());
00375 
00376         const stdair::BidPriceVector_T* lBidPriceVector_ptr = itCCCBPM->second;
00377         assert (lBidPriceVector_ptr != NULL);
00378                 
00379         //Initialization of fare option availability
00380         if (itCL == lClassPath.begin()) {
00381           lFO.setAvailability (lBidPriceVector_ptr->size());
00382         }
00383 
00384         // Availability update
00385         if (lFO.getAvailability() > 0) {
00386           //Segment availability calculation
00387           stdair::BidPriceVector_T lReverseBPV (lBidPriceVector_ptr->size());
00388           std::reverse_copy (lBidPriceVector_ptr->begin(),
00389                              lBidPriceVector_ptr->end(), lReverseBPV.begin());
00390 
00391           const stdair::YieldValue_T& lYield = itCCCYM->second;
00392           stdair::BidPriceVector_T::const_iterator lBidPrice =
00393             std::upper_bound (lReverseBPV.begin(), lReverseBPV.end(), lYield);
00394 
00395           const stdair::Availability_T lAvl = lBidPrice - lReverseBPV.begin();
00396 
00397           // Availability update
00398           lFO.setAvailability (std::min(lFO.getAvailability(), lAvl));
00399         }
00400 
00401         // Total bid price calculation
00402         if (lBidPriceVector_ptr->size() > 0) {
00403           lTotalBidPrice += lBidPriceVector_ptr->back();          
00404 
00405         } else {
00406           lTotalBidPrice = std::numeric_limits<stdair::BidPrice_T>::max();
00407         }
00408 
00409         // Total yield calculation (has been replaced by total fare).
00410         //lTotalYield += lYield;
00411       }
00412       // Multi-segment bid price control
00413 
00414       if (lClassPath.size() > 1) {
00415         if (lFO.getAvailability() > 0) {
00416           const stdair::Availability_T lAvl =
00417             alpha * lTotalYield >= lTotalBidPrice;
00418           lFO.setAvailability (lAvl * lFO.getAvailability());
00419 
00420         } else {
00421           const stdair::Availability_T lAvl =
00422             alpha * lTotalYield >= lTotalBidPrice;
00423           lFO.setAvailability (lAvl);
00424         }
00425       
00426         // DEBUG
00427         STDAIR_LOG_DEBUG ("Class: " << oCPStr.str()
00428                           << ", " << "Yield: " << alpha*lTotalYield << ", "
00429                           << "Bid price: " << lTotalBidPrice << ", "
00430                           << "Remaining capacity: " << "Undefined" << " "
00431                           << "Segment date: " << oStr.str());
00432       }
00433          
00434       // DEBUG
00435       STDAIR_LOG_DEBUG ("Fare option " << lFO.describe() << ", "
00436                         << "Availability " << lFO.getAvailability() << ", "
00437                         << "Segment Path " << oStr.str() << ", ");
00438     }
00439   }
00440 
00441   // \todo: the following code must be either re-written or removed.
00442   //        There is indeed a lot of code duplication.
00443   // ////////////////////////////////////////////////////////////////////
00444   void InventoryManager::
00445   calculateAvailabilityByProtectiveIBP (stdair::TravelSolutionStruct& ioTravelSolution) {
00446     std::ostringstream oStr;
00447 
00448     // Yield valuation coefficient for multi-segment travel solutions   
00449     double alpha = 1.0;
00450 
00451     const stdair::SegmentPath_T& lSP = ioTravelSolution.getSegmentPath();
00452     for (stdair::SegmentPath_T::const_iterator itSP = lSP.begin();
00453          itSP != lSP.end(); itSP++) {
00454       oStr << *itSP << ";";
00455     }
00456 
00457     //Retrieve bid price vector and yield maps
00458     const stdair::ClassYieldMapHolder_T& lClassYieldMapHolder =
00459       ioTravelSolution.getClassYieldMapHolder();
00460     const stdair::ClassBpvMapHolder_T& lClassBpvMapHolder =
00461       ioTravelSolution.getClassBpvMapHolder();
00462 
00463     //Retrieve the list of fare options and browse it
00464     stdair::FareOptionList_T& lFOList = ioTravelSolution.getFareOptionListRef();
00465     for (stdair::FareOptionList_T::iterator itFO = lFOList.begin();
00466          itFO != lFOList.end(); ++itFO) {
00467 
00468       stdair::FareOptionStruct& lFO = *itFO;
00469   
00470       stdair::ClassYieldMapHolder_T::const_iterator itCYM =
00471         lClassYieldMapHolder.begin();
00472       stdair::ClassBpvMapHolder_T::const_iterator itCBPM =
00473         lClassBpvMapHolder.begin();
00474 
00475       const stdair::ClassList_StringList_T& lClassPath = lFO.getClassPath();
00476 
00477       // Sanity checks
00478       assert (lClassPath.size() == lClassYieldMapHolder.size());
00479       assert (lClassPath.size() == lClassBpvMapHolder.size());
00480 
00481       // Yield is taken to be equal to fare (connecting flights)
00482       // TODO : take yield instead
00483       stdair::YieldValue_T lTotalYield = lFO.getFare();
00484       // Bid price initialisation
00485       stdair::BidPrice_T lTotalBidPrice = 0;
00486       // Maximal bid price initialisation
00487       stdair::BidPrice_T lMaxBidPrice = 0;
00488 
00489       //Browse class path, class-yield maps, class-(bid price vector) maps.
00490       //Each iteration corresponds to one segment.
00491 
00492       std::ostringstream oCPStr;
00493       for (stdair::ClassList_StringList_T::const_iterator itCL =
00494              lClassPath.begin();
00495            itCL != lClassPath.end(); ++itCL, ++itCYM, ++itCBPM) {
00496 
00497         // Class path determination
00498         if (itCL == lClassPath.begin()) {
00499           oCPStr << *itCL;
00500 
00501         } else {
00502           oCPStr << "-" << *itCL;
00503         }
00504 
00505         const stdair::ClassList_String_T& lCL = *itCL;
00506         stdair::ClassCode_T lCC;
00507         lCC.append (lCL, 0, 1);
00508 
00509         const stdair::ClassYieldMap_T& lCYM = *itCYM;
00510         stdair::ClassYieldMap_T::const_iterator itCCCYM = lCYM.find (lCC);
00511         assert (itCCCYM != lCYM.end());
00512 
00513         const stdair::YieldValue_T& lYield = itCCCYM->second;
00514         const stdair::ClassBpvMap_T& lCBPM = *itCBPM;
00515         stdair::ClassBpvMap_T::const_iterator itCCCBPM = lCBPM.find (lCC);
00516         assert (itCCCBPM != lCBPM.end());
00517 
00518         const stdair::BidPriceVector_T* lBidPriceVector_ptr = itCCCBPM->second;
00519         assert (lBidPriceVector_ptr != NULL);
00520                 
00521         // Initialization of fare option availability
00522         if (itCL == lClassPath.begin()) {
00523           lFO.setAvailability (lBidPriceVector_ptr->size());
00524         }
00525 
00526         // Availability update
00527         if (lFO.getAvailability() > 0) {
00528           
00529           //Segment availability calculation
00530           stdair::BidPriceVector_T lReverseBPV (lBidPriceVector_ptr->size());
00531           std::reverse_copy (lBidPriceVector_ptr->begin(),
00532                              lBidPriceVector_ptr->end(), lReverseBPV.begin());
00533 
00534           stdair::BidPriceVector_T::const_iterator lBidPrice =
00535             std::upper_bound (lReverseBPV.begin(), lReverseBPV.end(), lYield);
00536 
00537           const stdair::Availability_T lAvl = lBidPrice - lReverseBPV.begin();
00538           
00539           // Availability update
00540           lFO.setAvailability (std::min(lFO.getAvailability(), lAvl));
00541      
00542         }
00543 
00544         // Total bid price calculation
00545         if (lBidPriceVector_ptr->size() > 0) {
00546           lTotalBidPrice += lBidPriceVector_ptr->back();
00547 
00548           if (lMaxBidPrice < lBidPriceVector_ptr->back()) {
00549             lMaxBidPrice = lBidPriceVector_ptr->back();
00550           }
00551           
00552         } else {
00553           lTotalBidPrice = std::numeric_limits<stdair::BidPrice_T>::max();
00554         }
00555 
00556         // Total yield calculation (has been replaced by total fare).
00557         //lTotalYield += lYield;
00558       }
00559       // Multi-segment bid price control
00560 
00561       // Protective IBP (maximin): guarantees the minimal yield for each airline
00562       // Proration factors are all equal to 1/{number of partners}.
00563 
00564       lTotalBidPrice = std::max (lMaxBidPrice * lClassPath.size(),
00565                                  lTotalBidPrice);
00566 
00567       if (lClassPath.size() > 1) {
00568         if (lFO.getAvailability() > 0) {
00569           const stdair::Availability_T lAvl =
00570             alpha * lTotalYield >= lTotalBidPrice;
00571           lFO.setAvailability (lAvl * lFO.getAvailability());
00572 
00573         } else {
00574           const stdair::Availability_T lAvl =
00575             alpha * lTotalYield >= lTotalBidPrice;
00576           lFO.setAvailability (lAvl);
00577         }
00578       
00579         // DEBUG
00580         STDAIR_LOG_DEBUG ("Class: " << oCPStr.str()
00581                           << ", " << "Yield: " << alpha*lTotalYield << ", "
00582                           << "Bid price: " << lTotalBidPrice << ", "
00583                           << "Remaining capacity: " << "Undefined" << " "
00584                           << "Segment date: " << oStr.str());
00585       }
00586 
00587       // DEBUG         
00588       STDAIR_LOG_DEBUG ("Fare option " << lFO.describe() << ", "
00589                         << "Availability " << lFO.getAvailability() << ", "
00590                         << "Segment Path " << oStr.str() << ", ");
00591     }
00592   }
00593   
00594   //MODIF
00595   // ////////////////////////////////////////////////////////////////////
00596   void InventoryManager::setDefaultBidPriceVector (stdair::BomRoot& ioBomRoot) {
00597 
00598     const stdair::InventoryList_T& lInvList =
00599       stdair::BomManager::getList<stdair::Inventory> (ioBomRoot);
00600     for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
00601          itInv != lInvList.end(); ++itInv) {
00602       stdair::Inventory* lCurrentInv_ptr = *itInv;
00603       assert (lCurrentInv_ptr != NULL);
00604 
00605       // Set the default bid price for own cabins.
00606       setDefaultBidPriceVector (*lCurrentInv_ptr);
00607 
00608       // Check if the inventory contains images of partner inventories.
00609       // If so, set the default bid price for their cabins.
00610       if (stdair::BomManager::hasList<stdair::Inventory> (*lCurrentInv_ptr)) {
00611         const stdair::InventoryList_T& lPartnerInvList =
00612           stdair::BomManager::getList<stdair::Inventory> (*lCurrentInv_ptr);
00613 
00614         for (stdair::InventoryList_T::const_iterator itPartnerInv =
00615                lPartnerInvList.begin();
00616              itPartnerInv != lPartnerInvList.end(); ++itPartnerInv) {
00617           stdair::Inventory* lCurrentPartnerInv_ptr = *itPartnerInv;
00618           assert (lCurrentPartnerInv_ptr != NULL);
00619 
00620           setDefaultBidPriceVector (*lCurrentPartnerInv_ptr);
00621         }
00622       }            
00623     }     
00624   }
00625 
00626   // ////////////////////////////////////////////////////////////////////
00627   void InventoryManager::
00628   setDefaultBidPriceVector (stdair::Inventory& ioInventory) {
00629 
00630     const stdair::FlightDateList_T& lFlightDateList =
00631       stdair::BomManager::getList<stdair::FlightDate> (ioInventory);
00632     for (stdair::FlightDateList_T::const_iterator itFlightDate =
00633            lFlightDateList.begin();
00634          itFlightDate != lFlightDateList.end(); ++itFlightDate) {
00635       stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate;
00636       assert (lCurrentFlightDate_ptr != NULL);
00637 
00638       // Check if the flight date holds a list of leg dates.
00639       // If so retrieve it and initialise the bid price vectors of their cabins.
00640       if (stdair::BomManager::hasList<stdair::LegDate> (*lCurrentFlightDate_ptr)) {
00641         const stdair::LegDateList_T& lLegDateList =
00642           stdair::BomManager::getList<stdair::LegDate> (*lCurrentFlightDate_ptr);
00643         for (stdair::LegDateList_T::const_iterator itLegDate =
00644                lLegDateList.begin();
00645              itLegDate != lLegDateList.end(); ++itLegDate) {
00646           stdair::LegDate* lCurrentLegDate_ptr = *itLegDate;
00647           assert (lCurrentLegDate_ptr != NULL);
00648           
00649           const stdair::LegCabinList_T& lLegCabinList =
00650             stdair::BomManager::getList<stdair::LegCabin> (*lCurrentLegDate_ptr);
00651           for (stdair::LegCabinList_T::const_iterator itLegCabin =
00652                  lLegCabinList.begin();
00653                itLegCabin != lLegCabinList.end(); ++itLegCabin) {
00654             stdair::LegCabin* lCurrentLegCabin_ptr = *itLegCabin;
00655             assert (lCurrentLegCabin_ptr != NULL);
00656 
00657             const stdair::CabinCapacity_T& lCabinCapacity =
00658               lCurrentLegCabin_ptr->getPhysicalCapacity();
00659             lCurrentLegCabin_ptr->emptyBidPriceVector();
00660 
00661             stdair::BidPriceVector_T& lBPV =
00662               lCurrentLegCabin_ptr->getBidPriceVector();
00663 
00664             //for (stdair::CabinCapacity_T k = 0;k!=lCabinCapacity;k++) {lBPV.push_back(400 + 300/sqrt(k+1));}
00665             for (stdair::CabinCapacity_T k = 0; k != lCabinCapacity; k++) {
00666               lBPV.push_back (400);
00667             }
00668 
00669             lCurrentLegCabin_ptr->setPreviousBidPrice (lBPV.back());
00670             lCurrentLegCabin_ptr->setCurrentBidPrice (lBPV.back());          
00671           }
00672         }
00673       }
00674     }
00675   }  
00676   
00677   // ////////////////////////////////////////////////////////////////////
00678   bool InventoryManager::sell (stdair::Inventory& ioInventory,
00679                                const std::string& iSegmentDateKey,
00680                                const stdair::ClassCode_T& iClassCode,
00681                                const stdair::PartySize_T& iPartySize) {
00682 
00683     // Make the sale within the inventory.
00684     return InventoryHelper::sell (ioInventory, iSegmentDateKey,
00685                                   iClassCode, iPartySize);
00686   }
00687 
00688   // ////////////////////////////////////////////////////////////////////
00689   bool InventoryManager::cancel (stdair::Inventory& ioInventory,
00690                                  const std::string& iSegmentDateKey,
00691                                  const stdair::ClassCode_T& iClassCode,
00692                                  const stdair::PartySize_T& iPartySize) {
00693     
00694     // Make the sale within the inventory.
00695     return InventoryHelper::cancel (ioInventory, iSegmentDateKey,
00696                                     iClassCode, iPartySize);
00697   }
00698 
00699   // ////////////////////////////////////////////////////////////////////
00700   void InventoryManager::
00701   updateBookingControls (stdair::FlightDate& ioFlightDate) {
00702 
00703     // Forward the call to FlightDateHelper.
00704     FlightDateHelper::updateBookingControls (ioFlightDate);
00705   }
00706 
00707   // ////////////////////////////////////////////////////////////////////
00708   void InventoryManager::takeSnapshots(const stdair::Inventory& iInventory,
00709                                        const stdair::DateTime_T& iSnapshotTime){
00710 
00711     // Make the snapshots within the inventory
00712     InventoryHelper::takeSnapshots (iInventory, iSnapshotTime);
00713   }
00714     
00715   // ////////////////////////////////////////////////////////////////////
00716   void InventoryManager::
00717   createDirectAccesses (const stdair::BomRoot& iBomRoot) {
00718 
00719     // Browse the list of inventories and create direct accesses
00720     // within each inventory.
00721     const stdair::InventoryList_T& lInvList =
00722       stdair::BomManager::getList<stdair::Inventory> (iBomRoot);
00723     for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
00724          itInv != lInvList.end(); ++itInv) {
00725       stdair::Inventory* lCurrentInv_ptr = *itInv;
00726       assert (lCurrentInv_ptr != NULL);
00727 
00728       createDirectAccesses (*lCurrentInv_ptr);
00729     }
00730 
00731     // Fill some attributes of segment-date with the routing legs.
00732     BomRootHelper::fillFromRouting (iBomRoot);
00733   }
00734 
00735   // ////////////////////////////////////////////////////////////////////
00736   void InventoryManager::
00737   createDirectAccesses (stdair::Inventory& ioInventory) {
00738 
00739     // Browse the list of flight-dates and create direct accesses
00740     // within each flight-date.
00741     const stdair::FlightDateList_T& lFlightDateList = 
00742       stdair::BomManager::getList<stdair::FlightDate> (ioInventory);
00743     for (stdair::FlightDateList_T::const_iterator itFlightDate = 
00744            lFlightDateList.begin();
00745          itFlightDate != lFlightDateList.end(); ++itFlightDate) {
00746       stdair::FlightDate* lCurrentFlightDate_ptr = *itFlightDate;
00747       assert (lCurrentFlightDate_ptr != NULL);
00748 
00749       createDirectAccesses (*lCurrentFlightDate_ptr);
00750     }
00751   }
00752 
00753   // ////////////////////////////////////////////////////////////////////
00754   void InventoryManager::
00755   createDirectAccesses (stdair::FlightDate& ioFlightDate) {
00756 
00757     // Browse the list of segment-dates and create direct accesses
00758     // within each segment-date.
00759     const stdair::SegmentDateList_T& lSegmentDateList = 
00760       stdair::BomManager::getList<stdair::SegmentDate> (ioFlightDate);
00761     for (stdair::SegmentDateList_T::const_iterator itSegmentDate = 
00762            lSegmentDateList.begin();
00763          itSegmentDate != lSegmentDateList.end(); ++itSegmentDate) {
00764 
00765       stdair::SegmentDate* lCurrentSegmentDate_ptr = *itSegmentDate;
00766       assert (lCurrentSegmentDate_ptr != NULL);
00767 
00768       /*
00769        * If the segment is just marketed by this carrier,
00770        * retrieve the operating segment and call the createDirectAcces
00771        * method on its parent (flight date).
00772        */
00773       const stdair::SegmentDate* lOperatingSegmentDate_ptr =
00774         lCurrentSegmentDate_ptr->getOperatingSegmentDate ();
00775       if (lOperatingSegmentDate_ptr != NULL) {
00776         // Then get the (parent) flight date and create direct access.
00777         stdair::FlightDate* lOperatingFlightDate_ptr =
00778           stdair::BomManager::getParentPtr<stdair::FlightDate>(*lOperatingSegmentDate_ptr);
00779         assert (lOperatingFlightDate_ptr != NULL);
00780         createDirectAccesses (*lOperatingFlightDate_ptr);
00781       } else {
00782 
00783         const stdair::AirportCode_T& lBoardingPoint =
00784           lCurrentSegmentDate_ptr->getBoardingPoint();
00785         
00786         stdair::AirportCode_T currentBoardingPoint = lBoardingPoint;
00787         const stdair::AirportCode_T& lOffPoint =
00788           lCurrentSegmentDate_ptr->getOffPoint();
00789         
00790         // Add a sanity check so as to ensure that the loop stops. If
00791         // there are more than MAXIMAL_NUMBER_OF_LEGS legs, there is
00792         // an issue somewhere in the code (not in the parser, as the
00793         // segments are derived from the legs thanks to the
00794         // FlightPeriodStruct::buildSegments() method).
00795         unsigned short i = 1;
00796         while (currentBoardingPoint != lOffPoint
00797                && i <= stdair::MAXIMAL_NUMBER_OF_LEGS_IN_FLIGHT) {
00798           // Retrieve the (unique) LegDate getting that Boarding Point
00799           stdair::LegDate& lLegDate = stdair::BomManager::
00800             getObject<stdair::LegDate> (ioFlightDate, currentBoardingPoint);
00801           
00802           // Link the SegmentDate and LegDate together
00803           stdair::FacBomManager::addToListAndMap (*lCurrentSegmentDate_ptr,
00804                                                   lLegDate);
00805           stdair::FacBomManager::addToListAndMap (lLegDate,
00806                                                   *lCurrentSegmentDate_ptr);
00807           
00808           // Prepare the next iteration
00809           currentBoardingPoint = lLegDate.getOffPoint();
00810           ++i;
00811         }
00812         assert (i <= stdair::MAXIMAL_NUMBER_OF_LEGS_IN_FLIGHT);
00813         
00814         // Create the routing for the leg- and segment-cabins.
00815         // At the same time, set the SegmentDate attributes derived from
00816         // its routing legs (e.g., boarding and off dates).
00817         createDirectAccesses (*lCurrentSegmentDate_ptr);
00818       }
00819     }
00820   }
00821 
00822   // ////////////////////////////////////////////////////////////////////
00823   void InventoryManager::
00824   createDirectAccesses (stdair::SegmentDate& ioSegmentDate) {
00825 
00826     // Browse the list of segment-cabins and create direct accesses
00827     // within each segment-cabin.
00828     const stdair::SegmentCabinList_T& lSegmentCabinList = 
00829       stdair::BomManager::getList<stdair::SegmentCabin> (ioSegmentDate);
00830     for (stdair::SegmentCabinList_T::const_iterator itSegmentCabin = 
00831            lSegmentCabinList.begin();
00832          itSegmentCabin != lSegmentCabinList.end(); ++itSegmentCabin) {
00833 
00834       //
00835       stdair::SegmentCabin* lCurrentSegmentCabin_ptr = *itSegmentCabin;
00836       assert (lCurrentSegmentCabin_ptr != NULL);
00837 
00838       //
00839       const stdair::CabinCode_T& lCabinCode =
00840           lCurrentSegmentCabin_ptr->getCabinCode();
00841       
00842       // Iterate on the routing legs
00843       const stdair::LegDateList_T& lLegDateList =
00844         stdair::BomManager::getList<stdair::LegDate> (ioSegmentDate);
00845       for (stdair::LegDateList_T::const_iterator itLegDate =
00846              lLegDateList.begin();
00847            itLegDate != lLegDateList.end(); ++itLegDate) {
00848 
00849         const stdair::LegDate* lCurrentLegDate_ptr = *itLegDate;        
00850         assert (lCurrentLegDate_ptr != NULL);
00851 
00852         // Retrieve the LegCabin getting the same class of service
00853         // (cabin code) as the SegmentCabin.
00854         stdair::LegCabin& lLegCabin = stdair::BomManager::
00855           getObject<stdair::LegCabin> (*lCurrentLegDate_ptr, lCabinCode);
00856 
00867         stdair::FacBomManager::addToListAndMap (*lCurrentSegmentCabin_ptr,
00868                                                 lLegCabin,
00869                                                 lLegCabin.getFullerKey());
00870 
00881         stdair::FacBomManager::
00882           addToListAndMap (lLegCabin, *lCurrentSegmentCabin_ptr,
00883                            lCurrentSegmentCabin_ptr->getFullerKey());
00884       }      
00885     }
00886   }
00887     
00888   // ////////////////////////////////////////////////////////////////////
00889   void InventoryManager::
00890   buildSimilarSegmentCabinSets (const stdair::BomRoot& iBomRoot) {
00891     // Browse the list of inventories and create direct accesses
00892     // within each inventory.
00893     const stdair::InventoryList_T& lInvList =
00894       stdair::BomManager::getList<stdair::Inventory> (iBomRoot);
00895     for (stdair::InventoryList_T::const_iterator itInv = lInvList.begin();
00896          itInv != lInvList.end(); ++itInv) {
00897       stdair::Inventory* lCurrentInv_ptr = *itInv;
00898       assert (lCurrentInv_ptr != NULL);
00899 
00900       buildSimilarSegmentCabinSets (*lCurrentInv_ptr);
00901     }
00902   }
00903     
00904   // ////////////////////////////////////////////////////////////////////
00905   void InventoryManager::
00906   buildSimilarSegmentCabinSets (stdair::Inventory& ioInventory) {
00907     // For instance, we consider two flight-dates are
00908     // similar if they have the same flight number and the same
00909     // day-of-the-week departure.
00910 
00911     // Browse the segment-cabin list and build the sets of segment-cabin
00912     // which have the same flight number and origin-destination
00913     SimilarSegmentCabinSetMap_T lSSCSM;
00914 
00915     // Browsing the flight-date list
00916     const stdair::FlightDateList_T& lFlightDateList =
00917       stdair::BomManager::getList<stdair::FlightDate> (ioInventory);
00918     for (stdair::FlightDateList_T::const_iterator itFD= lFlightDateList.begin();
00919          itFD != lFlightDateList.end(); ++itFD) {
00920       const stdair::FlightDate* lFD_ptr = *itFD;
00921       assert (lFD_ptr != NULL);
00922       const stdair::FlightNumber_T& lFlightNumber = lFD_ptr->getFlightNumber();
00923 
00924       // Browsing the segment-date list and retrieve the departure
00925       // date, the origine and the destination of the segment
00926       const stdair::SegmentDateList_T& lSegmentDateList =
00927         stdair::BomManager::getList<stdair::SegmentDate> (*lFD_ptr);
00928       for (stdair::SegmentDateList_T::const_iterator itSD =
00929              lSegmentDateList.begin(); itSD != lSegmentDateList.end(); ++itSD) {
00930         const stdair::SegmentDate* lSD_ptr = *itSD;
00931         assert (lSD_ptr != NULL);
00932 
00933         const stdair::Date_T& lDepartureDate = lSD_ptr->getBoardingDate();
00934         const stdair::AirportCode_T& lOrigin = lSD_ptr->getBoardingPoint();
00935         const stdair::AirportCode_T& lDestination = lSD_ptr->getOffPoint();
00936 
00937         // Browsing the segment-cabin list and retrieve the cabin code and
00938         // build the corresponding key map.
00939         const stdair::SegmentCabinList_T& lSegmentCabinList =
00940           stdair::BomManager::getList<stdair::SegmentCabin> (*lSD_ptr);
00941         for (stdair::SegmentCabinList_T::const_iterator itSC =
00942                lSegmentCabinList.begin();
00943              itSC != lSegmentCabinList.end(); ++itSC) {
00944           stdair::SegmentCabin* lSC_ptr = *itSC;
00945           assert (lSC_ptr != NULL);
00946 
00947           std::ostringstream oStr;
00948           oStr << lFlightNumber << lDepartureDate.day_of_week()
00949                << lOrigin << lDestination << lSC_ptr->getCabinCode();
00950           const std::string lMapKey = oStr.str();
00951 
00952           // Add the segment cabin to the similar segment cabin set map.
00953           SimilarSegmentCabinSetMap_T::iterator itSSCS = lSSCSM.find (lMapKey);
00954           if (itSSCS == lSSCSM.end()) {
00955             DepartureDateSegmentCabinMap_T lDDSCMap;
00956             lDDSCMap.insert (DepartureDateSegmentCabinMap_T::
00957                              value_type (lDepartureDate, lSC_ptr));
00958             lSSCSM.insert (SimilarSegmentCabinSetMap_T::
00959                            value_type (lMapKey, lDDSCMap));
00960           } else {
00961             DepartureDateSegmentCabinMap_T& lDDSCMap = itSSCS->second;
00962             lDDSCMap.insert (DepartureDateSegmentCabinMap_T::
00963                              value_type (lDepartureDate, lSC_ptr));
00964           }
00965         }
00966       }
00967     }
00968 
00969     // Initialise the guillotine blocks.
00970     stdair::GuillotineNumber_T lGuillotineNumber = 1;
00971     for (SimilarSegmentCabinSetMap_T::const_iterator itSSCS = lSSCSM.begin();
00972          itSSCS != lSSCSM.end(); ++itSSCS, ++lGuillotineNumber) {
00973       const DepartureDateSegmentCabinMap_T& lDDSCMap = itSSCS->second;
00974 
00975       buildGuillotineBlock (ioInventory, lGuillotineNumber, lDDSCMap);
00976     }    
00977   }
00978 
00979   // ////////////////////////////////////////////////////////////////////
00980   void InventoryManager::
00981   buildGuillotineBlock (stdair::Inventory& ioInventory,
00982                         const stdair::GuillotineNumber_T& iGuillotineNumber,
00983                         const DepartureDateSegmentCabinMap_T& iDDSCMap) {
00984     // Build an empty guillotine block.
00985     const stdair::GuillotineBlockKey lKey (iGuillotineNumber);
00986     stdair::GuillotineBlock& lGuillotineBlock =
00987       stdair::FacBom<stdair::GuillotineBlock>::instance().create (lKey);
00988     stdair::FacBomManager::addToListAndMap (ioInventory, lGuillotineBlock);
00989 
00990     // Build the value type index map.
00991     DepartureDateSegmentCabinMap_T::const_iterator itDDSC = iDDSCMap.begin();
00992     assert (itDDSC != iDDSCMap.end());
00993     const stdair::SegmentCabin* lSegmentCabin_ptr = itDDSC->second;
00994     
00995     // Browse the booking class list and build the value type for the classes
00996     // as well as for the cabin (Q-equivalent).
00997     stdair::ValueTypeIndexMap_T lValueTypeIndexMap;
00998     stdair::BlockIndex_T lBlockIndex = 0;
00999     std::ostringstream lSCMapKey;
01000     lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
01001               << lSegmentCabin_ptr->describeKey();
01002     lValueTypeIndexMap.insert (stdair::ValueTypeIndexMap_T::
01003                                value_type (lSCMapKey.str(), lBlockIndex));
01004     ++lBlockIndex;
01005     
01006     // Browse the booking class list
01007     const stdair::BookingClassList_T& lBCList =
01008       stdair::BomManager::getList<stdair::BookingClass>(*lSegmentCabin_ptr);
01009     for (stdair::BookingClassList_T::const_iterator itBC= lBCList.begin();
01010          itBC != lBCList.end(); ++itBC) {
01011       const stdair::BookingClass* lBookingClass_ptr = *itBC;
01012       assert (lBookingClass_ptr != NULL);
01013       lValueTypeIndexMap.
01014         insert (stdair::ValueTypeIndexMap_T::
01015                 value_type(lBookingClass_ptr->describeKey(),lBlockIndex));
01016       ++lBlockIndex;
01017     }
01018 
01019     // Build the segment-cabin index map
01020     stdair::SegmentCabinIndexMap_T lSegmentCabinIndexMap;
01021     stdair::BlockNumber_T lBlockNumber = 0;
01022     for (; itDDSC != iDDSCMap.end(); ++itDDSC, ++lBlockNumber) {
01023       stdair::SegmentCabin* lCurrentSC_ptr = itDDSC->second;
01024       assert (lCurrentSC_ptr != NULL);
01025       lSegmentCabinIndexMap.
01026         insert (stdair::SegmentCabinIndexMap_T::value_type (lCurrentSC_ptr,
01027                                                             lBlockNumber));
01028 
01029       // Added the guillotine to the segment-cabin.
01030       lCurrentSC_ptr->setGuillotineBlock (lGuillotineBlock);
01031     }
01032 
01033     // Initialise the guillotine block.
01034     lGuillotineBlock.initSnapshotBlocks(lSegmentCabinIndexMap,
01035                                         lValueTypeIndexMap);
01036   }
01037 
01038   // ////////////////////////////////////////////////////////////////////
01039   void InventoryManager::initSnapshotEvents (const stdair::Date_T& iStartDate,
01040                                              const stdair::Date_T& iEndDate,
01041                                              stdair::EventQueue& ioQueue) {
01042     const stdair::Duration_T lTimeZero (0, 0, 0);
01043     const stdair::Duration_T lOneDayDuration (24, 0, 0);
01044     const stdair::DateTime_T lBeginSnapshotTime (iStartDate, lTimeZero);
01045     const stdair::DateTime_T lEndSnapshotTime (iEndDate, lTimeZero);
01046 
01047     // TODO: remove the defaut airline code.
01048     stdair::NbOfEvents_T lNbOfSnapshots = 0.0;
01049     for (stdair::DateTime_T lSnapshotTime = lBeginSnapshotTime;
01050          lSnapshotTime < lEndSnapshotTime; lSnapshotTime += lOneDayDuration) {
01051       // Create the snapshot event structure
01052       stdair::SnapshotPtr_T lSnapshotStruct =
01053         boost::make_shared<stdair::SnapshotStruct>(stdair::DEFAULT_AIRLINE_CODE,
01054                                                    lSnapshotTime);
01055       // Create the event structure
01056       stdair::EventStruct lEventStruct (stdair::EventType::SNAPSHOT,
01057                                         lSnapshotStruct);
01058 
01066     ioQueue.addEvent (lEventStruct);
01067     ++lNbOfSnapshots;
01068     }
01069 
01070     ioQueue.addStatus (stdair::EventType::SNAPSHOT, lNbOfSnapshots);
01071   }
01072 
01073   // ////////////////////////////////////////////////////////////////////
01074   void InventoryManager::
01075   initRMEvents (const stdair::Inventory& iInventory,
01076                 stdair::RMEventList_T& ioRMEventList,
01077                 const stdair::Date_T& iStartDate,
01078                 const stdair::Date_T& iEndDate) {
01079     const stdair::Duration_T lTimeZero (0, 0, 0);
01080     const stdair::Duration_T lTime (0, 0, 10);
01081     const stdair::Duration_T lOneDayDuration (24, 0, 0);
01082     const stdair::DateTime_T lEarliestEventTime (iStartDate, lTimeZero);
01083     const stdair::DateTime_T lLatestEventTime (iEndDate, lTimeZero);
01084 
01085     const stdair::AirlineCode_T& lAirlineCode = iInventory.getAirlineCode();
01086 
01087     // Browse the list of flight-dates and initialise the RM events for
01088     // each flight-date.
01089     const stdair::FlightDateList_T& lFDList =
01090       stdair::BomManager::getList<stdair::FlightDate> (iInventory);
01091     for (stdair::FlightDateList_T::const_iterator itFD = lFDList.begin();
01092          itFD != lFDList.end(); ++itFD) {
01093       const stdair::FlightDate* lFD_ptr = *itFD;
01094       assert (lFD_ptr != NULL);
01095 
01096       // Retrive the departure date and initialise the RM events with
01097       // the data collection points of the inventory.
01098       const stdair::Date_T& lDepartureDate = lFD_ptr->getDepartureDate();
01099       const stdair::DateTime_T lDepatureDateTime (lDepartureDate, lTime);
01100       for (stdair::DCPList_T::const_iterator itDCP =
01101              stdair::DEFAULT_DCP_LIST.begin();
01102            itDCP != stdair::DEFAULT_DCP_LIST.end(); ++itDCP) {
01103         const stdair::DCP_T& lDCP = *itDCP;
01104 
01105         // Create the event time and check if it is in the validate interval
01106         const stdair::DateTime_T lEventTime =
01107           lDepatureDateTime - lOneDayDuration * lDCP;
01108         if (lEventTime >= lEarliestEventTime && lEventTime <= lLatestEventTime){
01109           const stdair::KeyDescription_T lKeyDes = lFD_ptr->describeKey();
01110           stdair::RMEventStruct lRMEvent (lAirlineCode, lKeyDes, lEventTime);
01111           ioRMEventList.push_back (lRMEvent);
01112         }
01113       }      
01114     }
01115   }
01116 
01117   // ////////////////////////////////////////////////////////////////////
01118   void InventoryManager::
01119   addRMEventsToEventQueue (stdair::EventQueue& ioQueue,
01120                            stdair::RMEventList_T& ioRMEventList) {
01121     // Browse the RM event list and add them to the queue.
01122     for (stdair::RMEventList_T::iterator itRMEvent = ioRMEventList.begin();
01123          itRMEvent != ioRMEventList.end(); ++itRMEvent) {
01124       stdair::RMEventStruct& lRMEvent = *itRMEvent;
01125       stdair::RMEventPtr_T lRMEventPtr =
01126         boost::make_shared<stdair::RMEventStruct> (lRMEvent);
01127       stdair::EventStruct lEventStruct (stdair::EventType::RM, lRMEventPtr);
01128       ioQueue.addEvent (lEventStruct);
01129     }
01130 
01131     // Update the status of RM events within the event queue.
01132     ioQueue.updateStatus (stdair::EventType::RM, ioRMEventList.size());
01133   }
01134 }