Go to the documentation of this file.00001
00002
00003
00004
00005 #include <cassert>
00006 #include <cmath>
00007
00008 #include <stdair/basic/BasConst_Inventory.hpp>
00009 #include <stdair/bom/BomRetriever.hpp>
00010 #include <stdair/bom/BomManager.hpp>
00011 #include <stdair/bom/SegmentDate.hpp>
00012 #include <stdair/bom/SegmentCabin.hpp>
00013 #include <stdair/bom/FareFamily.hpp>
00014 #include <stdair/bom/BookingClass.hpp>
00015 #include <stdair/bom/GuillotineBlock.hpp>
00016 #include <stdair/service/Logger.hpp>
00017
00018 #include <airinv/basic/BasConst_Curves.hpp>
00019 #include <airinv/bom/GuillotineBlockHelper.hpp>
00020 #include <airinv/bom/FlightDateHelper.hpp>
00021 #include <airinv/bom/SegmentCabinHelper.hpp>
00022
00023 namespace AIRINV {
00024
00025
00026 void GuillotineBlockHelper::
00027 takeSnapshots (stdair::GuillotineBlock& ioGuillotineBlock,
00028 const stdair::DateTime_T& iSnapshotTime) {
00029
00030
00031 const stdair::SegmentCabinIndexMap_T& lSegmentCabinIndexMap =
00032 ioGuillotineBlock.getSegmentCabinIndexMap();
00033 for (stdair::SegmentCabinIndexMap_T::const_iterator itSCIdx =
00034 lSegmentCabinIndexMap.begin();
00035 itSCIdx != lSegmentCabinIndexMap.end(); ++itSCIdx) {
00036 const stdair::SegmentCabin* lSC_ptr = itSCIdx->first;
00037 assert (lSC_ptr != NULL);
00038 const stdair::BlockNumber_T& lSCIdx = itSCIdx->second;
00039
00040 const stdair::Date_T& lSnapshotDate = iSnapshotTime.date();
00041
00042
00043
00044 const stdair::SegmentDate& lSegmentDate =
00045 stdair::BomManager::getParent<stdair::SegmentDate> (*lSC_ptr);
00046 const stdair::Date_T& lDepartureDate = lSegmentDate.getBoardingDate();
00047 const stdair::DateOffset_T lDateOffset = lDepartureDate - lSnapshotDate;
00048 const stdair::DTD_T lDTD = lDateOffset.days() + 1;
00049
00050 if (lDTD >= 0 && lDTD <= stdair::DEFAULT_MAX_DTD) {
00051 SegmentCabinHelper::updateAvailabilities (*lSC_ptr);
00052 takeSnapshots (ioGuillotineBlock, lDTD, *lSC_ptr, lSCIdx);
00053 registerProductAndPriceOrientedBookings (ioGuillotineBlock,
00054 lDTD, *lSC_ptr, lSCIdx);
00055 }
00056 }
00057 }
00058
00059
00060 void GuillotineBlockHelper::
00061 takeSnapshots (stdair::GuillotineBlock& ioGuillotineBlock,
00062 const stdair::DTD_T& iDTD,
00063 const stdair::SegmentCabin& iSegmentCabin,
00064 const stdair::BlockNumber_T iSegmentCabinIdx) {
00065
00066
00067 stdair::SegmentCabinDTDSnapshotView_T lBookingView = ioGuillotineBlock.
00068 getSegmentCabinDTDBookingSnapshotView (iSegmentCabinIdx,
00069 iSegmentCabinIdx, iDTD);
00070 stdair::SegmentCabinDTDSnapshotView_T lCancellationView = ioGuillotineBlock.
00071 getSegmentCabinDTDCancellationSnapshotView (iSegmentCabinIdx,
00072 iSegmentCabinIdx, iDTD);
00073 stdair::SegmentCabinDTDSnapshotView_T lAvailabilityView = ioGuillotineBlock.
00074 getSegmentCabinDTDAvailabilitySnapshotView (iSegmentCabinIdx,
00075 iSegmentCabinIdx, iDTD);
00076
00077
00078 std::ostringstream lSCMapKey;
00079 lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
00080 << iSegmentCabin.describeKey();
00081 const stdair::BlockIndex_T& lCabinIdx =
00082 ioGuillotineBlock.getBlockIndex (lSCMapKey.str());
00083 lAvailabilityView[lCabinIdx] = iSegmentCabin.getAvailabilityPool();
00084
00085
00086
00087 const stdair::BookingClassList_T& lBCList =
00088 stdair::BomManager::getList<stdair::BookingClass> (iSegmentCabin);
00089 for (stdair::BookingClassList_T::const_iterator itBC = lBCList.begin();
00090 itBC != lBCList.end(); ++itBC) {
00091 const stdair::BookingClass* lBookingClass_ptr = *itBC;
00092 assert (lBookingClass_ptr != NULL);
00093
00094
00095 const stdair::BlockIndex_T& lIdx =
00096 ioGuillotineBlock.getBlockIndex (lBookingClass_ptr->describeKey());
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 lBookingView[lIdx]=lBookingClass_ptr->getNbOfBookings();
00107 lCancellationView[lIdx] =
00108 lBookingClass_ptr->getNbOfCancellations();
00109 lAvailabilityView[lIdx] =
00110 lBookingClass_ptr->getSegmentAvailability();
00111 }
00112 }
00113
00114
00115 void GuillotineBlockHelper::registerProductAndPriceOrientedBookings
00116 (stdair::GuillotineBlock& ioGuillotineBlock, const stdair::DTD_T& iDTD,
00117 const stdair::SegmentCabin& iSegmentCabin,
00118 const stdair::BlockNumber_T iSegmentCabinIdx) {
00119
00120
00121 stdair::SegmentCabinDTDRangeSnapshotView_T lRangeBookingView =
00122 ioGuillotineBlock.getSegmentCabinDTDRangeBookingSnapshotView (iSegmentCabinIdx, iSegmentCabinIdx, iDTD, iDTD + 1);
00123 stdair::SegmentCabinDTDRangeSnapshotView_T lRangeCancellationView =
00124 ioGuillotineBlock.getSegmentCabinDTDRangeCancellationSnapshotView (iSegmentCabinIdx, iSegmentCabinIdx, iDTD, iDTD + 1);
00125 stdair::SegmentCabinDTDSnapshotView_T lProductAndPriceOrientedBookingView =
00126 ioGuillotineBlock.getSegmentCabinDTDProductAndPriceOrientedBookingSnapshotView (iSegmentCabinIdx, iSegmentCabinIdx, iDTD);
00127
00128
00129 std::ostringstream lSCMapKey;
00130 lSCMapKey << stdair::DEFAULT_SEGMENT_CABIN_VALUE_TYPE
00131 << iSegmentCabin.describeKey();
00132 const stdair::BlockIndex_T& lCabinIdx =
00133 ioGuillotineBlock.getBlockIndex (lSCMapKey.str());
00134
00135
00136
00137 const stdair::BookingClassList_T& lBCList =
00138 stdair::BomManager::getList<stdair::BookingClass> (iSegmentCabin);
00139 stdair::BookingClassList_T::const_reverse_iterator itBC = lBCList.rbegin();
00140 assert (itBC != lBCList.rend());
00141 stdair::BookingClass* lLowestClass_ptr = *itBC; ++itBC;
00142 assert (lLowestClass_ptr != NULL);
00143
00144
00145 const stdair::BlockIndex_T& lClassIdx =
00146 ioGuillotineBlock.getBlockIndex (lLowestClass_ptr->describeKey());
00147
00148
00149 const stdair::NbOfBookings_T lNbOfNetBkgs =
00150 lRangeBookingView[lClassIdx][0] - lRangeBookingView[lClassIdx][1];
00151 const stdair::NbOfCancellations_T lNbOfCx =
00152 lRangeCancellationView[lClassIdx][0]-lRangeCancellationView[lClassIdx][1];
00153 const stdair::NbOfBookings_T lNbOfGrossBkgs = lNbOfNetBkgs + lNbOfCx;
00154
00155
00156 lProductAndPriceOrientedBookingView[lCabinIdx] = lNbOfGrossBkgs;
00157
00158
00159 const stdair::Yield_T& lLowestYield = lLowestClass_ptr->getYield();
00160
00161
00162 bool noLowerClassAvl = true;
00163 if (lLowestClass_ptr->getSegmentAvailability() >= 1.0) {
00164 noLowerClassAvl = false;
00165 }
00166
00167
00168 const double lFRAT5Coef = getFRAT5Coefficient (iDTD);
00169 const double lSellUpCoef = -log(0.5) / (lFRAT5Coef - 1);
00170
00171
00172 for (; itBC != lBCList.rend(); ++itBC) {
00173 const stdair::BookingClass* lBookingClass_ptr = *itBC;
00174 assert (lBookingClass_ptr != NULL);
00175
00176
00177 const stdair::Yield_T& lYield = lBookingClass_ptr->getYield();
00178 assert (lYield > lLowestYield);
00179
00180
00181 const stdair::BlockIndex_T& lIdx =
00182 ioGuillotineBlock.getBlockIndex (lBookingClass_ptr->describeKey());
00183
00184
00185 const stdair::NbOfBookings_T lNetBkgs =
00186 lRangeBookingView[lIdx][0] - lRangeBookingView[lIdx][1];
00187 const stdair::NbOfCancellations_T lCx =
00188 lRangeCancellationView[lIdx][0] - lRangeCancellationView[lIdx][1];
00189 const stdair::NbOfBookings_T lGrossBkgs = lNetBkgs + lCx;
00190
00191
00192
00193
00194 if (noLowerClassAvl == false) {
00195 lProductAndPriceOrientedBookingView[lIdx] = lGrossBkgs;
00196 } else {
00197
00198 const stdair::NbOfBookings_T lQEquiBkgs =
00199 lGrossBkgs / exp ((1.0 - lYield/lLowestYield) * lSellUpCoef);
00200 lProductAndPriceOrientedBookingView[lCabinIdx] += lQEquiBkgs;
00201
00202 if (lBookingClass_ptr->getSegmentAvailability() >= 1.0) {
00203 noLowerClassAvl = false;
00204 }
00205 }
00206 }
00207 }
00208
00209
00210 double GuillotineBlockHelper::getFRAT5Coefficient (const stdair::DTD_T& iDTD){
00211 FRAT5Curve_T::const_iterator itFRAT5 =
00212 DEFAULT_PICKUP_FRAT5_CURVE.lower_bound (iDTD);
00213 assert (itFRAT5 != DEFAULT_PICKUP_FRAT5_CURVE.end());
00214
00215 if (itFRAT5 == DEFAULT_PICKUP_FRAT5_CURVE.begin()) {
00216 return itFRAT5->second;
00217 }
00218
00219 assert (itFRAT5 != DEFAULT_PICKUP_FRAT5_CURVE.begin());
00220 FRAT5Curve_T::const_iterator itNextFRAT5 = itFRAT5; --itNextFRAT5;
00221
00222 const stdair::DTD_T& lPrevDTD = itFRAT5->first;
00223 const stdair::DTD_T& lNextDTD = itNextFRAT5->first;
00224 const double& lPrevFRAT5 = itFRAT5->second;
00225 const double& lNextFRAT5 = itNextFRAT5->second;
00226 assert (lPrevDTD > lNextDTD);
00227
00228 double oFRAT5 = lPrevFRAT5
00229 + (iDTD - lNextDTD) * (lNextFRAT5 - lPrevFRAT5) / (lPrevDTD - lNextDTD);
00230
00231 return oFRAT5;
00232 }
00233 }