AirInv Logo  1.00.0
C++ Simulated Airline Inventory Management System library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
parseInventory.cpp
Go to the documentation of this file.
1 
5 // STL
6 #include <cassert>
7 #include <iostream>
8 #include <sstream>
9 #include <fstream>
10 #include <string>
11 // Boost (Extended STL)
12 #include <boost/program_options.hpp>
13 #include <boost/tokenizer.hpp>
14 // StdAir
15 #include <stdair/basic/BasLogParams.hpp>
16 #include <stdair/basic/BasDBParams.hpp>
17 #include <stdair/service/Logger.hpp>
18 // AirInv
20 #include <airinv/config/airinv-paths.hpp>
21 
22 // //////// Constants //////
26 const std::string K_AIRINV_DEFAULT_LOG_FILENAME ("parseInventory.log");
27 
31 const std::string K_AIRINV_DEFAULT_INVENTORY_FILENAME (STDAIR_SAMPLE_DIR
32  "/invdump01.csv");
36 const std::string K_AIRINV_DEFAULT_SCHEDULE_FILENAME (STDAIR_SAMPLE_DIR
37  "/schedule01.csv");
41 const std::string K_AIRINV_DEFAULT_OND_FILENAME (STDAIR_SAMPLE_DIR
42  "/ond01.csv");
43 
47 const std::string K_AIRINV_DEFAULT_YIELD_FILENAME (STDAIR_SAMPLE_DIR
48  "/yieldstore01.csv");
49 
53 const std::string K_AIRINV_DEFAULT_SEGMENT_DATE_KEY ("SV,5,2010-03-11,KBP,JFK");
54 
58 const stdair::ClassCode_T K_AIRINV_DEFAULT_CLASS_CODE ("Y");
59 
63 const stdair::PartySize_T K_AIRINV_DEFAULT_PARTY_SIZE (2);
64 
69 const bool K_AIRINV_DEFAULT_BUILT_IN_INPUT = false;
70 
75 const bool K_AIRINV_DEFAULT_FOR_SCHEDULE = false;
76 
80 const int K_AIRINV_EARLY_RETURN_STATUS = 99;
81 
82 // ///////// Parsing of Options & Configuration /////////
83 // A helper function to simplify the main part.
84 template<class T> std::ostream& operator<< (std::ostream& os,
85  const std::vector<T>& v) {
86  std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " "));
87  return os;
88 }
89 
93 int readConfiguration (int argc, char* argv[],
94  bool& ioIsBuiltin, bool& ioIsForSchedule,
95  stdair::Filename_T& ioInventoryFilename,
96  stdair::Filename_T& ioScheduleInputFilename,
97  stdair::Filename_T& ioODInputFilename,
98  stdair::Filename_T& ioYieldInputFilename,
99  std::string& ioSegmentDateKey,
100  stdair::ClassCode_T& ioClassCode,
101  stdair::PartySize_T& ioPartySize,
102  std::string& ioLogFilename) {
103  // Default for the built-in input
104  ioIsBuiltin = K_AIRINV_DEFAULT_BUILT_IN_INPUT;
105 
106  // Default for the inventory or schedule option
107  ioIsForSchedule = K_AIRINV_DEFAULT_FOR_SCHEDULE;
108 
109  // Declare a group of options that will be allowed only on command line
110  boost::program_options::options_description generic ("Generic options");
111  generic.add_options()
112  ("prefix", "print installation prefix")
113  ("version,v", "print version string")
114  ("help,h", "produce help message");
115 
116  // Declare a group of options that will be allowed both on command
117  // line and in config file
118 
119  boost::program_options::options_description config ("Configuration");
120  config.add_options()
121  ("builtin,b",
122  "The sample BOM tree can be either built-in or parsed from an input file. That latter must then be given with the -i/--inventory or -s/--schedule option")
123  ("for_schedule,f",
124  "The BOM tree should be built from a schedule file (instead of from an inventory dump)")
125  ("inventory,i",
126  boost::program_options::value< std::string >(&ioInventoryFilename)->default_value(K_AIRINV_DEFAULT_INVENTORY_FILENAME),
127  "(CSV) input file for the inventory")
128  ("schedule,s",
129  boost::program_options::value< std::string >(&ioScheduleInputFilename)->default_value(K_AIRINV_DEFAULT_SCHEDULE_FILENAME),
130  "(CSV) input file for the schedule")
131  ("ond,o",
132  boost::program_options::value< std::string >(&ioODInputFilename)->default_value(K_AIRINV_DEFAULT_OND_FILENAME),
133  "(CSV) input file for the O&D")
134  ("yield,y",
135  boost::program_options::value< std::string >(&ioYieldInputFilename)->default_value(K_AIRINV_DEFAULT_YIELD_FILENAME),
136  "(CSV) input file for the yield")
137  ("segment_date_key,k",
138  boost::program_options::value< std::string >(&ioSegmentDateKey)->default_value(K_AIRINV_DEFAULT_SEGMENT_DATE_KEY),
139  "Segment-date key")
140  ("class_code,c",
141  boost::program_options::value< stdair::ClassCode_T >(&ioClassCode)->default_value(K_AIRINV_DEFAULT_CLASS_CODE),
142  "Class code")
143  ("party_size,p",
144  boost::program_options::value< stdair::PartySize_T >(&ioPartySize)->default_value(K_AIRINV_DEFAULT_PARTY_SIZE),
145  "Party size")
146  ("log,l",
147  boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_AIRINV_DEFAULT_LOG_FILENAME),
148  "Filename for the logs")
149  ;
150 
151  // Hidden options, will be allowed both on command line and
152  // in config file, but will not be shown to the user.
153  boost::program_options::options_description hidden ("Hidden options");
154  hidden.add_options()
155  ("copyright",
156  boost::program_options::value< std::vector<std::string> >(),
157  "Show the copyright (license)");
158 
159  boost::program_options::options_description cmdline_options;
160  cmdline_options.add(generic).add(config).add(hidden);
161 
162  boost::program_options::options_description config_file_options;
163  config_file_options.add(config).add(hidden);
164  boost::program_options::options_description visible ("Allowed options");
165  visible.add(generic).add(config);
166 
167  boost::program_options::positional_options_description p;
168  p.add ("copyright", -1);
169 
170  boost::program_options::variables_map vm;
171  boost::program_options::
172  store (boost::program_options::command_line_parser (argc, argv).
173  options (cmdline_options).positional(p).run(), vm);
174 
175  std::ifstream ifs ("airinv.cfg");
176  boost::program_options::store (parse_config_file (ifs, config_file_options),
177  vm);
178  boost::program_options::notify (vm);
179 
180  if (vm.count ("help")) {
181  std::cout << visible << std::endl;
182  return K_AIRINV_EARLY_RETURN_STATUS;
183  }
184 
185  if (vm.count ("version")) {
186  std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
187  return K_AIRINV_EARLY_RETURN_STATUS;
188  }
189 
190  if (vm.count ("prefix")) {
191  std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
192  return K_AIRINV_EARLY_RETURN_STATUS;
193  }
194 
195  if (vm.count ("builtin")) {
196  ioIsBuiltin = true;
197  }
198  const std::string isBuiltinStr = (ioIsBuiltin == true)?"yes":"no";
199  std::cout << "The BOM should be built-in? " << isBuiltinStr << std::endl;
200 
201  if (vm.count ("for_schedule")) {
202  ioIsForSchedule = true;
203  }
204  const std::string isForScheduleStr = (ioIsForSchedule == true)?"yes":"no";
205  std::cout << "The BOM should be built from schedule? " << isForScheduleStr
206  << std::endl;
207 
208  if (ioIsBuiltin == false) {
209 
210  if (ioIsForSchedule == false) {
211  // The BOM tree should be built from parsing an inventory dump
212  if (vm.count ("inventory")) {
213  ioInventoryFilename = vm["inventory"].as< std::string >();
214  std::cout << "Input inventory filename is: " << ioInventoryFilename
215  << std::endl;
216 
217  } else {
218  // The built-in option is not selected. However, no inventory dump
219  // file is specified
220  std::cerr << "Either one among the -b/--builtin, -i/--inventory or "
221  << " -f/--for_schedule and -s/--schedule options "
222  << "must be specified" << std::endl;
223  }
224 
225  } else {
226  // The BOM tree should be built from parsing a schedule (and O&D) file
227  if (vm.count ("schedule")) {
228  ioScheduleInputFilename = vm["schedule"].as< std::string >();
229  std::cout << "Input schedule filename is: " << ioScheduleInputFilename
230  << std::endl;
231 
232  } else {
233  // The built-in option is not selected. However, no schedule file
234  // is specified
235  std::cerr << "Either one among the -b/--builtin, -i/--inventory or "
236  << " -f/--for_schedule and -s/--schedule options "
237  << "must be specified" << std::endl;
238  }
239 
240  if (vm.count ("ond")) {
241  ioODInputFilename = vm["ond"].as< std::string >();
242  std::cout << "Input O&D filename is: " << ioODInputFilename << std::endl;
243  }
244 
245  if (vm.count ("yield")) {
246  ioYieldInputFilename = vm["yield"].as< std::string >();
247  std::cout << "Input yield filename is: "
248  << ioYieldInputFilename << std::endl;
249  }
250  }
251  }
252 
253  if (vm.count ("log")) {
254  ioLogFilename = vm["log"].as< std::string >();
255  std::cout << "Log filename is: " << ioLogFilename << std::endl;
256  }
257 
258  return 0;
259 }
260 
261 
262 // ///////// M A I N ////////////
263 int main (int argc, char* argv[]) {
264 
265  // State whether the BOM tree should be built-in or parsed from an
266  // input file
267  bool isBuiltin;
268  bool isForSchedule;
269 
270  // Input file names
271  stdair::Filename_T lInventoryFilename;
272  stdair::Filename_T lScheduleInputFilename;
273  stdair::Filename_T lODInputFilename;
274  stdair::Filename_T lYieldInputFilename;
275 
276  // Parameters for the sale
277  std::string lSegmentDateKey;
278  stdair::ClassCode_T lClassCode;
279  stdair::PartySize_T lPartySize;
280 
281  // Output log File
282  stdair::Filename_T lLogFilename;
283 
284  // Call the command-line option parser
285  const int lOptionParserStatus =
286  readConfiguration (argc, argv, isBuiltin, isForSchedule, lInventoryFilename,
287  lScheduleInputFilename, lODInputFilename,
288  lYieldInputFilename, lSegmentDateKey, lClassCode,
289  lPartySize, lLogFilename);
290 
291  if (lOptionParserStatus == K_AIRINV_EARLY_RETURN_STATUS) {
292  return 0;
293  }
294 
295  // Set the log parameters
296  std::ofstream logOutputFile;
297  // Open and clean the log outputfile
298  logOutputFile.open (lLogFilename.c_str());
299  logOutputFile.clear();
300 
301  // Initialise the inventory service
302  const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
303  AIRINV::AIRINV_Master_Service airinvService (lLogParams);
304 
305  // DEBUG
306  STDAIR_LOG_DEBUG ("Welcome to AirInv");
307 
308  // Check wether or not a (CSV) input file should be read
309  if (isBuiltin == true) {
310 
311  // Build the sample BOM tree for RMOL
312  airinvService.buildSampleBom();
313 
314  // Define a specific segment-date key for the sample BOM tree
315  //lSegmentDateKey = "BA,9,2011-06-10,LHR,SYD";
316  lSegmentDateKey = "SQ,11,2010-02-08,SIN,BKK";
317 
318  } else {
319  if (isForSchedule == true) {
320  // Build the BOM tree from parsing a schedule file (and O&D list)
321  stdair::ScheduleFilePath lScheduleFilePath (lScheduleInputFilename);
322  stdair::ODFilePath lODFilePath (lODInputFilename);
323  AIRRAC::YieldFilePath lYieldFilePath (lYieldInputFilename);
324  airinvService.parseAndLoad (lScheduleFilePath, lODFilePath,
325  lYieldFilePath);
326 
327  if (lSegmentDateKey == K_AIRINV_DEFAULT_SEGMENT_DATE_KEY) {
328  // Define a specific segment-date key for the schedule-based inventory
329  lSegmentDateKey = "SQ,11,2010-01-15,SIN,BKK";
330  }
331 
332  } else {
333  // Build the BOM tree from parsing an inventory dump file
334  AIRINV::InventoryFilePath lInventoryFilePath (lInventoryFilename);
335  airinvService.parseAndLoad (lInventoryFilePath);
336  }
337  }
338 
339  // Make a booking
340  const bool isSellSuccessful =
341  airinvService.sell (lSegmentDateKey, lClassCode, lPartySize);
342 
343  // DEBUG
344  STDAIR_LOG_DEBUG ("Sale ('" << lSegmentDateKey << "', " << lClassCode << ": "
345  << lPartySize << ") successful? " << isSellSuccessful);
346 
347  // DEBUG: Display the whole BOM tree
348  const std::string& lCSVDump = airinvService.csvDisplay();
349  STDAIR_LOG_DEBUG (lCSVDump);
350 
351  // Close the Log outputFile
352  logOutputFile.close();
353 
354  /*
355  Note: as that program is not intended to be run on a server in
356  production, it is better not to catch the exceptions. When it
357  happens (that an exception is throwned), that way we get the
358  call stack.
359  */
360 
361  return 0;
362 }