RMOL Logo  1.00.0
C++ library of Revenue Management and Optimisation classes and functions
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
PolicyHelper.cpp
Go to the documentation of this file.
1 
2 // //////////////////////////////////////////////////////////////////////
3 // Import section
4 // //////////////////////////////////////////////////////////////////////
5 // STL
6 #include <cassert>
7 #include <cmath>
8 // StdAir
9 #include <stdair/basic/BasConst_Inventory.hpp>
10 #include <stdair/basic/BasConst_Yield.hpp>
11 #include <stdair/bom/SegmentCabin.hpp>
12 #include <stdair/bom/Policy.hpp>
13 #include <stdair/bom/BookingClass.hpp>
14 #include <stdair/bom/FareFamily.hpp>
15 #include <stdair/bom/NestingNode.hpp>
16 #include <stdair/bom/BomManager.hpp>
17 #include <stdair/factory/FacBomManager.hpp>
18 // RMOL
20 
21 namespace RMOL {
22  // ////////////////////////////////////////////////////////////////////
23  void PolicyHelper::
24  diffBetweenTwoPolicies (stdair::NestingNode& ioNode,
25  const stdair::Policy& iFirstPolicy,
26  const stdair::Policy& iSecondPolicy) {
27 
28  // Retrieve the booking class list of the first policy
29  const stdair::BookingClassList_T& lFirstBCList =
30  stdair::BomManager::getList<stdair::BookingClass> (iFirstPolicy);
31 
32  // Browse the booking class list
33  for (stdair::BookingClassList_T::const_iterator itBC = lFirstBCList.begin();
34  itBC != lFirstBCList.end(); ++itBC){
35  const stdair::BookingClass* iFirstPolicyBC_ptr = *itBC;
36  const stdair::BookingClassKey& lFirstPolicyBCKey =
37  iFirstPolicyBC_ptr->getKey();
38  const stdair::ClassCode_T& lFirstPolicyClassCode =
39  lFirstPolicyBCKey.getClassCode();
40  // Retrieve the fare family of the booking class and the list of booking
41  // class of this fare family
42  const stdair::FareFamily& lFareFamily =
43  stdair::BomManager::getParent<stdair::FareFamily> (*iFirstPolicyBC_ptr);
44 
45  // Retrieve the list of booking class between the both booking classes
46  diffBetweenBookingClassAndPolicy (ioNode, lFareFamily,
47  lFirstPolicyClassCode,
48  iSecondPolicy);
49  }
50  }
51 
52  // ////////////////////////////////////////////////////////////////////
53  const bool PolicyHelper::
54  intersectionBetweenPolicyAndBookingClassList (const stdair::BookingClassList_T& iBCList,
55  const stdair::Policy& iPolicy,
56  stdair::ClassCode_T& oClassCode) {
57  bool isInBookingClassList = false;
58 
59  // Retrieve the booking classes of the policy
60  const bool hasAListOfBC =
61  stdair::BomManager::hasList<stdair::BookingClass> (iPolicy);
62  if (hasAListOfBC == false) {
63  return isInBookingClassList;
64  }
65  const stdair::BookingClassList_T& lPolicyBookingClassList =
66  stdair::BomManager::getList<stdair::BookingClass> (iPolicy);
67 
68  // Browse the booking class list of the fare family
69  stdair::BookingClassList_T::const_iterator itFFBC = iBCList.begin();
70  for (; itFFBC != iBCList.end(); ++itFFBC) {
71  stdair::BookingClass* lFFBC_ptr = *itFFBC;
72  const stdair::BookingClassKey& lFFBCKey = lFFBC_ptr->getKey();
73  const stdair::ClassCode_T& lFFClassCode = lFFBCKey.getClassCode();
74  // Compare the booking class with booking classes of policy
75  stdair::BookingClassList_T::const_iterator itPolicyBC =
76  lPolicyBookingClassList.begin();
77  for (; itPolicyBC != lPolicyBookingClassList.end(); ++itPolicyBC){
78  const stdair::BookingClass* lPolicyBC_ptr = *itPolicyBC;
79  const stdair::BookingClassKey& lPolicyBCKey = lPolicyBC_ptr->getKey();
80  const stdair::ClassCode_T& lPolicyClassCode =
81  lPolicyBCKey.getClassCode();
82  if (lPolicyClassCode == lFFClassCode) {
83  oClassCode = lPolicyClassCode;
84  isInBookingClassList = true;
85  return isInBookingClassList;
86  }
87  }
88  }
89  // If the policy has not any booking class in the fare family,
90  // return false
91  return isInBookingClassList;
92  }
93 
94  // ////////////////////////////////////////////////////////////////////
95  void PolicyHelper::
96  diffBetweenBookingClassAndPolicy (stdair::NestingNode& ioNode,
97  const stdair::FareFamily& iFareFamily,
98  const stdair::ClassCode_T& iFirstPolicyClassCode,
99  const stdair::Policy& iSecondPolicy) {
100  const stdair::BookingClassList_T& lFFBCList =
101  stdair::BomManager::getList<stdair::BookingClass> (iFareFamily);
102  const bool isEmptyBookingClassList = lFFBCList.empty();
103  if (isEmptyBookingClassList == true) {
104  std::ostringstream ostr;
105  ostr << "The booking class list of the fare family "
106  << iFareFamily.describeKey() << " is empty.";
107  STDAIR_LOG_DEBUG(ostr.str());
108  throw EmptyBookingClassListException (ostr.str());
109  }
110 
111  // Retrieve the reverse iterator for the first booking class
112  stdair::BookingClassList_T::const_reverse_iterator ritBC;
113  for (ritBC = lFFBCList.rbegin(); ritBC != lFFBCList.rend(); ++ritBC) {
114  const stdair::BookingClass* lBC_ptr = *ritBC;
115  assert (lBC_ptr != NULL);
116  const stdair::BookingClassKey& lBookingClassKey = lBC_ptr->getKey();
117  const stdair::ClassCode_T& lClassCode = lBookingClassKey.getClassCode();
118  if (iFirstPolicyClassCode == lClassCode) {
119  break;
120  }
121  }
122  if (ritBC == lFFBCList.rend()) {
123  std::ostringstream ostr;
124  ostr << "The booking class " << iFirstPolicyClassCode
125  << "is not in the Fare Family " << iFareFamily.describeKey();
126  STDAIR_LOG_DEBUG(ostr.str());
127  throw MissingBookingClassInFareFamilyException (ostr.str());
128  }
129  assert(ritBC != lFFBCList.rend());
130 
131  // Retrieve the booking class of the second policy in the same
132  // fare family than the current booking class
133  stdair::ClassCode_T lSecondPolicyClassCode;
134  const bool hasABookingClassIn =
135  intersectionBetweenPolicyAndBookingClassList(lFFBCList,
136  iSecondPolicy,
137  lSecondPolicyClassCode);
138  // Add booking class between the first booking class and
139  // the second booking class
140 
141  if (hasABookingClassIn == false) {
142  for (; ritBC != lFFBCList.rend(); ++ritBC) {
143  stdair::BookingClass* lBC_ptr = *ritBC;
144  stdair::FacBomManager::addToList (ioNode, *lBC_ptr);
145  }
146  } else {
147 
148  for (; ritBC != lFFBCList.rend(); ++ritBC) {
149  stdair::BookingClass* lBC_ptr = *ritBC;
150  assert (lBC_ptr != NULL);
151  const stdair::BookingClassKey& lBookingClassKey = lBC_ptr->getKey();
152  const stdair::ClassCode_T& lClassCode = lBookingClassKey.getClassCode();
153  if (lSecondPolicyClassCode == lClassCode) {
154  break;
155  }
156  stdair::FacBomManager::addToList (ioNode, *lBC_ptr);
157  }
158  assert(ritBC != lFFBCList.rend());
159  }
160  }
161 
162  // ////////////////////////////////////////////////////////////////////
163  void PolicyHelper::
164  computeLastNode (stdair::NestingNode& ioNode,
165  const stdair::Policy& iPolicy,
166  const stdair::SegmentCabin& iSegmentCabin) {
167  // Compare the number of booking classes in the policy and the number
168  // of fare families of the segment-cabin.
169  ioNode.setYield(stdair::DEFAULT_YIELD_VALUE);
170  const stdair::BookingClassList_T& lBCList =
171  stdair::BomManager::getList<stdair::BookingClass> (iPolicy);
172  const stdair::NbOfClasses_T lNbOfClasses = lBCList.size();
173  const stdair::FareFamilyList_T& lFFList =
174  stdair::BomManager::getList<stdair::FareFamily> (iSegmentCabin);
175  const stdair::NbOfFareFamilies_T lNbOfFFs = lFFList.size();
176  assert (lNbOfFFs >= lNbOfClasses);
177 
178  // Number of closed fare families in the policy.
179  const stdair::NbOfFareFamilies_T lNbOfClosedFFs = lNbOfFFs - lNbOfClasses;
180  stdair::FareFamilyList_T::const_reverse_iterator itFF = lFFList.rbegin();
181  for (unsigned i=0; i<lNbOfClosedFFs; ++i, ++itFF) {
182  const stdair::FareFamily* lFF_ptr = *itFF;
183  assert (lFF_ptr != NULL);
184  const stdair::BookingClassList_T& lCurrentBCList =
185  stdair::BomManager::getList<stdair::BookingClass> (*lFF_ptr);
186  for (stdair::BookingClassList_T::const_reverse_iterator itCurrentBC =
187  lCurrentBCList.rbegin(); itCurrentBC != lCurrentBCList.rend();
188  ++itCurrentBC) {
189  stdair::BookingClass* lCurrentBC_ptr = *itCurrentBC;
190  assert (lCurrentBC_ptr != NULL);
191  stdair::FacBomManager::addToList (ioNode, *lCurrentBC_ptr);
192  }
193  }
194 
195  //
196  for (stdair::BookingClassList_T::const_reverse_iterator itBC =
197  lBCList.rbegin(); itBC != lBCList.rend(); ++itBC) {
198  const stdair::BookingClass* lBC_ptr = *itBC;
199  assert (lBC_ptr != NULL);
200  const stdair::FareFamily& lFF =
201  stdair::BomManager::getParent<stdair::FareFamily> (*lBC_ptr);
202 
203  const stdair::BookingClassList_T& lCurrentBCList =
204  stdair::BomManager::getList<stdair::BookingClass> (lFF);
205  for (stdair::BookingClassList_T::const_reverse_iterator itCurrentBC =
206  lCurrentBCList.rbegin(); itCurrentBC != lCurrentBCList.rend();
207  ++itCurrentBC) {
208  stdair::BookingClass* lCurrentBC_ptr = *itCurrentBC;
209  assert (lCurrentBC_ptr != NULL);
210  if (lCurrentBC_ptr->describeKey() != lBC_ptr->describeKey()) {
211  stdair::FacBomManager::addToList (ioNode, *lCurrentBC_ptr);
212  } else {
213  break;
214  }
215  }
216  }
217  }
218 
219  // ////////////////////////////////////////////////////////////////////
220  bool PolicyHelper::isNested (const stdair::Policy& iFirstPolicy,
221  const stdair::Policy& iSecondPolicy) {
222  bool isNested = false;
223  // The number of classes in the first policy should be smaller or equal
224  // to the number of classes in the second one.
225  const bool hasAListOfBCFirstPolicy =
226  stdair::BomManager::hasList<stdair::BookingClass> (iFirstPolicy);
227  // All policies are nested with the empty policy
228  if (hasAListOfBCFirstPolicy == false) {
229  isNested = true;
230  return isNested;
231  }
232  const stdair::BookingClassList_T& lFirstBCList =
233  stdair::BomManager::getList<stdair::BookingClass> (iFirstPolicy);
234  const bool hasAListOfBCSecondPolicy =
235  stdair::BomManager::hasList<stdair::BookingClass> (iSecondPolicy);
236  // The empty policy is not nested
237  if (hasAListOfBCSecondPolicy == false) {
238  return isNested;
239  }
240  const stdair::BookingClassList_T& lSecondBCList =
241  stdair::BomManager::getList<stdair::BookingClass> (iSecondPolicy);
242  if (lFirstBCList.size() > lSecondBCList.size()) {
243  return isNested;
244  }
245 
246  // Browse the two lists of booking classes and verify if the pairs
247  // of classes are in order.
248  stdair::BookingClassList_T::const_iterator itFirstBC = lFirstBCList.begin();
249  for (stdair::BookingClassList_T::const_iterator itSecondBC =
250  lSecondBCList.begin(); itFirstBC != lFirstBCList.end();
251  ++itFirstBC, ++itSecondBC) {
252  const stdair::BookingClass* lFirstBC_ptr = *itFirstBC;
253  assert (lFirstBC_ptr != NULL);
254  const std::string lFirstKey = lFirstBC_ptr->describeKey();
255  const stdair::BookingClass* lSecondBC_ptr = *itSecondBC;
256  assert (lSecondBC_ptr != NULL);
257  const std::string lSecondKey = lSecondBC_ptr->describeKey();
258  if (lFirstKey == lSecondKey) {
259  break;
260  }
261 
262  // Retrieve the parent FF and its booking class list.
263  const stdair::FareFamily& lFF =
264  stdair::BomManager::getParent<stdair::FareFamily> (*lFirstBC_ptr);
265  const stdair::BookingClassList_T& lBCList =
266  stdair::BomManager::getList<stdair::BookingClass> (lFF);
267  for (stdair::BookingClassList_T::const_iterator itBC = lBCList.begin();
268  itBC != lBCList.end(); ++itBC) {
269  const stdair::BookingClass* lBC_ptr = *itBC;
270  assert (lBC_ptr != NULL);
271  const std::string lKey = lBC_ptr->describeKey();
272  if (lFirstKey == lKey) {
273  break;
274  } else if (lSecondKey == lKey) {
275  return isNested;
276  }
277  }
278  }
279 
280  isNested = true;
281  return isNested;
282  }
283 }