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

rmol/bom/PolicyHelper.cpp

Go to the documentation of this file.
00001 
00002 // //////////////////////////////////////////////////////////////////////
00003 // Import section
00004 // //////////////////////////////////////////////////////////////////////
00005 // STL
00006 #include <cassert>
00007 #include <cmath>
00008 // StdAir
00009 #include <stdair/basic/BasConst_Inventory.hpp>
00010 #include <stdair/basic/BasConst_Yield.hpp>
00011 #include <stdair/bom/SegmentCabin.hpp>
00012 #include <stdair/bom/Policy.hpp>
00013 #include <stdair/bom/BookingClass.hpp>
00014 #include <stdair/bom/FareFamily.hpp>
00015 #include <stdair/bom/NestingNode.hpp>
00016 #include <stdair/bom/BomManager.hpp>
00017 #include <stdair/factory/FacBomManager.hpp>
00018 // RMOL
00019 #include <rmol/bom/PolicyHelper.hpp>
00020 
00021 namespace RMOL {
00022   // ////////////////////////////////////////////////////////////////////
00023   void PolicyHelper::
00024   diffBetweenTwoPolicies (stdair::NestingNode& ioNode,
00025                           const stdair::Policy& iFirstPolicy,
00026                           const stdair::Policy& iSecondPolicy) {
00027 
00028     // Retrieve the booking class list of the first policy
00029     const stdair::BookingClassList_T& lFirstBCList = 
00030           stdair::BomManager::getList<stdair::BookingClass> (iFirstPolicy);
00031 
00032     // Browse the booking class list
00033     for (stdair::BookingClassList_T::const_iterator itBC = lFirstBCList.begin();
00034          itBC != lFirstBCList.end(); ++itBC){
00035       const stdair::BookingClass* iFirstPolicyBC_ptr = *itBC;
00036       const stdair::BookingClassKey& lFirstPolicyBCKey = 
00037         iFirstPolicyBC_ptr->getKey();
00038       const stdair::ClassCode_T& lFirstPolicyClassCode = 
00039         lFirstPolicyBCKey.getClassCode();
00040       // Retrieve the fare family of the booking class and the list of booking 
00041       // class of this fare family
00042       const stdair::FareFamily& lFareFamily = 
00043         stdair::BomManager::getParent<stdair::FareFamily> (*iFirstPolicyBC_ptr);
00044       
00045       // Retrieve the list of booking class between the both booking classes
00046       diffBetweenBookingClassAndPolicy (ioNode, lFareFamily, 
00047                                         lFirstPolicyClassCode, 
00048                                         iSecondPolicy);
00049     }
00050   }
00051 
00052   // ////////////////////////////////////////////////////////////////////
00053   const bool PolicyHelper::
00054   intersectionBetweenPolicyAndBookingClassList (const stdair::BookingClassList_T& iBCList,
00055                                             const stdair::Policy& iPolicy,
00056                                             stdair::ClassCode_T& oClassCode) {
00057     bool isInBookingClassList = false;
00058 
00059     // Retrieve the booking classes of the policy
00060     const bool hasAListOfBC = 
00061       stdair::BomManager::hasList<stdair::BookingClass> (iPolicy);
00062     if (hasAListOfBC == false) {
00063       return isInBookingClassList;
00064     } 
00065     const stdair::BookingClassList_T& lPolicyBookingClassList =
00066       stdair::BomManager::getList<stdair::BookingClass> (iPolicy);
00067 
00068     // Browse the booking class list of the fare family
00069     stdair::BookingClassList_T::const_iterator itFFBC = iBCList.begin();
00070     for (; itFFBC != iBCList.end(); ++itFFBC) {
00071       stdair::BookingClass* lFFBC_ptr = *itFFBC;
00072       const stdair::BookingClassKey& lFFBCKey = lFFBC_ptr->getKey();
00073       const stdair::ClassCode_T& lFFClassCode = lFFBCKey.getClassCode();
00074       // Compare the booking class with booking classes of policy 
00075       stdair::BookingClassList_T::const_iterator itPolicyBC = 
00076         lPolicyBookingClassList.begin();
00077       for (; itPolicyBC != lPolicyBookingClassList.end(); ++itPolicyBC){
00078         const stdair::BookingClass* lPolicyBC_ptr = *itPolicyBC;
00079         const stdair::BookingClassKey& lPolicyBCKey = lPolicyBC_ptr->getKey();
00080         const stdair::ClassCode_T& lPolicyClassCode = 
00081           lPolicyBCKey.getClassCode();
00082         if (lPolicyClassCode == lFFClassCode) {
00083           oClassCode = lPolicyClassCode;
00084           isInBookingClassList = true;
00085           return isInBookingClassList;
00086         }
00087       }
00088     }
00089     // If the policy has not any booking class in the fare family,
00090     // return false
00091     return isInBookingClassList;
00092   }
00093 
00094   // ////////////////////////////////////////////////////////////////////
00095   void PolicyHelper::
00096   diffBetweenBookingClassAndPolicy (stdair::NestingNode& ioNode,
00097                                     const stdair::FareFamily& iFareFamily,
00098                                     const stdair::ClassCode_T& iFirstPolicyClassCode,
00099                                     const stdair::Policy& iSecondPolicy) {    
00100     const stdair::BookingClassList_T& lFFBCList = 
00101         stdair::BomManager::getList<stdair::BookingClass> (iFareFamily);
00102     const bool isEmptyBookingClassList = lFFBCList.empty();
00103     if (isEmptyBookingClassList == true) {
00104       std::ostringstream ostr;
00105       ostr << "The booking class list of the fare family " 
00106            << iFareFamily.describeKey() << " is empty.";
00107       STDAIR_LOG_DEBUG(ostr.str());
00108       throw EmptyBookingClassListException (ostr.str());
00109     }
00110     
00111     // Retrieve the reverse iterator for the first booking class   
00112     stdair::BookingClassList_T::const_reverse_iterator ritBC;   
00113     for (ritBC = lFFBCList.rbegin(); ritBC != lFFBCList.rend(); ++ritBC) {
00114       const stdair::BookingClass* lBC_ptr = *ritBC;
00115       assert (lBC_ptr != NULL);
00116       const stdair::BookingClassKey& lBookingClassKey = lBC_ptr->getKey();
00117       const stdair::ClassCode_T& lClassCode = lBookingClassKey.getClassCode();
00118       if (iFirstPolicyClassCode == lClassCode) {
00119         break;
00120       }   
00121     }
00122     if (ritBC == lFFBCList.rend()) {
00123       std::ostringstream ostr;
00124       ostr << "The booking class " << iFirstPolicyClassCode 
00125            << "is not in the Fare Family " << iFareFamily.describeKey();
00126       STDAIR_LOG_DEBUG(ostr.str());
00127       throw MissingBookingClassInFareFamilyException (ostr.str());
00128     }
00129     assert(ritBC != lFFBCList.rend());
00130 
00131     // Retrieve the booking class of the second policy in the same
00132     // fare family than the current booking class
00133     stdair::ClassCode_T lSecondPolicyClassCode;
00134     const bool hasABookingClassIn = 
00135       intersectionBetweenPolicyAndBookingClassList(lFFBCList,
00136                                                    iSecondPolicy,
00137                                                    lSecondPolicyClassCode);
00138     // Add booking class between the first booking class and 
00139     // the second booking class
00140 
00141     if (hasABookingClassIn == false) {
00142       for (; ritBC != lFFBCList.rend(); ++ritBC) {
00143         stdair::BookingClass* lBC_ptr = *ritBC;
00144         stdair::FacBomManager::addToList (ioNode, *lBC_ptr);
00145       }
00146     } else {
00147       
00148       for (; ritBC != lFFBCList.rend(); ++ritBC) {
00149         stdair::BookingClass* lBC_ptr = *ritBC;
00150         assert (lBC_ptr != NULL);
00151         const stdair::BookingClassKey& lBookingClassKey = lBC_ptr->getKey();
00152         const stdair::ClassCode_T& lClassCode = lBookingClassKey.getClassCode();
00153         if (lSecondPolicyClassCode == lClassCode) {
00154           break;
00155         }
00156         stdair::FacBomManager::addToList (ioNode, *lBC_ptr);
00157       }
00158       assert(ritBC != lFFBCList.rend());
00159     }
00160   }
00161 
00162   // ////////////////////////////////////////////////////////////////////
00163   void PolicyHelper::
00164   computeLastNode (stdair::NestingNode& ioNode,
00165                    const stdair::Policy& iPolicy,
00166                    const stdair::SegmentCabin& iSegmentCabin) {
00167     // Compare the number of booking classes in the policy and the number
00168     // of fare families of the segment-cabin.
00169     ioNode.setYield(stdair::DEFAULT_YIELD_VALUE);
00170     const stdair::BookingClassList_T& lBCList =
00171       stdair::BomManager::getList<stdair::BookingClass> (iPolicy);
00172     const stdair::NbOfClasses_T lNbOfClasses = lBCList.size();
00173     const stdair::FareFamilyList_T& lFFList =
00174       stdair::BomManager::getList<stdair::FareFamily> (iSegmentCabin);
00175     const stdair::NbOfFareFamilies_T lNbOfFFs = lFFList.size();
00176     assert (lNbOfFFs >= lNbOfClasses);
00177 
00178     // Number of closed fare families in the policy.
00179     const stdair::NbOfFareFamilies_T lNbOfClosedFFs = lNbOfFFs - lNbOfClasses;
00180     stdair::FareFamilyList_T::const_reverse_iterator itFF = lFFList.rbegin();
00181     for (unsigned i=0; i<lNbOfClosedFFs; ++i, ++itFF) {
00182       const stdair::FareFamily* lFF_ptr = *itFF;
00183       assert (lFF_ptr != NULL);
00184       const stdair::BookingClassList_T& lCurrentBCList =
00185         stdair::BomManager::getList<stdair::BookingClass> (*lFF_ptr);
00186       for (stdair::BookingClassList_T::const_reverse_iterator itCurrentBC =
00187              lCurrentBCList.rbegin(); itCurrentBC != lCurrentBCList.rend();
00188            ++itCurrentBC) {
00189         stdair::BookingClass* lCurrentBC_ptr = *itCurrentBC;
00190         assert (lCurrentBC_ptr != NULL);
00191         stdair::FacBomManager::addToList (ioNode, *lCurrentBC_ptr);
00192       }
00193     }
00194 
00195     //
00196     for (stdair::BookingClassList_T::const_reverse_iterator itBC =
00197            lBCList.rbegin(); itBC != lBCList.rend(); ++itBC) {
00198       const stdair::BookingClass* lBC_ptr = *itBC;
00199       assert (lBC_ptr != NULL);
00200       const stdair::FareFamily& lFF =
00201         stdair::BomManager::getParent<stdair::FareFamily> (*lBC_ptr);
00202 
00203       const stdair::BookingClassList_T& lCurrentBCList =
00204         stdair::BomManager::getList<stdair::BookingClass> (lFF);
00205       for (stdair::BookingClassList_T::const_reverse_iterator itCurrentBC =
00206              lCurrentBCList.rbegin(); itCurrentBC != lCurrentBCList.rend();
00207            ++itCurrentBC) {
00208         stdair::BookingClass* lCurrentBC_ptr = *itCurrentBC;
00209         assert (lCurrentBC_ptr != NULL);
00210         if (lCurrentBC_ptr->describeKey() != lBC_ptr->describeKey()) {
00211           stdair::FacBomManager::addToList (ioNode, *lCurrentBC_ptr);
00212         } else {
00213           break;
00214         }
00215       }      
00216     }
00217   }
00218 
00219   // ////////////////////////////////////////////////////////////////////
00220   bool PolicyHelper::isNested (const stdair::Policy& iFirstPolicy,
00221                                const stdair::Policy& iSecondPolicy) {
00222     bool isNested = false;
00223     // The number of classes in the first policy should be smaller or equal
00224     // to the number of classes in the second one.
00225     const bool hasAListOfBCFirstPolicy = 
00226       stdair::BomManager::hasList<stdair::BookingClass> (iFirstPolicy);
00227     // All policies are nested with the empty policy
00228     if (hasAListOfBCFirstPolicy == false) {
00229       isNested = true;
00230       return isNested;
00231     } 
00232     const stdair::BookingClassList_T& lFirstBCList =
00233       stdair::BomManager::getList<stdair::BookingClass> (iFirstPolicy);
00234     const bool hasAListOfBCSecondPolicy = 
00235       stdair::BomManager::hasList<stdair::BookingClass> (iSecondPolicy);
00236     // The empty policy is not nested
00237     if (hasAListOfBCSecondPolicy == false) {
00238       return isNested;
00239     } 
00240     const stdair::BookingClassList_T& lSecondBCList =
00241       stdair::BomManager::getList<stdair::BookingClass> (iSecondPolicy);
00242     if (lFirstBCList.size() > lSecondBCList.size()) {
00243       return isNested;
00244     }
00245 
00246     // Browse the two lists of booking classes and verify if the pairs
00247     // of classes are in order.
00248     stdair::BookingClassList_T::const_iterator itFirstBC = lFirstBCList.begin();
00249     for (stdair::BookingClassList_T::const_iterator itSecondBC =
00250            lSecondBCList.begin(); itFirstBC != lFirstBCList.end();
00251          ++itFirstBC, ++itSecondBC) {
00252       const stdair::BookingClass* lFirstBC_ptr = *itFirstBC;
00253       assert (lFirstBC_ptr != NULL);
00254       const std::string lFirstKey = lFirstBC_ptr->describeKey();
00255       const stdair::BookingClass* lSecondBC_ptr = *itSecondBC;
00256       assert (lSecondBC_ptr != NULL);
00257       const std::string lSecondKey = lSecondBC_ptr->describeKey();
00258       if (lFirstKey == lSecondKey) {
00259         break;
00260       }
00261       
00262       // Retrieve the parent FF and its booking class list.
00263       const stdair::FareFamily& lFF =
00264         stdair::BomManager::getParent<stdair::FareFamily> (*lFirstBC_ptr);
00265       const stdair::BookingClassList_T& lBCList =
00266         stdair::BomManager::getList<stdair::BookingClass> (lFF);
00267       for (stdair::BookingClassList_T::const_iterator itBC = lBCList.begin();
00268            itBC != lBCList.end(); ++itBC) {
00269         const stdair::BookingClass* lBC_ptr = *itBC;
00270         assert (lBC_ptr != NULL);
00271         const std::string lKey = lBC_ptr->describeKey();
00272         if (lFirstKey == lKey) {
00273           break;
00274         } else if (lSecondKey == lKey) {
00275           return isNested;
00276         }
00277       }
00278     }
00279 
00280     isNested = true;
00281     return isNested;
00282   }
00283 }