eFinancialPlanner  V1.0 (proof of concept)
Personal Financial Planning based on Maslowian Portfolio Theory
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
investor_ui.class.cpp
Go to the documentation of this file.
1 
14 class investor_ui : public investor
15 {
16 public:
17  investor_ui();
18 // int investor_id;
19 // string user_name;
20 // string first_name;
21 // string last_name;
22 //
23 // string currency;
24 // struct tm birth_date;
25 
26 // char active_actions[6] = "11000"; //e.g. 11000 for someone who has logged in but did nothing else
27  int active_action = 1; // eg. 1 for the home screen
28 
29  bool set_investor_id (const string& s);
30  bool set_user_name (const string& s);
31  bool set_first_name (const string& s);
32  bool set_last_name (const string& s);
33  bool set_password (const string& s);
34  bool set_currency (const string& s);
35  bool set_birth_date (const string& s);
36  bool set_simulate_till_age(const string& s);
37  bool is_logged_in ();
38  void logout ();
40  void login ();
42 
43 //inherited: string get_full_name();
44 //inherited: float age(int Mnbr = 0);
45 //inherited: int months2simulate();
46 
47  string parse_user_info(bool parse_wrapper = true);
48 
49  void home_screen();
50  void show_home_screen_form();
51  void register_form();
52  void register_exec();
53  void account_form();
54  void account_save();
55  void login_form();
56  void login_exec();
57  void show_disclaimer();
58  void personalize_screen();
59  void personalize_save();
60  void personalize_reload(string action);
61 
62  void show_inventory_form();
63  void asset_add();
64  void asset_edit();
65  void asset_save();
66  void asset_delete();
67 
68  void goal_help_form();
69  void goal_help_save();
70 
71  void goal_list();
72  void goal_add();
73  void goal_edit();
74  void goal_save();
75  void goal_delete();
76 
77  void cash_flow_list();
78  void cash_flow_add();
79  void cash_flow_edit();
80  void cash_flow_save();
81  void cash_flow_delete();
82 
83  void feedback();
84  void show_simulation();
85  void show_follow_up();
86  void show_total_portfolio(investment_problem * oInvProbl);
87  void parse_savings_plan(investment_problem * oInvProbl, int g); // show the savings plan for goal g
88 
90 
91 
92 private:
96  void show_login_form_body();
98  void parse_bm(std::map<int, float> benchmark, int ref_number);
99  // personalize:
100  void personalize_form();
101  void personalize_pref_table();
102  void personalize_ER_table();
103  void personalize_vol_table();
106  void parse_simulation_duration_form(int nbrMonths, string action = "s");
108  void parse_form_open_personalize(string the_content);
109  void parse_form_close_personalize(string the_content, bool show_reload = true);
110  string button_to(string go_to, string description, char type_redir);
112  void personalize_set_prefs();
113  void personalize_set_ER();
114  void personalize_set_vol();
115  void personalize_set_corr();
116  void parse_goal_box(investment_problem * oInvProbl, int g, string s_var = "", string s_desc = "");
117 
118  std::map<int, string> asset_class_names;
119 
120 };
121 
122 
127 {
128 }
129 
133 string investor_ui::parse_user_info(bool parse_wrapper)
134 {
135  string s;
136  switch (oConfig.layout)
137  {
138  case '2' :
139  s = "<div class=\"alert alert-info\">";
140  s = s + "<h4>" + this->get_full_name() + "</h4>"
141  + "<ul>"
142  + "<li>" + t_b_currency + ": " + this->currency + "</li>"
143  + "<li>" + t_b_date + ": " + tm2DateStr(this->birth_date) + ", age: " + round2str(this->age(),1) + " years old</li>"
144  + "<li>" + t_sim_till + ": " + to_string((int)round(this->simulate_till_age)) + " years old</li>"
145  + "</ul>"
146  + "</div>";
147  break;
148  case '1' :
149  default :
150  s = "<div class=\"alert alert-info\">";
151  s = s + "<h4>" + this->get_full_name() + "</h4>"
152  + "<ul>"
153  + "<li>" + t_b_currency + ": " + this->currency + "</li>"
154  + "<li>" + t_b_date + ": " + tm2DateStr(this->birth_date) + ", age: " + round2str(this->age(),1) + " years old</li>"
155  + "<li>" + t_sim_till + ": " + to_string((int)round(this->simulate_till_age)) + " years old</li>"
156  + "</ul>"
157  + "</div>";
158  break;
159  }
160  return s;
161 }
162 
163 
170 inline string investor_ui::button_to(string go_to, string description, char type_redir)
171 {
172  string s;
173  s = "<button class=\"btn btn-primary\" onclick=\"location.href='";
174  switch (type_redir)
175  {
176  case 'a': s = s + oConfig.soft_url + "?a="; break;
177  case 's': s = s + oConfig.soft_url + "?a2="; break;
178  case 'u': {};
179  default : {};
180  }
181  s = s + go_to + "';\">";
182  s = s + description;
183  s = s + "</button>";
184  return s;
185 }
186 
187 
192 {
193  switch (oConfig.layout)
194  {
195  case '2':
196  cout << "<div class=\"row-fluid\">";
197  cout << "<div class=\"col-md-3 alert alert-info\">\n";
199  cout << "</div>\n";
200  cout << "<div class=\"col-md-1\"><center>&nbsp;or&nbsp;</center></div>\n";
201  cout << "<div class=\"col-md-2 alert alert-info\" >";
203  cout << "</div>\n";
204  cout << "</div>\n"; // row
205  break;
206  case '1':
207  default:
208  //cout << "<div class=\"container-fluid\">";
209  cout << "<div class=\"row-fluid\">";
210  cout << "<div class=\"span1\"></div>\n";
211  cout << "<div class=\"span5 alert alert-info\">\n";
213  cout << "</div>\n"; // span
214  cout << "<div class=\"span1\"><p class=\"center\">...OR...</p></div>\n";
215  cout << "<div class=\"span4 alert alert-info\" >";
217  cout << "</div>\n"; // span
218  cout << "</div>\n"; // row
219  //cout << "</div>\n"; // container
220  }
221 
222 /* cout << p("This simple process consists of three easy steps:");
223  cout << "<img src=\"" << oConfig.www_dir << "/img/ranking.jpeg\" align=\"right\"/>";
224  cout << ul();
225  cout << li("<a href=\"" + oConfig.soft_url + "?a=rf\">Register</a> or <a href=\"" + oConfig.soft_url + "?a=lf\">Login</a>");
226  if (investor_id == 0)
227  {
228  cout << li("STEP 1: Make an inventory of your assets and main cash-flows (income and expenses)");
229  cout << li("STEP 2: Set Your personal financial goals");
230  cout << li("STEP 3: Contemplate on the Feedback");
231  cout << p(" ");
232  cout << "<p>Next step: <button type=\"btn btn-primary\" class=\"btn btn-primary\" onclick=\"window.location.href=\'" + oConfig.soft_url + "?a=rf\'\">Register</button> or ";
233  cout << "<button type=\"btn btn-primary\" class=\"btn btn-primary\" onclick=\"window.location.href=\'" + oConfig.soft_url + "?a=lf\'\">Login</button></p>";
234  cout << p(" ");
235  }
236  else
237  {
238  cout << li("STEP 1: <a href=\"" + oConfig.soft_url + "?a=if\">Make an inventory of your assets and main cash-flows (income and expenses)</a>");
239  cout << li("STEP 2: <a href=\"" + oConfig.soft_url + "?a=gf\">Set Your personal financial goals</a>");
240  cout << li("STEP 3: <a href=\"" + oConfig.soft_url + "?a=f\">Contemplate on the Feedback</a>");
241  cout << p(" ");
242  cout << "<p>Next step: <button type=\"btn btn-primary\" onclick=\"window.location.href=\'" + oConfig.soft_url + "?a=gl\'\">Define Your Goals</button></p>";
243  cout << p(" ");
244  }
245  cout << ul();*/
246 }
247 
248 
249 
256 {
258  hh.show_toolBar("home",is_logged_in()?get_full_name():"");
259  hh.aside(t_aside["welcome"]);
260  //hh.show_home();
262  hh.footer("home","welcome");
263 }
264 
271 {
272  cout << "<h2>" << t_Register << "</h2>";
273  cout << "\n<form class=\"regform\" method=\"post\" action=\"" + oConfig.soft_url + "\">\n";
274  cout << "<fieldset>\n";
275  cout << "<ol>\n";
276  cout << "<li>\n";
277  cout << "<label for=\"email\">valid e-mail</label><input type=\"email\" name=\"email\" autofocus=\"true\" required placeholder=\"boss@universe.org\">\n";
278  cout << "</li>\n<li>";
279  cout << "<label for=\"password\">Password</label><input type=\"password\" name=\"password\" required value=\"\" autocomplete=\"off\" placeholder=\"min 8 characters, captial, special, etc.\" pattern=\"(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,}\" title=\"Password must be 8 or more characters with at least one number, an upper-case letter, a lower-case letter, and one special character!\">\n";
280  cout << "</li>\n<li>";
281  cout << "<label for=\"password1\">Repeat Password</label><input type=\"password\" name=\"password1\" required value=\"\" autocomplete=\"off\" placeholder=\"8-10 characters\" pattern=\"(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,}\" title=\"Password must be 8 or more characters with at lest one number, an upper-case letter, a lower-case letter, and one special character!\">\n";
282 
283  //was: pattern=\"^(?=.{8,})(?=.[a-z])(?=.[A-Z])(?=.[\\d])(?=.[\\W]).$\"
284 
285  cout << "</li>\n<li>";
286  cout << "<label for=\"first_name\">First Name</label><input type=\"text\" name=\"first_name\" placeholder=\"FirstName\">\n";
287  cout << "</li>\n<li>";
288  cout << "<label for=\"last_name\">Last Name</label><input type=\"text\" name=\"last_name\" placeholder=\"LastName\">\n";
289  cout << "</li>\n<li>";
290  cout << "<label for=\"currency\">Base Currency</label>" << oCurrency.dropDown_currency("EUR");
291  //<input type=\"text\" name=\"currency\" value=\"EUR\" required placeholder=\"EUR\">\n";
292  cout << "</li>\n<li>";
293  cout << "<label for=\"bdate\">birth date</label><input type=\"text\" id=\"datepicker\" data-date-format=\"yyyy-mm-dd\" data-date-viewmode=\"years\" required placeholder=\"yyyy-mm-dd\" title=\"Enter your birth date\" name=\"bdate\">\n";
294 // cout << "<script>$('#datepicker').datepicker('setEndDate', '2012-01-01')</script>";
295 
296  cout << "<script type=\"text/javascript\">$('#datepicker').datepicker({format: \"yyyy-mm-dd\", autoclose: true, todayBtn: false, setEndDate: \"2016-01-01\"});</script>";
297 
298  //cout << "<script type=\"text/javascript\">var nowTemp = new Date(); var now = new Date(nowTemp.getFullYear(), nowTemp.getMonth(), nowTemp.getDate(), 0, 0, 0, 0); $('#datepicker').datepicker({onRender: function(date) { return date.valueOf() <= now.valueOf() ? 'disabled' : '';}}).on('changeDate', function(ev) { checkout.hide();}).data('datepicker');</script>";
299 
300 
301  cout << "</li>\n<li>";
302  cout << "<label for=\"simtill\">simulate till age</label><input type=\"number\" required placeholder=\"90\" title=\"Till what age is this simulation relevant\" name=\"simtill\">\n";
303  cout << "</li>\n<li>";
304 // cout << "<label for=\"user_type\">e-mail</label><input type=\"radio\" name=\"user_type\" value=\"investor\" checked=\"checked\" />&nbsp;investor <input type=\"radio\" name=\"user_type\" value=\"advisor\" />&nbsp;advisor \n";
305  cout << "</li>\n<li>";
306  cout << "<input type=\"checkbox\" name=\"agree\" value=\"ragree\" required/>I hereby confirm that I agree with the "<< hh.terms_of_use() << ", the "<< hh.privacy_policy() << " and the " << hh.cookie_policy() << ".";
307  cout << "</li>\n<li>";
308  cout << "<button class=\"btn btn-primary btn-block\" type=\"submit\" value=\"Submit\">" << t_Register << "</button>\n&nbsp;";
309 // cout << "<button class=\"btn btn-primary\" type=\"reset\" value=\"reset\">Reset</button>\n&nbsp;";
310  cout << "</li></ol>\n";
311  cout << "</fieldset>";
312  cout << "<input type=\"hidden\" name=\"a\" value=\"re\" />&nbsp;\n";
313  cout << "</form>\n";
314 // cout << t_regFrm["requiredFields"];
315  cout << t_regFrm["policiesNote"];
316 }
317 
318 /* **********************************************
319  * register_form
320  *
321  * **********************************************/
323 {
325  hh.show_toolBar("register");
326  hh.aside(t_aside["register"]);
328  hh.footer("register","register");
329 }
330 
331 
336 {//cout << "<script>$('#sandbox-container input').datepicker({format: \"yyyy-mm-dd\"});</script>";
337  cout << "<br>\n";
338  cout << "<div class=\"well\">";
339  cout << "\n<form class=\"" << ((oConfig.layout == '2')?"regform":"") << "\" method=\"post\" action=\"" << oConfig.soft_url << "\">\n";
340  cout << "<fieldset>\n";
341  cout << "<ol>\n";
342  cout << "<li>\n";
343  cout << "<label for=\"email\">e-mail</label><input type=\"email\" name=\"email\" autofocus=\"true\" required placeholder=\"boss@universe.org\" value=\"" << user_name << "\">*\n";
344  cout << "</li>\n<li>";
345  cout << "<label for=\"password_old\">Old Password</label><input type=\"password\" name=\"password_old\" value=\"\" autocomplete=\"off\" placeholder=\"8-10 characters\" pattern=\"^(?=.{8,})(?=.*[a-z])(?=.*[A-Z])(?=.*[\\d])(?=.*[\\W]).*$\" title=\"Password must be 8 or more characters with at lest one number, an upper-case letter, a lower-case letter, and one special character!\">**\n";
346  cout << "</li>\n<li>";
347  cout << "<label for=\"password\">New Password</label><input type=\"password\" name=\"password\" value=\"\" autocomplete=\"off\" placeholder=\"8-10 characters\" pattern=\"^(?=.{8,})(?=.*[a-z])(?=.*[A-Z])(?=.*[\\d])(?=.*[\\W]).*$\" title=\"Password must be 8 or more characters with at lest one number, an upper-case letter, a lower-case letter, and one special character!\">**\n";
348  cout << "</li>\n<li>";
349  cout << "<label for=\"password1\">Repeat New Password</label><input type=\"password\" name=\"password1\" value=\"\" autocomplete=\"off\" placeholder=\"8-10 characters\" pattern=\"^(?=.{8,})(?=.*[a-z])(?=.*[A-Z])(?=.*[\\d])(?=.*[\\W]).*$\" title=\"Password must be 8 or more characters with at least one number, an upper-case letter, a lower-case letter, and one special character!\">**\n";
350  cout << "</li>\n<li>";
351  cout << "<label for=\"first_name\">First Name</label><input type=\"text\" name=\"first_name\" required placeholder=\"FirstName\" value=\"" << first_name << "\">*\n";
352  cout << "</li>\n<li>";
353  cout << "<label for=\"last_name\">Last Name</label><input type=\"text\" name=\"last_name\" required placeholder=\"LastName\" value=\"" << last_name << "\">*\n";
354  cout << "</li>\n<li>";
355  cout << "<label for=\"currency\">Currency</label>" << oCurrency.dropDown_currency(currency) << "*\n" ;
356  cout << "</li>\n<li>";
357  cout << "<label for=\"bdate\">birth date</label><input class=\"datepicker\" data-date-format=\"yyyy-mm-dd\" data-date-viewmode=\"years\" required placeholder=\"yyyy-mm-dd\" title=\"Enter your birth date\" name=\"bdate\" value=\"" << tm2DateStr(birth_date) << "\">*\n";
358  cout << "<script>$('.datepicker').datepicker()</script>";
359  cout << "</li>\n<li>";
360 
361 // cout << "<label for=\"user_type\">e-mail</label><input type=\"radio\" name=\"user_type\" value=\"investor\" checked=\"checked\" />&nbsp;investor <input type=\"radio\" name=\"user_type\" value=\"advisor\" />&nbsp;advisor *\n";
362  cout << "</li>\n<li>";
363 // cout << "<input type=\"checkbox\" name=\"agree\" value=\"ragree\" required/>I hereby confirm that I agree with Privacy and Cookie Policy.";
364 // cout << "</li>\n<li>";
365  cout << "<label for=\"simtill\">simulate till age</label><input type=\"number\" required placeholder=\"110\" title=\"Till what age is this simulation relevant\" name=\"simtill\" value=\"" << simulate_till_age << "\" >*\n";
366  cout << "</li>\n<li>";
367 
368  cout << "<button class=\"btn btn-primary\" type=\"submit\" value=\"Submit\">Save</button>\n&nbsp;";
369  cout << "<button class=\"btn btn-primary\" type=\"reset\" value=\"reset\">Reset</button>\n&nbsp;";
370  cout << "</li></ol>\n";
371  cout << "</fieldset>";
372  cout << "<input type=\"hidden\" name=\"a\" value=\"is\" />&nbsp;\n";
373  cout << "</form>\n";
374  cout << t_regFrm["requiredFields"];
375  cout << t_regFrm["policiesNote"];
376  cout << "<p>[**] only to be filled out IF you want to change the password, in that case all three fields have to be filled out.</p>";
377  cout << "</div>"; // well
378 }
379 
384 {
387 // hh.aside(t_aside["register"]);
389  hh.footer("","account");
390 }
391 
396 {
399  hh.aside(t_aside["disclaimer"]);
400  cout << t_disclaimer;
401  hh.footer("","");
402 }
403 
410 {
411  string uid, pwd, pwd1, fName, lName, currency, bdate, curr, simtill;
412  bool success = true;
413 
414  uid = cgi("email");
415  pwd = cgi("password");
416  pwd1 = cgi("password1");
417  fName = cgi("first_name");
418  lName = cgi("last_name");
419  curr = cgi("currency");
420  bdate = cgi("bdate");
421  simtill = cgi("simtill");
422 #ifdef DEBUG
423  debug_info += "<br>bdate: " + bdate;
424 #endif
425 // form_iterator fvalue1 = cgi.getElement(varName);
426 
427  if (pwd == pwd1)
428 // if (strcpm(pwd,pwd1) == 0)
429  {
430  if (set_user_name(uid) && set_first_name(fName) && set_last_name(lName) && set_password(pwd) && set_birth_date(bdate) && set_simulate_till_age(simtill) && set_currency(curr) && add_to_db())
431  {
432  investor_id = get_from_db(uid, pwd); //changes the error_message
433 // if (investor_id != 0) {cout << "Set-Cookie:iid=" << std::to_string(investor_id) << ";\n";}
434  }
435  else
436  {
437  success = false;
438  }
439  }
440  else
441  {
442  error_message = error_message + t_errMsg["pwdsMatch"];
443  error_message = error_message + "<li>pwd: " + pwd + ", pwd1: " + pwd1 + "</li>";
444  success = false;
445  }
446  if (success)
447  {
449  hh.show_toolBar("goals",get_full_name());
450 //xxx oGoal.list(investor_id, true); // list existing and show input form for new
452  hh.aside(t_aside["goalInfo"]);
453 //xxx hh.footer("assets","goal");
454  hh.footer("","goal_help");
455  }
456  else
457  {
458  hh.header(0);
459  hh.show_toolBar("register");
461  hh.aside(t_aside["registerFail"]);
462  hh.footer("register","register");
463  }
464 }
465 
471 {
472  string uid, pwdold, pwd, pwd1, fName, lName, currency, bdate, curr, simtill;
473  bool success = true;
474 
475  uid = cgi("email");
476  pwdold = cgi("password_old");
477  pwd = cgi("password");
478  pwd1 = cgi("password1");
479  fName = cgi("first_name");
480  lName = cgi("last_name");
481  curr = cgi("currency");
482  bdate = cgi("bdate");
483  simtill = cgi("simtill");
484 #ifdef DEBUG
485  debug_info += "<br>bdate: " + bdate;
486 #endif
487 // form_iterator fvalue1 = cgi.getElement(varName);
488 
489  if (set_user_name(uid) && set_first_name(fName) && set_last_name(lName) && set_birth_date(bdate) && set_currency(curr) && set_simulate_till_age(simtill) && save())
490  {
491  investor_id = get_from_db(uid, pwd); //changes the error_message
492 // if (investor_id != 0) {cout << "Set-Cookie:iid=" << std::to_string(investor_id) << ";\n";}
493  }
494  else
495  {
496  success = false;
497  }
498 
499  if (pwdold != "" && pwd == pwd1)
500  {
501  cout << "<br>PASSWORDCHANGE not implemented yet, sorry!"; //TODO
503  error_message = error_message + t_errMsg["pwdsMatch"];
504  error_message = error_message + "<li>pwd: " + pwd + ", pwd1: " + pwd1 + "</li>";
505  success = false;
506  }
507  if (success)
508  {
510  hh.show_toolBar("goals",get_full_name());
511  oGoal.list(investor_id, true); // list existing and show input form for new
512  hh.aside(t_aside["welcomeBack1"] + get_full_name() + t_aside["welcomeBack1"]);
513  hh.footer("goals","asset");
514  }
515  else
516  {
517  //show the account form again ...
518  account_form();
519  }
520 }
521 
522 
523 /* ***********************************************
524  * show_login_form_body
525  * ***********************************************
526  */
528 {
529  cout << "<h2>" << t_Login << "</h2>";
530  cout << "<form class=\"loginform\" method=\"post\" action=\"" + oConfig.soft_url + "\">";
531  cout << "<fieldset id=\"login_form\">\n";
532  cout << "<ol>\n";
533  cout << "<li>\n";
534  cout << "<label for=\"email\">e-mail</label><input type=\"email\" name=\"email\" autofocus=\"true\" required placeholder=\"boss@universe.org\">\n";
535  cout << "</li>\n<li>";
536  cout << "<label for=\"password\">Password</label><input type=\"password\" name=\"password\" >\n";
537  cout << "</li>\n<li>";
538  cout << "<button class=\"btn btn-primary btn-block\" type=\"submit\" value=\"Submit\">" << t_Login << "</button>\n&nbsp;";
539 // cout << "<button class=\"btn btn-primary\" type=\"reset\" value=\"Reset\">Clear Form</button>\n&nbsp;";
540  cout << "<input type=\"hidden\" name=\"a\" value=\"le\" />&nbsp;\n";
541  cout << "</li></ol>\n";
542  cout << "</fieldset>";
543  cout << "</form>\n";
544 // cout << "<p>(*) Required fields.</p>";
545 }
546 
547 
548 /* **********************************************
549  * login_form
550  *
551  * **********************************************/
553 {
554  hh.header(0);
555  hh.show_toolBar("login");
556  hh.aside(t_aside["login"]);
558  hh.footer("login", "login");
559 }
560 
561 
562 /* ***********************************************
563  * login_exec
564  * ***********************************************
565  */
567 {
568  string uid, pwd;
569  error_message = ""; // clear the error messsage of this object
570  uid = cgi("email");
571  pwd = cgi("password");
572 
573  investor_id = get_from_db(uid, pwd); //changes the error_message
574  if (investor_id != 0)
575  {
577  login();
578  hh.show_toolBar("personalize",get_full_name());
580  hh.aside(t_aside["welcomeBack1"] + get_full_name() + t_aside["welcomeBack2"]);
581  hh.footer("personalize","personalize");
582  }
583  else
584  {
585  hh.header(0);
586  hh.show_toolBar("login");
588  hh.footer("login", "login");
589  }
590 }
591 
596 {
597  int i;
598  this->load_preferences(); // loads the experience, knowledge and desirability (includes set_max_exposure)
599 
600  //cout << "<table width=\"100%\" class=\"prefTable\">";
601  cout << "<tr><th>" << t_Asset_Class << "</th>"
602  << "<th>" << t_Experience << "</th>"
603  << "<th>" << t_Knowledge << "</th>"
604  << "<th>" << t_Desirability << "</th>"
605  << "<th>" << t_Max_Exp << "</th></tr>";
606  for(i=1; i <= NBR_ASSET_CLASSES; i++)
607  {
608  cout << "<tr>";
609  cout << "<td>" << asset_class_names[i] << "</td>";
610  cout << "<td><input type=\"number\" min=\"1\" max=\"5\" name=\"experience" << to_string(i) << "\" required size=\"1\" value=\"" << experience[i] << "\"></td>";
611  cout << "<td><input type=\"number\" min=\"1\" max=\"5\" name=\"knowledge" << to_string(i) << "\" required size=\"1\" value=\"" << knowledge[i] << "\"></td>";
612  cout << "<td><input type=\"number\" min=\"1\" max=\"5\" name=\"desirability" << to_string(i) << "\" required size=\"1\" value=\"" << desirability[i] << "\"></td>";
613  cout << "<td>" << max_exposure[i] << "</td>"; //the limit in %
614  cout << "</tr>";
615  }
616  // done byt the close-function: cout << "</table>";
617 }
618 
619 
624 {
625  int ac;
626 // cout << "<table width=\"100%\" class=\"prefTable\">";
627  cout << "<tr><th> Asset Class </th><th>" << t_personalize["ER"]["theader"] << "</th><th></th></tr>";
628  for(ac=1; ac <= NBR_ASSET_CLASSES; ac++)
629  {
630  cout << "<tr>";
631  cout << "<td>" << asset_class_names[ac] << "</td>";
632  cout << "<td><input step=\"0.1\" type=\"number\" min=\"-10\" max=\"25\" name=\"ER" << to_string(ac) << "\" required size=\"1\" value=\"" << round2str(ER[ac] * 100,1) << "\"></td><td>%</td>";
633  cout << "</tr>";
634  }
635 }
636 
641 {
642  int ac;
643 // cout << "<table width=\"100%\" class=\"prefTable\">";
644  cout << "<tr><th>" << t_Asset_Class << "</th><th>" << t_personalize["vol"]["theader"] << "</th><th></th></tr>";
645  for(ac=1; ac <= NBR_ASSET_CLASSES; ac++)
646  {
647  cout << "<tr>";
648  cout << "<td>" << asset_class_names[ac] << "</td>";
649  cout << "<td><input step=\"0.1\" type=\"number\" min=\"0\" max=\"100\" name=\"vol" << to_string(ac) << "\" required size=\"1\" value=\"" << round2str(sqrt(covar[ac][ac]) * 100,1) << "\"></td><td>%</td>";
650  cout << "</tr>";
651  }
652 }
653 
658 {
659  int ac;
660  cout << "<tr><th>" << t_Asset_Class << "</th>";
661  cout << "<th>" << t_personalize["ER"]["theader"] << "</th>";
662  cout << "<th>" << t_personalize["vol"]["theader"] << "</th>";
663  cout << "</tr>";
664  for(ac=1; ac <= NBR_ASSET_CLASSES; ac++)
665  {
666  cout << "<tr>";
667  cout << "<td>" << asset_class_names[ac] << "</td>";
668  cout << "<td><input step=\"0.1\" type=\"number\" min=\"-10\" max=\"25\" name=\"ER" << to_string(ac) << "\" required size=\"1\" value=\"" << round2str(ER[ac] * 100,1) << "\">%</td>";
669  cout << "<td><input step=\"0.1\" type=\"number\" min=\"0\" max=\"100\" name=\"vol" << to_string(ac) << "\" required size=\"1\" value=\"" << round2str(sqrt(covar[ac][ac]) * 100,1) << "\">%</td>";
670  cout << "</tr>";
671  }
672 }
673 
674 
679 {
680  int ac_i, ac_j;
681  float covar_ij;
682 // cout << "<table width=\"100%\" class=\"covar\">";
683  cout << "<tr><th></th>";
684  for (ac_i=1; ac_i <= NBR_ASSET_CLASSES; ac_i++) cout << "<th>" << asset_class_names[ac_i] << "</th>";
685  cout << "</tr>";
686  for (ac_i=1; ac_i <= NBR_ASSET_CLASSES; ac_i++)
687  {
688  cout << "<tr>";
689  cout << "<th>" << asset_class_names[ac_i] << "</th>";
690  for(ac_j=1; ac_j <= NBR_ASSET_CLASSES; ac_j++)
691  {
692  //cout << "<covar[" << ac_i << ", " << ac_j << "] = " << covar[ac_i][ac_j];
693  if (covar[ac_i][ac_i] != 0 && covar[ac_j][ac_j] != 0)
694  {
695  covar_ij = covar[ac_i][ac_j] / (sqrt(covar[ac_i][ac_i] * covar[ac_j][ac_j]));
696  }
697  else
698  {
699  covar_ij = 0;
700  error_message = error_message + "<li>ERRNO200: incorrect covar matrix</li>";
701  }
702  cout << "<td>" << "<input " << ((ac_i <= ac_j)?"disabled":"") << " step=\"1\" type=\"number\" min=\"-100\" max=\"100\" name=\"corr" << add0(ac_i)<< add0(ac_j) << "\" required size=\"1\" value=\"" << round2str(covar_ij * 100.0, 0) << "\"></td>";
703  }
704  cout << "</tr>";
705  }
706 }
707 
708 
713 {
714 
715  asset_class_names = oAssetClass.get_assetList(); // asset_class_names is a variable of the investor class
717  cout << t_personalize1;
718 
719  cout << "<div class=\"panel-group\" id=\"accordion2\">";
720 
721  parse_form_open_personalize("general");
722  cout << "<tr>\n";
723 
724 
725  cout << "<td><label for=\"currency\">Currency*</label></td><td>" << oCurrency.dropDown_currency(currency) << "</td><td>" << t_info_curr <<"</td>\n</tr>";
726  cout << "<tr><td><label for=\"bdate\">birth date*</label></td><td><input class=\"datepicker\" data-date-format=\"yyyy-mm-dd\" data-date-viewmode=\"years\" required placeholder=\"yyyy-mm-dd\" title=\"Enter your birth date\" name=\"bdate\" value=\"" << tm2DateStr(birth_date) << "\"></td><td>" << t_info_bdate << ".</td>\n</tr>";
727 
728  cout << "<script>$('.datepicker').datepicker()</script>";
729 
730  cout << "<tr><td><label for=\"simtill\">simulate till age*</label></td><td><input type=\"number\" required placeholder=\"110\" title=\"Till what age is this simulation relevant\" name=\"simtill\" value=\"" << simulate_till_age << "\" ></td><td>" << t_info_simtill << "</td></tr>";
731  parse_form_close_personalize("general", false);
732 /*
733  *moved to extra info:
734  cout << t_personalize_concepts;
735  cout << t_personalize_scoring;
736  */
739  parse_form_close_personalize("prefs", false);
740 
741 // cout << t_regFrm["requiredFields"];
742  this->load_ER(this->investor_id); // loads the this->ER map
743  this->load_covar(this->investor_id); // loads the this->coavar map of maps
744 
745  if (oConfig.merge_ER_vol)
746  {
750  }
751  else
752  {
756 
757 
761  }
762 
766 
767  cout << "</div>"; // the accordion2
768  cout << "<br clear=\"all\">";
769 }
770 
775 {
776  cout << "\n<div class=\"panel panel-default\">";
777  cout << "\n<div class=\"panel-heading\">";
778  cout << "<a data-toggle=\"collapse\" data-parent=\"#accordion2\" data-target=\"#collapse" << the_content << "\">";
779  cout << "<h3>" << t_personalize[the_content]["title"] << "&nbsp;<span class=\"glyphicon glyphicon-triangle-bottom\"></span></h3></a>";
780  cout << "</div>";
781  cout << "\n<div id=\"collapse" << the_content <<"\" class=\"panel-collapse collapse\">";
782  cout << "\n<div class=\"panel-body\">";
783  switch (oConfig.layout)
784  {
785  case '1' :
786  cout << t_personalize[the_content]["info"];
787  break;
788  case '2' :
789 // cout << t_personalize[the_content]["info"];
790  bs_modal(t_show_extra_info, t_personalize[the_content]["info"], "modal" + the_content);
791  break;
792  default:
793  cout << t_personalize[the_content]["info"];
794  }
795  cout << "\n<form method=\"post\" action=\"" + oConfig.soft_url + "\">\n";
796  cout << "<fieldset>\n";
797  cout << "\n<table class=\"" << the_content << "\">";
798 }
799 
800 
804 void investor_ui::parse_form_close_personalize(string the_content, bool show_reload)
805 {
806  cout << "</table>";
807  cout << "<button class=\"btn btn-primary\" type=\"submit\" name =\"a\" value=\"ps\">Save " << t_personalize[the_content]["content"] << "</button>\n&nbsp;";
808  cout << "<button class=\"btn btn-primary\" type=\"reset\" value=\"reset\">Undo Last Changes</button>\n&nbsp;";
809  if (show_reload) cout << "<button class=\"btn btn-primary\" type=\"submit\" name =\"a\" value=\"" << "r" << the_content << "\">" << t_reload << " " << t_personalize[the_content]["content"] << "</button>\n&nbsp;";
810  //cout << button_to("r" + the_content, t_reload + " " + t_personalize[the_content]["content"], 's');
811  cout << "</fieldset>";
812 // cout << "<input type=\"hidden\" name=\"a\" value=\"ps\" />&nbsp;\n";
813  cout << "<input type=\"hidden\" name=\"content\" value=\"" << the_content << "\" />&nbsp;\n";
814  cout << "<input type=\"hidden\" name=\"uid\" value=\"" << investor_id << "\" />&nbsp;\n";
815  cout << "</form>\n";
816  cout << "<p><a data-toggle=\"collapse\" data-parent=\"#accordion2\" data-target=\"#collapse" + the_content + "\">";
817  cout << t_collapse << "&nbsp;<span class=\"glyphicon glyphicon-triangle-top\"></span></a></p>";
818  cout << "</div></div></div>" << endl;
819 }
820 
821 
822 
827 {
829  hh.show_toolBar("personalize",get_full_name());
830  hh.aside(t_aside["personalize"]);
832  hh.footer("personalize","personalize");
833 }
834 
839 {
841 
842  string the_content = cgi("content"); // the content that is being updated
843  //hh.header(investor_id);
844  if (the_content == "general") {personalize_set_general(); save_preferences();}
845  else if (the_content == "prefs") {personalize_set_prefs(); save_preferences();}
846  else if (the_content == "ER") {personalize_set_ER(); save_ER(this->investor_id);}
847  else if (the_content == "vol") {personalize_set_vol(); save_covar(this->investor_id);}
848  else if (the_content == "ERvol") // in case ER and vol were presented in one table
849  {
852  save_ER(this->investor_id);
853  save_covar(this->investor_id);
854  }
855  else if (the_content == "corr") {personalize_set_corr(); save_covar(this->investor_id);}
856 
857  set_max_exposure(); // to have them ready
858  // if relevant show an error message and show the screeen again
860 }
861 
866 {
867  string s, uid, currency, bdate, curr, simtill, ac;
868 
869  // process the general information
870  uid = cgi("uid");
871  curr = cgi("currency");
872  bdate = cgi("bdate");
873  simtill = cgi("simtill");
874 
875  if (set_birth_date(bdate) && set_currency(curr) && set_simulate_till_age(simtill) && save())
876  {
877 // investor_id = load_from_db(uid);
878  }
879  else
880  {
881  error_message = error_message + "<li>I failed to save essential user information, please contact an administrator -- #ErrNo009</li>";
882  }
883 }
884 
885 
890 {
891  string s, ac;
892  int i;
893 
894  // process the asset allocation related information
895  for(i=1; i <= NBR_ASSET_CLASSES; i++)
896  {
897  ac = to_string(i);
898  s = cgi("experience" + ac);
899  set_scale("experience", i, atoi(s.c_str()));
900  s = cgi("knowledge" + ac);
901  set_scale("knowledge", i, atoi(s.c_str()));
902  s = cgi("desirability" + ac);
903  set_scale("desirability",i, atoi(s.c_str()));
904  }
905 }
906 
911 {
912  int ac;
913  for (ac=1; ac <= NBR_ASSET_CLASSES; ac++)
914  {
915  ER[ac] = atof((cgi("ER" + to_string(ac))).c_str()) / 100;
916  }
917 }
918 
923 {
924  load_covar(investor_id); // load all the values and overwrite in the next lines a few
925  int ac;
926  for (ac=1; ac <= NBR_ASSET_CLASSES; ac++)
927  {
928  covar[ac][ac] = pow(atof((cgi("vol" + to_string(ac))).c_str()) / 100, 2);
929  }
930 }
931 
936 {
937  load_covar(investor_id); // needed because we need the volatilities
938  int ac_i, ac_j;
939  for (ac_i=1; ac_i <= NBR_ASSET_CLASSES; ac_i++)
940  {
941  for (ac_j=1; ac_j <= NBR_ASSET_CLASSES; ac_j++)
942  {
943  if (ac_i > ac_j)
944  {
945  covar[ac_i][ac_j] = covar[ac_j][ac_i] = atof((cgi("corr" + add0(ac_i) + add0(ac_j))).c_str()) / 100 * sqrt(covar[ac_i][ac_i] * covar[ac_j][ac_j]);
946  //cout << "<br>CGI: " << cgi("corr" + add0(ac_i) + add0(ac_j)) << " | covar[" << ac_i << "][" << ac_j << "] = " << covar[ac_i][ac_j] << " | covar_ii " << covar[ac_i][ac_i];
947  }
948  }
949  }
950 }
951 
958 {
959  if (action == "rER") reload_ER(investor_id);
960  else if (action == "rvol") reload_covar(investor_id, 'v');
961  else if (action == "rERvol")
962  {
965  }
966  else if (action == "rcorr") reload_covar(investor_id, 'c');
967  else
968  {
969  error_message = error_message + "<li>unexpected action passed to reload -- Error Number ER656</li>";
970  }
972 // error_message = error_message + "<LI>action=" + action + "</li>";
973 }
974 
975 
976 
977 /* **********************************************
978  * show_inventory_form
979  *
980  * **********************************************/
982 {
984  hh.show_toolBar("assets",get_full_name());
986  hh.footer("assets","asset");
987 }
988 
989 /* **********************************************
990  * show_inventory_form_body
991  *
992  * **********************************************/
994 {
995 // cout << h2("Assets / Current Posessions");
996  cout << "<form method=\"post\" action=\"" + oConfig.soft_url + "?a=aa\">";
997  cout << "<table class=\"asset\">\n";
998  cout << "<tr>";
999  cout << "<th>Description</th><th>Asset Class</th><th>Amount</th><th>Currency</th><th>Actions</th>";
1000  cout << "</tr>\n";
1002  cout << "<tr>";
1003  cout << "<td><input type=\"text\" name=\"description\" required ></td>" ;
1004  cout << "<td>" << oAssetClass.dropDown_assetClass() << "</td>" ;
1005  cout << "<td><input type=\"number\" min=\"0\" name=\"amount\" required placeholder=\"1000\" title=\"Please enter a positive number\"></td>" ;
1006  cout << "<td>" << oCurrency.dropDown_currency() << "</td>" ;
1007 
1008  switch (oConfig.layout)
1009  {
1010  case '1' :
1011  cout << "<td><button type=\"submit\" value=\"Submit\"><img src=\"" << oConfig.css_dir << "plus.svg\" alt=\"add\" width=\"16\"></button></td>" ;
1012  break;
1013  case '2' :
1014  cout << "<td><button type=\"submit\" value=\"Submit\" data-toggle=\"tooltip\" title=\"" << t_save << "\"><span class=\"glyphicon glyphicon-ok\" style=\"color:green\"></span></button>";
1015  cout << "<button type=\"submit\" value=\"Submit\" data-toggle=\"tooltip\" title=\"" << t_reset << "\"><span class=\"glyphicon glyphicon-chevron-left\" style=\"color:blue\"></span></button>" ;
1016  break;
1017  default :
1018  cout << "<td><button type=\"reset\" data-toggle=\"tooltip\" title=\"" << t_reset << "\"><span class=\"glyphicon glyphicon-chevron-left\" style=\"color:blue\"></span></button></td>" ;
1019  break;
1020  }
1021 
1022  cout << "</table>\n";
1023  cout << "<input type=\"hidden\" name=\"iid\" value=\"" << investor_id << "\" />\n&nbsp;";
1024  cout << "</form>";
1025 
1026 // cout << h2("Future Savings (Cash Flows)"); // cout << p("... to be added (not implemented yet).");
1027 
1028 }
1029 
1030 
1031 
1032 /* ***********************************************
1033  * asset_add
1034  * ***********************************************
1035  */
1037 //cgicc::Cgicc &formData
1038 {
1040 // string iid = cgi("iid");
1041  string desc = cgi("description");
1042  string aclass = cgi("asset_class");
1043  string amnt = cgi("amount");
1044  string curr = cgi("currency");
1045 
1046  error_message = "";
1047 
1048  if (oAsset.set_investor(to_string(investor_id)) && oAsset.set_description(desc) && oAsset.set_asset_class(aclass) && oAsset.set_amount(amnt) && oAsset.set_currency(curr) && oAsset.save())
1049  {
1050  cout << "<p class=\"markup\">New asset, \"" << desc << "\", successfully added.</p>";
1051  }
1052  hh.show_toolBar("assets",get_full_name());
1054  hh.footer("assets","asset");
1055 }
1056 
1062 {
1063  string iid = cgi("iid");
1064  string aid = cgi("aid");
1065  error_message = "";
1066 
1067  set_investor_id(iid);
1069  hh.show_toolBar("assets",get_full_name());
1070 
1071  if (oAsset.set_asset_id(aid))
1072  {
1073  oAsset.load();
1075  }
1076 
1077  hh.footer("");
1078 }
1079 
1080 /* ***********************************************
1081  * assete_Save
1082  * ***********************************************
1083  */
1085 {
1086  string aid = cgi("aid");
1087  string iid = cgi("iid");
1088  string desc = cgi("description");
1089  string aclass = cgi("asset_class");
1090  string amnt = cgi("amount");
1091  string curr = cgi("currency");
1092 
1093  if (oAsset.set_asset_id(aid) && oAsset.set_investor(iid) && oAsset.set_description(desc) && oAsset.set_asset_class(aclass) && oAsset.set_amount(amnt) && oAsset.set_currency(curr) && oAsset.save())
1094  {
1095  cout << "<p class=\"markup\">Changes to asset, \"" << desc << "\", successfully saved.</p>";
1096  }
1097 
1098  investor_id = atoi(iid.c_str());
1100  hh.show_toolBar("assets",get_full_name());
1102  hh.footer("assets","asset");
1103 }
1104 
1105 
1106 /* ***********************************************
1107  * asset_delete
1108  * ***********************************************
1109  */
1111 {
1112  string iid = cgi("iid");
1113  string aid = cgi("aid");
1114 
1115  if (set_investor_id(iid))
1116  {
1117  oAsset.set_asset_id(aid);
1118  if (oAsset.asset_delete())
1119  {
1120  std_message = std_message + "<p class=\"markup\">Asset #" + aid + " successfully deleted.</p>";
1121  }
1122  }
1124  hh.show_toolBar("assets",get_full_name());
1126  hh.footer("assets","asset");
1127 }
1128 
1129 
1134 {
1136  hh.show_toolBar("goals",get_full_name());
1137  cout << "<div class=\"clearBoth\">\n";
1138  oGoal.list(investor_id, true);
1139  cout << "</div>\n";
1140  hh.aside(t_aside["goalInfo"]);
1141  hh.footer("goals","goal");
1142 }
1143 
1144 
1145 /* ***********************************************
1146  * goal_add
1147  * ***********************************************
1148  */
1150 //cgicc::Cgicc &formData
1151 {
1152  bool success = false;
1153  if (oGoal.load_fromEnv()) {success = oGoal.save();}
1154  if (success)
1155  {
1156  std_message = std_message + "<p class=\"markup\">New goal, \"" + oGoal.tbl[2].get_sValue() + "\", successfully added.</p>";
1157  }
1158  else
1159  {
1160  //TODO
1161  }
1163  hh.show_toolBar("goals",get_full_name());
1165  hh.footer("goals","goal");
1166 }
1167 
1168 
1169 /* ***********************************************
1170  * goal_edit
1171  * ***********************************************
1172  */
1174 {
1175  oGoal.load_fromEnv();
1176 
1178  hh.show_toolBar("goals",get_full_name());
1179 
1180  if (oGoal.exists())
1181  {
1182  oGoal.load_fromDB();
1184  }
1185 
1186  hh.footer("goals","goal");
1187 }
1188 
1189 /* ***********************************************
1190  * goale_Save
1191  * ***********************************************
1192  */
1194 {
1195  if (oGoal.load_fromEnv() && oGoal.save())
1196  {
1197  std_message = std_message + "<p class=\"markup\">Changes to goal, \"" + oGoal.tbl[3].get_sValue() + "\", successfully saved.</p>";
1198  }
1200  hh.show_toolBar("goals",get_full_name());
1201  oGoal.list(investor_id, true);
1202  hh.footer("goals","goal");
1203 }
1204 
1205 /* ***********************************************
1206  * goal_delete
1207  * ***********************************************
1208  */
1210 {
1212  string gid = cgi("gid");
1213  if (oGoal.load_fromEnv() && oGoal.delete_bona())
1214 
1215  {
1216  cout << "<p class=\"markup\">Goal #" << gid << "; successfully deleted.</p>";
1217  }
1218  hh.show_toolBar("goals",get_full_name());
1219  oGoal.list(investor_id, true);
1220  hh.footer("goals","goal");
1221 }
1222 
1223 
1224 /* **********************************************
1225  * cash_flow_list ***********************************
1226  * **********************************************
1227  * **********************************************/
1229 {
1231  hh.show_toolBar("cfs",get_full_name());
1232  cout << "<div class=\"clearBoth\">\n";
1233  oCF.list(investor_id, true); // list existing ans show input form for new
1234  cout << "</div>\n";
1235  hh.aside(t_aside["cash_flowInfo"]);
1236  hh.footer("cfs","cash_flow");
1237 }
1238 
1239 
1240 /* ***********************************************
1241  * cash_flow_add
1242  * ***********************************************
1243  */
1245 //cgicc::Cgicc &formData
1246 {
1247  bool success = false;
1248  if (oCF.load_fromEnv()) {success = oCF.save();}
1249  if (success)
1250  {
1251  std_message = std_message + "<p class=\"markup\">New cash flow, \"" + oCF.tbl[2].get_sValue() + "\", successfully added.</p>";
1252  }
1253 
1255  hh.show_toolBar("cfs",get_full_name());
1256  oCF.list(investor_id);
1257  hh.footer("cfs","cash_flow");
1258 }
1259 
1260 
1261 /* ***********************************************
1262  * cash_flow_edit
1263  * ***********************************************
1264  */
1266 {
1267  oCF.load_fromEnv();
1268 
1270  hh.show_toolBar("cfs",get_full_name());
1271 
1272  if (oCF.exists())
1273  {
1274  oCF.load_fromDB();
1276  }
1277 
1278  hh.footer("cfs","cash_flow");
1279 }
1280 
1281 /* ***********************************************
1282  * cash_flowe_Save
1283  * ***********************************************
1284  */
1286 {
1287  if (oCF.load_fromEnv() && oCF.save())
1288  {
1289  std_message = std_message + "<p class=\"markup\">Changes to cash flow, \"" + oCF.tbl[3].get_sValue() + "\", successfully saved.</p>";
1290  }
1292  hh.show_toolBar("cfs",get_full_name());
1293  oCF.list(investor_id, true);
1294  hh.footer("cfs","cash_flow");
1295 }
1296 
1297 /* ***********************************************
1298  * cash_flow_delete
1299  * ***********************************************
1300  */
1302 {
1303  string gid = cgi("gid");
1304  if (oCF.load_fromEnv() && oCF.delete_bona())
1305  {
1306  std_message = std_message + "<p class=\"markup\">CF #" + gid + "; successfully deleted.</p>";
1307  }
1308 
1310  hh.show_toolBar("cfs",get_full_name());
1311  oCF.list(investor_id, true);
1312  hh.footer("cfs","cash_flow");
1313 }
1314 
1315 /*************************************************************************************/
1320 /* ******************************************************
1321  * bool set_user_name(string s);
1322  *
1323  * ******************************************************
1324  */
1325 bool investor_ui::set_user_name(const std::string& s) {
1326  bool rc = true;
1327  if (s.length() < 4)
1328  {
1329  rc = false;
1330  error_message = error_message + "<li>user_name is too short (at least 4 characters required)</li>";
1331  }
1332  /* TODO: check if it is a valid email address *
1333  */
1334  if (rc) {user_name = s;}
1335  return rc;
1336 }
1337 
1338 /* ******************************************************
1339  * bool set_first_name(const std::string& s);
1340  *
1341  * ******************************************************
1342  */
1343 bool investor_ui::set_first_name(const std::string& s) {
1344  bool rc = true;
1345  if (s.length() < 2)
1346  {
1347  rc = false;
1348  error_message = error_message + "<li>first_name is too short (at least 2 characters required)</li>";
1349  }
1350  if (rc) {first_name = s;}
1351  return rc;
1352 }
1353 /* ******************************************************
1354  * bool set_last_name(const std::string& s);
1355  *
1356  * ******************************************************
1357  */
1358 bool investor_ui::set_last_name(const std::string& s) {
1359  bool rc = true;
1360  if (s.length() < 2)
1361  {
1362  rc = false;
1363  error_message = error_message + "<li>last_name is too short (at least 2 characters required)</li>";
1364  }
1365  if (rc) {last_name = s;}
1366  return rc;
1367 }
1368 /* ******************************************************
1369  * bool set_password(const std::string& s);
1370  *
1371  * ******************************************************
1372  */
1373 bool investor_ui::set_password(const std::string& s) {
1374  bool rc = true;
1375  if (s.length() < 4)
1376  {
1377  rc = false;
1378  error_message = error_message + "<li>password is too short (at least 4 characters required)</li>";
1379  }
1380  if (rc) {password = s;}
1381  return rc;
1382 }
1383 
1389 bool investor_ui::set_currency(const std::string& s) {
1390  bool rc;
1391  if (oCurrency.set_curr(s)) //this returns true if the currency exists
1392  {
1393  this->currency = s;
1394  rc = true;
1395  }
1396  else
1397  {
1398  rc = false;
1399  error_message = error_message + "<li>not a valid currency</li>";
1400  }
1401  return rc;
1402 }
1403 
1404 
1410 bool investor_ui::set_investor_id(const std::string& s) {
1411  int a = atoi(s.c_str());
1412  bool rc = true;
1413 
1414  if (this->exists(a))
1415  {
1416  investor_id = a;
1417  }
1418  else
1419  {
1420  rc = false;
1421  error_message = error_message + "<li>Sorry, invalid user</li>";
1422  investor_id = 0;
1423  }
1424  return rc;
1425 }
1426 
1430 bool investor_ui::set_birth_date(const std::string& s)
1431 {
1432  bool rc = true;
1433  if (!is_valid_dateStr(s))
1434  {
1435  rc = false;
1436  error_message = error_message + "<li>invalid birth_date:" + s + "</li>";
1437  }
1438 // cout << "[" << s << "]";
1439  if (rc) {dateStr2tm(s, &birth_date);}
1440  return rc;
1441 }
1442 
1447 bool investor_ui::set_simulate_till_age(const std::string& s)
1448 {
1449  bool rc = true;
1450  float sim_till = atof(s.c_str());
1451  if (sim_till <= age(0) + MIN_YEARS_TO_SIMULATE)
1452  {
1453  rc = false;
1454  error_message = error_message + "<li>\"simulate till age\" should be higher than your current age + " + to_string(MIN_YEARS_TO_SIMULATE) + " years!</li>";
1455  }
1456  simulate_till_age = (rc) ? (int)round(sim_till) : SIMULATE_TILL_DEFAULT;
1457  return rc;
1458 }
1459 
1464 {
1465  std::string s;
1466  bool rc = false;
1467  // first prune all users that should be logged-out!
1468  s = "UPDATE " + oConfig.tbl_prefix + "_investors SET is_logged_in = 0 WHERE TIMESTAMPDIFF(MINUTE, last_activity_at, CURRENT_TIMESTAMP()) > 30;";
1469  if (db.runSQL(s)) {} else {error_message = error_message + "<li>Please contact us.</li>";}
1470 
1471  // then check if this particular user is logged in
1472  s = "SELECT is_logged_in FROM " + oConfig.tbl_prefix + "_investors WHERE investor_id = " + std::to_string(investor_id) + ";";
1473  db.res = db.stmt->executeQuery(s);
1474  while (db.res->next())
1475  {
1476  if (db.res->getString("is_logged_in") == "1") {rc = true;} else {rc = false;}
1477  }
1478  return rc;
1479 }
1480 
1485 {
1486  std::string s;
1487  // first prune all users that should be logged-out!
1488  s = "UPDATE " + oConfig.tbl_prefix + "_investors SET is_logged_in = 0 WHERE investor_id = " + to_string(investor_id) + ";";
1489  cout << s;
1490  if (db.runSQL(s)) {} else {error_message = error_message + "<li>Please contact us, and provide the code \"i_ui::lo\".</li>";}
1491  home_screen();
1492 }
1493 
1495 {
1496  const CgiEnvironment& env = cgi.getEnvironment(); // const_form_iterator name = cgi.getElement("name"); // const_form_iterator value = cgi.getElement("value");
1497  const_cookie_iterator iter;
1498  bool rc = false;
1499 
1500  for(iter = env.getCookieList().begin(); iter != env.getCookieList().end(); ++iter)
1501  {if (iter->getName() == "iid") {rc = set_investor_id(iter->getValue());}}
1502 
1503 #ifdef DEBUG
1504  debug_info = debug_info + "investor_id (from cookie) = " + to_string(investor_id) + "<br/>";
1505 #endif
1506 
1507  if (!(is_logged_in()))
1508  {
1509  investor_id = 0;
1510 #ifdef DEBUG
1511  debug_info = debug_info + "user is not logged in<br/>";
1512 #endif
1513  }
1514  return rc;
1515 }
1516 
1517 
1524 {
1525  std::string s;
1526  s = "UPDATE " + oConfig.tbl_prefix + "_investors SET is_logged_in = 1, last_login_at = NOW() , last_activity_at = NOW() WHERE investor_id=" + std::to_string(investor_id) + ";";
1527  if (db.runSQL(s)) {} else {error_message = error_message + "<li>Please contact us - login error.</li>";}
1528 }
1529 
1530 
1531 
1538 {
1539  std::string s;
1540  s = "UPDATE " + oConfig.tbl_prefix + "_investors SET is_logged_in = 1, last_activity_at = NOW() WHERE investor_id=" + std::to_string(investor_id) + ";";
1541  if (db.runSQL(s)) {} else {error_message = error_message + "<li>Please contact us - login error.</li>";} }
1542 
1543 
1549 void investor_ui::parse_goal_box(investment_problem * oInvProbl, int g, string s_var, string s_desc)
1550 {
1551  string color_box = (goal_type_i2s[oInvProbl->goalZ[g].goal_type] == "unallocated") ? "greyBox" : hh.get_box_color_class(oInvProbl->goalZ[g].color);
1552 
1553  string goal_title = "<h3 class=\"" + color_box + "\">" + to_string(g) + ". " + oInvProbl->goalZ[g].description + "&nbsp;<span class=\"glyphicon glyphicon-triangle-bottom\"></span></h3>";
1554  cout << hh.collapse_open("goalsAccordion", goal_title, g, false, true, "soft-" + color_box);
1555 
1556  // string collapse_open(string parent_id, string title, int nbr, bool add_triangle = true, bool is_open = true, string xtra_body_class = "");
1557 
1558 
1559  /* switch (oConfig.layout)
1560  {
1561  case '2' :
1562 
1563 
1564  cout << "\n<div class=\"panel panel-default\">";
1565  cout << "\n<div class=\"panel-heading\">";
1566  cout << "<a data-toggle=\"collapse\" data-parent=\"#accordion2\" data-target=\"#collapse" << g << "\">";
1567 
1568 
1569 
1570  cout << "<h3 class=\"";
1571  hh.cout_box_color(oInvProbl->goalZ[g].color);
1572  cout << "\">" << oInvProbl->goalZ[g].description << "&nbsp;<span class=\"glyphicon glyphicon-triangle-bottom\"></span></h3></a>";
1573  cout << "</div>";
1574  cout << "\n<div id=\"collapse" << g <<"\" class=\"panel-collapse collapse in\">"; ///< note the "in": the jqplot chart won't render in hidden div's :-(
1575  cout << "\n<div class=\"panel-body\">";
1576  break;
1577  case '1':
1578  default :
1579  cout << "<div class=\"alert alert-info\">";
1580  cout << "<div class=\"";
1581  hh.cout_box_color(oInvProbl->goalZ[g].color);
1582  cout << "\">";
1583  cout << "<h4>" << g << ". " << oInvProbl->goalZ[g].description << "</h4> ";
1584  cout << "</div>";
1585  }*/
1586  std::cout.precision(2);
1587  cout << "<ul>";
1588  // -- description
1589  cout << "<li><b>description</b>:" << oInvProbl->goalZ[g] << "</li>";
1590 
1591  if (oInvProbl->goalZ[g].realization_monthNbr < 0)
1592  {
1593  cout << "<li>This goal seems to be in the past ... please check</li>";
1594  }
1595  else
1596  {
1597  // -- benchmark
1598  cout << "<li><b>benchmark</b>:<br>";
1599  parse_bm(oInvProbl->goalZ[g].benchmark, g);
1600  cout <<"</li>";
1601 
1602  // -- savings plan
1603  cout << "<li><b>savings plan</b>: ";
1604  parse_savings_plan(oInvProbl, g);
1605  cout <<"</li>";
1606  //----cout << "</div>" ; continue;
1607 
1608  // -- plot
1609  cout << "<li><b>overview plot</b>";
1610  oInvProbl->javaGraph(g, s_var, s_desc);
1611  //--> }
1612 
1613  // -- remarks
1614  cout << "<li><b>remarks</b>: ";
1615  cout << oInvProbl->goalZ[g].remarks;
1616  cout <<"</li>";
1617 
1618  }
1619  cout << "</ul>";
1620 
1621  cout << hh.collapse_close("goalsAccordion", g);
1622  // cout << "<script class=\"code\" type=\"text/javascript\">$(document).ready(function(){$('.collapse" << g << "').collapse('hide');})</scripts>";
1623 /* switch (oConfig.layout)
1624  {
1625  case '2' :
1626  cout << "</div></div></div>";
1627  break;
1628  case '1' :
1629  default :
1630  cout << "</div>";
1631  }*/
1632 
1633 }
1634 
1635 
1636 
1643 {
1644  int g;
1645 // load_from_db(to_string(investor_id));
1646 
1647  hh.header(investor_id, true, true); // true as second param adds the javascript to hide/show the plans
1648  // true as third param adds the jqPolt sources
1649  hh.show_toolBar("feedback",get_full_name());
1650 
1651  hh.aside(t_aside["feedback"]);
1652 
1653  investment_problem oInvestmentProbl(this->investor_id);
1654 
1655  try
1656  {
1657  oInvestmentProbl.solve();
1658  }
1659  catch (int e)
1660  {
1661  #ifdef DEBUG
1662  cout << "# error in investment_problem.solve(): " << __FILE__ << "(" << __FUNCTION__
1663  << ") on line " << to_string(__LINE__) << "<br># ERR: " << e;
1664  #endif
1665  }
1666 
1667 //cout << oInvestmentProbl.get_nbr_goals();
1668  // now show the feedback on the screen
1669 
1670  cout << this->parse_user_info(true);
1671 
1672  cout << "<div class=\"panel-group\" id=\"goalsAccordion\">";
1673 
1674  for (g = 1; g <= oInvestmentProbl.get_nbr_goals(); g++)
1675  {
1676  parse_goal_box(&oInvestmentProbl, g);
1677  /*std::cout.precision(2);
1678 
1679  cout << "<div class=\"alert alert-info\">";
1680  cout << "<div class=\"";
1681  hh.cout_box_color(oInvestmentProbl.goalZ[g].color);
1682  cout << "\">";
1683  cout << "<h4>" << g << ". " << oInvestmentProbl.goalZ[g].description << "</h4> ";
1684  cout << "</div>";
1685  cout << "<ul>";
1686  // -- description
1687  cout << "<li><b>description</b>:" << oInvestmentProbl.goalZ[g] << "</li>";
1688 
1689  if (oInvestmentProbl.goalZ[g].realization_monthNbr < 0)
1690  {
1691  cout << "<li>This goal seems to be in the past ... please check</li>";
1692  }
1693  else
1694  {
1695  // -- benchmark
1696  cout << "<li><b>benchmark</b>:<br>";
1697  parse_bm(oInvestmentProbl.goalZ[g].benchmark, g);
1698  cout <<"</li>";
1699 
1700  // -- savings plan
1701  cout << "<li><b>savings plan</b>:";
1702  parse_savings_plan(&oInvestmentProbl, g);
1703  cout <<"</li>";
1704  //----cout << "</div>" ; continue;
1705 
1706  // -- plot
1707  cout << "<li><b>overview plot</b>";
1708  oInvestmentProbl.javaGraph(g);
1709  //--> }
1710 
1711  // -- remarks
1712  cout << "<li><b>remarks</b>:";
1713  cout << oInvestmentProbl.goalZ[g].remarks;
1714  cout <<"</li>";
1715 
1716  }
1717  cout << "</ul>";
1718  cout << "</div>"; // alert alert-info*/
1719  } // for loop per goal
1720  cout << "</div>"; // goalsAccordion
1721 
1722  show_total_portfolio(&oInvestmentProbl);
1723  hh.footer("feedback","feedback");
1724 }
1725 
1726 
1732 {
1733  int g;
1734 // load_from_db(to_string(investor_id)); //load the investor object
1735  hh.header(investor_id, true, true); // false as second param should not add javascript to hide/show the plans
1736 
1737  hh.show_toolBar("simulation",get_full_name());
1738  hh.aside(t_aside["simulation"]);
1739 
1740  //int i; cout << "<BR>before init"; for (i=1; i <= 20; i++) cout << " -- " << i;
1741 
1742  simulation oSimulation(this->investor_id);
1743  //cout << "<BR>before simulate"; for (i=1; i <= 20; i++) cout << " -- " << i;
1744 
1745  oSimulation.simulate();
1746 
1747  //cout << "<BR>after simulate"; for (i=1; i <= 20; i++) cout << " -- " << i;
1748 
1749  cout << "<br>";
1750  cout << "<p>This page presents <strong>a simulation</strong>. A simulation is just <strong>one</strong> possible scenario (something that could happen). Press the button [Simulate Again] to see another simulation.</p><p>Last session You stated " << oSimulation.get_nbr_goals() << " goals, below you see what might happen.</p>";
1751  cout << "<br>" << endl;
1752 
1755 
1757  parse_simulation_insight(&oSimulation);
1758 
1760 //solve is included in simulate() {above}// oSimulation.solve();
1761  for (g = 1; g <= oSimulation.get_nbr_goals(); g++)
1762  {
1763  parse_goal_box(&oSimulation, g, oSimulation.goalZ[g].simulation_string, "simulated evolution");
1764 /*
1765  //goalZ[g].load(); /// TODO: load goals in stead of recalcualting !!!!!!!!!!!!!!!!!!!!!!!!
1766  cout << "<div class=\"alert alert-info\">";
1767  cout << "<div class=\"";
1768  hh.cout_box_color(oSimulation.goalZ[g].color);
1769  cout << "\">";
1770  cout << "<h4>" << g << ". " << oSimulation.goalZ[g].description << "</h4> ";
1771  cout << "</div>";
1772  cout << "<ul>";
1773  // -- description
1774  cout << "<li><b>description</b>:" << oSimulation.goalZ[g] << "</li>";
1775  // -- benchmark
1776  cout << "<li><b>benchmark</b>:<br>";
1777  parse_bm(oSimulation.goalZ[g].benchmark, g);
1778  cout <<"</li>";
1779 
1780  // -- savings plan
1781  cout << "<li><b>savings plan</b>:";
1782  parse_savings_plan(&oSimulation, g);
1783 
1784 
1785  //-- graph
1786  oSimulation.javaGraph(g, oSimulation.goalZ[g].simulation_string, "simulated evolution");
1787  cout << "<li><b>plot of the simulation</b>:</li>";
1788 // cout << "<div id=\"chartOverview"<<g<<"\" style=\"height:350px; width:650px;\"></div>";
1789  cout << "</ul>";
1790  cout << "</div>"; // alert alert-info
1791  */
1792  }
1793  cout << "<br>";
1794  hh.footer("simulation","simulation");
1795 }
1796 
1805 {
1806 // struct tm theDate;
1807  int g, simulation_length_mnths;
1808  string mnth_max, the_comment;
1809 // load_from_db(to_string(investor_id)); //load the investor object
1810  hh.header(investor_id, false, true); // false as second param should not add javascript to hide/show the plans
1811  // second param
1812  hh.show_toolBar("followup",get_full_name());
1813  hh.aside(t_aside["follow_up"]);
1814 
1815  follow_up oFollowUp(this->investor_id);
1816 
1817  oFollowUp.simulate();
1818  cout << "<br>";
1819  cout << "<p>This page presents <strong>a simulation</strong> of what can possible happen in the future. In other words it is a simulation of how a dashboard to follow up on investments could look like in the future (given a certain market evolution). So, in an operational version of this software you would not have to put in a number of months to simulate, the system would rather drop you an emeail with this overview updated with today's market values.</p><p>Last session You stated " << oFollowUp.get_nbr_goals() << " goals. Below you find more information on any recommended actions.</p>";
1820 
1823 
1825  parse_simulation_insight(&oFollowUp);
1826 
1828 // cout << "<BR> oFollowUp.get_nbrMonths2simulate() = " << oFollowUp.get_nbrMonths2simulate();
1829  for (g = 1; g <= oFollowUp.get_nbr_goals(); g++) oFollowUp.prepare_javaVars_colors(g, oFollowUp.get_nbrMonths2simulate());
1830  oFollowUp.parse_dashboard();
1831 
1832 
1833  cout << "<h2>Detailed Follow-Up per Goal</h2>";
1835  for (g = 1; g <= oFollowUp.get_nbr_goals(); g++)
1836  {
1837  cout << "<div class=\"alert alert-info\">";
1838  cout << "<div class=\"";
1839  hh.cout_box_color(oFollowUp.goalZ[g].color);
1840  cout << "\">";
1841  cout << "<h4>" << g << ". " << oFollowUp.goalZ[g].description << "</h4> ";
1842  cout << "</div>";
1843  cout << "<ul>";
1844  // -- description
1845  cout << "<li><b>Description</b>:" << oFollowUp.goalZ[g] << "</li>";
1846  /* // -- benchmark
1847  cout << "<li><b>Benchmark</b>:<br>";
1848  parse_bm(oFollowUp.goalZ[g].benchmark, g);
1849  cout <<"</li>";
1850 
1851  cout << "<li><b>Savings Plan</b>:<br>";
1852  parse_savings_plan(&oFollowUp, g);
1853  cout <<"</li>";
1854  */
1855  // -- simulation plot
1856  cout << "<li><b>How it might looks like in "<< mnth_max <<":</b>";
1857  //oFollowUp.javaGraph(g, oFollowUp.goalZ[g].simulation_string, "simulated evolution", oFollowUp.get_nbrMonths2simulate()); // this sets also the followup color
1858  oFollowUp.parse_javaGraph( g, oFollowUp.goalZ[g].simulation_string, t_plotlabels_evol[5]);
1859  simulation_length_mnths = min(oFollowUp.get_nbrMonths2simulate(),((goal_type_i2s[oFollowUp.goalZ[g].goal_type] == "rainy day savings") ? months2simulate() : oFollowUp.goalZ[g].realization_monthNbr));
1860  simulation_length_mnths = min(oFollowUp.get_nbrMonths2simulate(), oFollowUp.goalZ[g].realization_monthNbr);
1861  mnth_max = months2yms(simulation_length_mnths);
1862  the_comment = (simulation_length_mnths < oFollowUp.goalZ[g].realization_monthNbr) ? t_feedback[oFollowUp.goalZ[g].color] : t_feedback_post[oFollowUp.goalZ[g].color_followup] ;
1863  if (goal_type_i2s[oFollowUp.goalZ[g].goal_type] == "rainy day savings") the_comment = "Since this is your &quot;buffer&quot; investment it is not possible to say that this is a good of a bad situation now. The future will tell."; // to force
1864 
1865  cout << "</li>";
1866  cout << "<li><span class=\"" << hh.get_box_color_class(oFollowUp.goalZ[g].color_followup) << "\">The new color of this goal is <b>" << oFollowUp.goalZ[g].color_followup << "</b>. This means that after " << mnth_max << " and <b>if</b> you carefully followed the plan, this it <b>might</b> be that the dvice at that future moment would be: <b><i>"<< the_comment <<"</i></b></p><p>Note that this is only <b>one</b> possible outcome, press [enter], [F5] or the refresh button to see another possible simulation (eventually change the simulation horizon).<br>Note that not only you might put in different saving amounts or follow a different benchmark, also reasonable expectations about return, volatility and correlations might change!</li>";
1867  cout << "</ul>";
1868  cout << "</div>"; // alert alert-info
1869  }
1870 
1871  cout << "<br>";
1872  hh.footer("followup","follow_up");
1873 }
1874 
1875 
1881 void investor_ui::parse_bm(std::map<int, float> benchmark, int goal_number)
1882 {
1883  std::map <int, string> asset_list = oAssetClass.get_assetList();
1884  unsigned i;
1885  float the_total = 0;
1886 
1887  //normalize the benchmark:
1888  for (i = 1; i <= benchmark.size(); i++) the_total += benchmark[i];
1889  for (i = 1; i <= benchmark.size(); i++) benchmark[i] = benchmark[i] / the_total;
1890 
1891 //xx cout << "\n<table class=\"bm\"><tr><td>";
1892 
1893  // the table:
1894 /* cout << "\n<table style=\"font-size:0.8em;\" border=\"1\">";
1895 
1896  for(i=1; i <= NBR_ASSET_CLASSES; i++)
1897  {
1898  cout << "<tr><td>"<< asset_list[i] << "</td><td>" << round(benchmark[i]*10000)/100 << "%</td></tr>";
1899  }
1900  cout << "</table>";
1901 */
1902  //the pie chart:
1903 //xx cout << "</td><td>";
1904  // - the pie chart of the benchmark
1905  cout << "\n<script class=\"code\" type=\"text/javascript\">$(document).ready(function(){var data = [";
1906  for(i=1; i <= NBR_ASSET_CLASSES; i++)
1907  {
1908  cout << "['" << asset_list[i] << " : " << round(benchmark[i]*10000)/100 << "%'," << round(benchmark[i]*10000)/100 << "]";
1909  if (i < NBR_ASSET_CLASSES) cout << ", ";
1910  }
1911  cout << "];";
1912  cout << "var plot"<<goal_number<<" = jQuery.jqplot ('chart"<<goal_number<<"', [data], ";
1913  cout << "{";
1914  cout << "seriesColors :" << hh.assetClassColors << ", ";
1915  cout << "seriesDefaults: {";
1916  // Make this a pie chart.
1917  cout << "renderer: jQuery.jqplot.PieRenderer,";
1918  cout << "rendererOptions: {";
1919  // Put data labels on the pie slices.
1920  // By default, labels show the percentage of the slice.
1921  cout << "showDataLabels: true }},";
1922  cout << "legend: { show:true, location: 'e', showLabels:true}";
1923  cout << "}";
1924  cout << ");});</script>";
1925  // cout << "<span id=\"floatLeft\" style=\"width:40%;\">";
1926  cout << "<div id=\"chart"<<goal_number<<"\" style=\"height:" << to_string(NBR_ASSET_CLASSES * 34) << "px; width:600px; tr height:1em;\"></div>";
1927 //xx cout << "</td></tr></table>";
1928 }
1929 
1930 
1935 {
1936  cout << "<h3>Easy Goal Definition Screen</h3>";
1937  cout << "<p>Here are some common goals that might help you to set your goals.</p>";
1938 
1939  cout << "\n<form method=\"post\" action=\"" + oConfig.soft_url + "?a=ghs\" class=\"helpForm\">\n";
1940 
1941  cout << "<div class=\"goalHelpDiv\">";
1942 
1944  cout << hh.collapse_open("goalHelpDiv", "Retirement", 1, true, true);
1945  //cout << "<div class=\"alert alert-info\">";
1946  // cout << "<h3>Retirement</h3>\n";
1947  cout << "<p>Many people will consider their own retirement as the most important goal to save for.<br/>In order to plan for your retirement, you will need to do the following steps:";
1948  cout << "<ul><li>find out how much retirement income you will get from any sources outside this plan (minimal income, legal retirment, etc.)</li>";
1949  cout << "<li>find out how much monthly expenses you will have (housing, housing related costs, food, clothes, presents, etc.)</li>";
1950  cout << "<li>make the difference of the two above: that difference is the amount that you will need every month. Fill it in below.</li></ul></p>";
1951  cout << "<fieldset>\n";
1952  cout << "<ol>\n";
1953  cout << "<li>\n";
1954  cout << "<label for=\"R_from_age\">age when you plan to retire</label><input type=\"number\" name=\"R_from_age\" autofocus=\"true\" placeholder=\"65\" value=\"\"> the age at which you start to need the additional income\n";
1955  cout << "</li>\n<li>";
1956  cout << "<label for=\"R_till_age\">age till when the income is needed</label><input type=\"number\" name=\"R_till_age\" autofocus=\"false\" placeholder=\"110\" value=\"110\"> 110 years old should be a safe limit, but feel free to provide your own.\n";
1957  cout << "</li>\n<li>";
1958  cout << "<label for=\"R_income\">monthly additional income desired</label><input type=\"number\" name=\"R_income\" autofocus=\"false\" placeholder=\"1000\" value=\"\">\n";
1959  cout << "</li>\n";
1960  cout << "</ol>\n";
1961  cout << "</fieldset>";
1962  //cout << "</div>\n";
1963  cout << hh.collapse_close("goalHelpDiv",1);
1964 
1966  cout << hh.collapse_open("goalHelpDiv", "Rainy Day Savings", 2, true, false);
1967 // cout << "<div class=\"alert alert-info\">";
1968 // cout << "<h3>Rainy Day Savings</h3>\n";
1969  cout << "<p>A second investment goal that might come to your attention is \"a saving for the rainy day\". It is an amount that you will always want to keep liquid and available in case something unforeseen happens.";
1970  cout << "unforeseen reasons why you would need money are per definition those that you did do not plan for (as separate goals). Examples are urgent repair on the house, legal assistance, repatriation, hospitalisation costs (not covered by any insurance or the amount that you might have to advance), etc.</p>";
1971  cout << "<p>Troubles to decide on the amount? Try on of the following rule of thumb: two monthly salaties plus two months rent (or equivalent rental potential if you live in your own place)</p>";
1972  cout << "<fieldset>\n";
1973  cout << "<ol>\n";
1974  cout << "<li>\n"; error_message = "";
1975 
1976  cout << "<label for=\"RDS_amount\">amount of the rainy day savings:</label><input type=\"number\" name=\"RDS_amount\" autofocus=\"true\" placeholder=\"5000\" value=\"\">\n";
1977  cout << "</li>\n";
1978  cout << "</ol>\n";
1979  cout << "</fieldset>";
1980 // cout << "</div>\n";
1981  cout << hh.collapse_close("goalHelpDiv", 2, true);
1982 
1984  cout << hh.collapse_open("goalHelpDiv", "Insurances", 3, true, false);
1985 // cout << "<div class=\"alert alert-info\">";
1986 // cout << "<h3>Insurances</h3>\n";
1987  cout << "<p>While it is probably easier to keep insurances out of this analysis (ie. deduce insurance payments that you plan to add from your saving capacity),";
1988  cout << " it is very important to consider if you would need any of the following insurances and make sure that you have them in place!</p>";
1989  cout << "<ul>";
1990  cout << "<li>life insurance: provides a certain amount of money for your close ones in case you pass away, not only to cover cost related to that unfortunate moment, but also to make sure they can live the life you want them to live without your contribution.</li>";
1991  cout << "<li>hospitalisation insurance: pays (preferably as third payer) for the event of hospitalisation</li>";
1992  cout << "<li>income insurance: in case you lose your income due to loss of business or loss of ability to work, you might want to have some replacement income in place.</li>";
1993  cout << "<li>insurance on any important properties: use as a rule of thumb that any utilitaraian object that you can not easily by back should be insured (eg. if you loose your computer it might be no problem to replace it but if your house burns down you might not be able to recover from that: so you need an insurance on the house!</li>";
1994  cout << "<li>TPL for your and those people for whome you're legally responsible</li>";
1995  cout << "<li>Any relevant professional insurance (eg. you might be legally responsible for the advice that you give as consultant)</li>";
1996  cout << "</ul>";
1997 // cout << "</div>\n";
1998  cout << hh.collapse_close("goalHelpDiv",3);
1999 
2001  cout << hh.collapse_open("goalHelpDiv", "Savings for (grand-) childeren", 4, true, false);
2002 // cout << "<div class=\"alert alert-info\">";
2003 // cout << "<h3>Savings for (grand-) childeren</h3>\n";
2004  cout << "<p>Many people will want to sed aside some money for their loved ones. Typical examples are kids or grand-kids. Most probably you will want to save for their studies or provide them with a certain amount \"to start their lives\"</p>";
2005  cout << "<fieldset>\n";
2006  cout << "<ul>\n";
2007  cout << "<li><b>First Kid</b>\n";
2008  cout << "<ol>\n";
2009  cout << "<li><label for=\"K1_desc\">description / name:</label><input type=\"text\" name=\"K1_desc\" placeholder=\"Amelia\" value=\"\"></li>\n";
2010  cout << "<li><label for=\"K1_amount\">amount:</label><input type=\"number\" name=\"K1_amount\" placeholder=\"10000\" value=\"\"></li>\n";
2011  cout << "<li><label for=\"K1_years\">due in</label><input type=\"number\" name=\"K1_years\" placeholder=\"15\" value=\"\"> years</li>\n";
2012  cout << "</ol></li>\n";
2013  cout << "<li><b>Second Kid</b>\n";
2014  cout << "<ol>\n";
2015  cout << "<li><label for=\"K2_desc\">description / name:</label><input type=\"text\" name=\"K2_desc\" placeholder=\"Amelia\" value=\"\"></li>\n";
2016  cout << "<li><label for=\"K2_amount\">amount:</label><input type=\"number\" name=\"K2_amount\" placeholder=\"10000\" value=\"\"></li>\n";
2017  cout << "<li><label for=\"K2_years\">due in</label><input type=\"number\" name=\"K2_years\" placeholder=\"15\" value=\"\"> years</li>\n";
2018  cout << "</ol></li>\n";
2019  cout << "<li><b>Third Kid</b>\n";
2020  cout << "<ol>\n";
2021  cout << "<li><label for=\"K3_desc\">description / name:</label><input type=\"text\" name=\"K3_desc\" placeholder=\"Amelia\" value=\"\"></li>\n";
2022  cout << "<li><label for=\"K3_amount\">amount:</label><input type=\"number\" name=\"K3_amount\" placeholder=\"10000\" value=\"\"></li>\n";
2023  cout << "<li><label for=\"K3_years\">due in</label><input type=\"number\" name=\"K3_years\" placeholder=\"15\" value=\"\"> years</li>\n";
2024  cout << "</ol></li>\n";
2025  cout << "</ul>\n";
2026  cout << "</fieldset>";
2027 // cout << "</div>\n";
2028  cout << hh.collapse_close("goalHelpDiv",4);
2029 
2030 
2032  cout << hh.collapse_open("goalHelpDiv", "Foreseeable expenses", 5, true, false);
2033 // cout << "<div class=\"alert alert-info\">";
2034 // cout << "<h3>Foreseeable expenses</h3>\n";
2035  cout << "Examples are:";
2036  cout << "<ul><li>repair to your dwelling house</li>";
2037  cout << "<li>a new car</li>";
2038  cout << "<li>etc.</li></ul>";
2039  cout << "<fieldset>\n";
2040  cout << "<ul>\n";
2041  cout << "<li><b>First Expense</b>\n";
2042  cout << "<ol>\n";
2043  cout << "<li><label for=\"FE1_desc\">description:</label><input type=\"text\" name=\"FE1_desc\" placeholder=\"Repair House\" value=\"\"></li>\n";
2044  cout << "<li><label for=\"FE1_amount\">amount:</label><input type=\"number\" name=\"FE1_amount\" placeholder=\"10000\" value=\"\"></li>\n";
2045  cout << "<li><label for=\"FE1_years\">due in</label><input type=\"number\" name=\"FE1_years\" placeholder=\"15\" value=\"\"> years</li>\n";
2046  cout << "</ol></li>\n";
2047  cout << "<li><b>Second Expense</b>\n";
2048  cout << "<ol>\n";
2049  cout << "<li><label for=\"FE2_desc\">description:</label><input type=\"text\" name=\"FE2_desc\" placeholder=\"New Car\" value=\"\"></li>\n";
2050  cout << "<li><label for=\"FE2_amount\">amount:</label><input type=\"number\" name=\"FE2_amount\" placeholder=\"10000\" value=\"\"></li>\n";
2051  cout << "<li><label for=\"FE2_years\">due in</label><input type=\"number\" name=\"FE2_years\" placeholder=\"15\" value=\"\"> years</li>\n";
2052  cout << "</ol></li>\n";
2053  cout << "<li><b>Third Expense</b>\n";
2054  cout << "<ol>\n";
2055  cout << "<li><label for=\"FE3_desc\">description:</label><input type=\"text\" name=\"FE3_desc\" placeholder=\"Maintainance Yacht\" value=\"\"></li>\n";
2056  cout << "<li><label for=\"FE3_amount\">amount:</label><input type=\"number\" name=\"FE3_amount\" placeholder=\"10000\" value=\"\"></li>\n";
2057  cout << "<li><label for=\"FE3_years\">due in</label><input type=\"number\" name=\"FE3_years\" placeholder=\"15\" value=\"\"> years</li>\n";
2058  cout << "</ol></li>\n";
2059  cout << "</ul>\n";
2060  cout << "</fieldset>";
2061 // cout << "</div>\n";
2062  cout << hh.collapse_close("goalHelpDiv",5);
2063 
2065  cout << hh.collapse_open("goalHelpDiv", "Foreseeable expenses", 6, true, false);
2066 // cout << "<div class=\"alert alert-info\">";
2067 // cout << "<h3>Life Dream</h3>\n";
2068  cout << "<p>Your personal life dream: art purchase, travel, yacht, a gift to a good cause, etc.</p>";
2069  cout << "<fieldset>\n";
2070  cout << "<ul>\n";
2071  cout << "<li><b>First Life Dream</b>\n";
2072  cout << "<ol>\n";
2073  cout << "<li><label for=\"LD1_desc\">description:</label><input type=\"text\" name=\"LD1_desc\" placeholder=\"Yacht\" value=\"\"></li>\n";
2074  cout << "<li><label for=\"LD1_amount\">amount:</label><input type=\"number\" name=\"LD1_amount\" placeholder=\"100000\" value=\"\"></li>\n";
2075  cout << "<li><label for=\"LD1_age\">age to realize this dream</label><input type=\"number\" name=\"LD1_age\" placeholder=\"55\" value=\"\"> years old</li>\n";
2076  cout << "</ol></li>\n";
2077  cout << "<li><b>Second Life Dream</b>\n";
2078  cout << "<ol>\n";
2079  cout << "<li><label for=\"LD2_desc\">description:</label><input type=\"text\" name=\"LD2_desc\" placeholder=\"World Travel\" value=\"\"></li>\n";
2080  cout << "<li><label for=\"LD2_amount\">amount:</label><input type=\"number\" name=\"LD2_amount\" placeholder=\"100000\" value=\"\"></li>\n";
2081  cout << "<li><label for=\"LD2_age\">age to realize this dream</label><input type=\"number\" name=\"LD2_age\" placeholder=\"65\" value=\"\"> years old</li>\n";
2082  cout << "</ol></li>\n";
2083  cout << "<li><b>Third Life Dream</b>\n";
2084  cout << "<ol>\n";
2085  cout << "<li><label for=\"LD3_desc\">description:</label><input type=\"text\" name=\"LD3_desc\" placeholder=\"Gift to Good Cause\" value=\"\"></li>\n";
2086  cout << "<li><label for=\"LD3_amount\">amount:</label><input type=\"number\" name=\"LD3_amount\" placeholder=\"100000\" value=\"\"></li>\n";
2087  cout << "<li><label for=\"LD3_age\">age to realize this dream</label><input type=\"number\" name=\"LD3_age\" placeholder=\"75\" value=\"\"> years old</li>\n";
2088  cout << "</ol></li>\n";
2089  cout << "</ul>\n";
2090  cout << "</fieldset>";
2091 // cout << "</div>\n";
2092  cout << hh.collapse_close("goalHelpDiv",6);
2093 
2094  cout << "<button class=\"btn btn-primary\" type=\"submit\" value=\"Submit\">ADD ALL the goals that are filled out</button>\n&nbsp;";
2095  cout << "<button class=\"btn btn-primary\" type=\"reset\" value=\"reset\">"<< t_clear_form <<"</button>\n&nbsp;";
2096  cout << "<button class=\"btn btn-primary\" onclick=\"window.location.href='/" << oConfig.soft_url << "a=gl'\">" << t_cancel << "</button>";
2097  cout << "<input type=\"hidden\" name=\"a\" value=\"ghs\" />&nbsp;\n";
2098  cout << "</form>\n";
2099 
2100  cout << "</div>"; // goalHelpDiv
2101 }
2102 
2107 {
2110  hh.footer("","");
2111 }
2112 
2113 
2119 {
2120  aGOAL the_goal(investor_id);
2121  int k;
2122 
2124  string R_from_age = cgi("R_from_age");
2125  string R_till_age = cgi("R_till_age");
2126  string R_income = cgi("R_income");
2127  if((R_from_age != "") && (R_till_age != "") && (R_income != ""))
2128  {
2129  float from_age = atof(R_from_age.c_str());
2130  float till_age = atof(R_till_age.c_str());
2131  if (from_age <= age())
2132  {
2133  from_age = this->age(0);
2134  std_message = std_message + "<li>I changed the from_date of the retirement goal to today (one cannot plan for past income)</li>";
2135  }
2136  if (from_age < till_age)
2137  {
2138  string f_dateStr = mNbr2dateStr(age2monthNbr(from_age));
2139  string t_dateStr = mNbr2dateStr(age2monthNbr(till_age));
2140 #ifdef DEBUG
2141  debug_info = debug_info + "<br>f_dateStr = " + f_dateStr + ", mNbr = " + to_string(age2monthNbr(from_age))+ ", age = " + to_string(from_age);
2142  debug_info = debug_info + "<br>t_dateStr = " + t_dateStr + ", mNbr = " + to_string(age2monthNbr(till_age))+ ", age = " + to_string(till_age);
2143 #endif
2144  if (the_goal.set_amount(R_income) && the_goal.set_from_date(f_dateStr) && the_goal.set_till_date(t_dateStr))
2145  {
2146  the_goal.set_goal_type(to_string(goal_type_s2i["income from/to"]));
2147  the_goal.set_description("Extra income during retirement");
2148  the_goal.set_currency(this->currency);
2149  the_goal.set_priority("1");
2150  the_goal.set_frequency("M");
2151  the_goal.set_realization_age(dateStr2Age(t_dateStr), this->age(0));
2152  the_goal.set_max_shortfall("0");
2153  the_goal.add_to_db();
2154  }
2155  }
2156  else
2157  {
2158  error_message = error_message + "<li>Sorry, I failed to add the RETIREMENT goal (note that the from-date must be in the future but before the end date; provided: from_age=" + R_from_age + ", till_age=" + R_till_age + ")), please retry!</li>";
2159  }
2160  }
2161 
2163  string RDS_amount = cgi("RDS_amount");
2164  //the_goal = new aGOAL; //xxxxxxxxxxxxxx
2165  if(RDS_amount != "")
2166  {
2167  if (atof(RDS_amount.c_str()) > 0)
2168  {
2169  string end_dateStr = mNbr2dateStr(age2monthNbr(simulate_till_age));
2170  the_goal.set_amount(RDS_amount);
2171  the_goal.set_from_date(tm2DateStr(get_tm(0)));
2172  the_goal.set_till_date(end_dateStr);
2173  the_goal.set_goal_type(to_string(goal_type_s2i["rainy day savings"]));
2174  the_goal.set_description("Rainy day savings");
2175  the_goal.set_currency(this->currency);
2176  the_goal.set_priority("3");
2177  the_goal.set_frequency("O");
2178  the_goal.set_realization_age(to_string(simulate_till_age), this->age(0));
2179  the_goal.set_max_shortfall("0");
2180  the_goal.add_to_db();
2181  }
2182  else
2183  {
2184  error_message = error_message + "<li>Sorry, the RAINY DAY savings should be a positive amount.</li>";
2185  }
2186  }
2187 
2188  string g_desc;
2189  string g_amount;
2190  string g_years ;
2191  string g_age;
2192 
2193  float g_age_fl;
2194 
2195 
2197  for (k = 1; k <=3; k++)
2198  {
2199  g_desc = cgi("K" + to_string(k) + "_desc");
2200  g_amount = cgi("K" + to_string(k) + "_amount");
2201  g_years = cgi("K" + to_string(k) + "_years");
2202 
2203  if (g_desc + g_amount + g_years != "")
2204  {
2205  if (atof(g_years.c_str()) > 0)
2206  {
2207  the_goal.set_amount(g_amount);
2208  g_age_fl = this->age(0) + atof(g_years.c_str());
2209  the_goal.set_realization_age(to_string(g_age_fl), this->age(0));
2210  the_goal.set_from_date(mNbr2dateStr(age2monthNbr(g_age_fl)));
2211  the_goal.set_till_date(the_goal.from_date);
2212  the_goal.set_goal_type(to_string(goal_type_s2i["amount@date"]));
2213  the_goal.set_description(g_desc);
2214  the_goal.set_currency(this->currency);
2215  the_goal.set_priority("5");
2216  the_goal.set_frequency("O");
2217  the_goal.set_max_shortfall("0");
2218  the_goal.add_to_db();
2219  }
2220  else
2221  {
2222  error_message = error_message + "<li>The spending for your kids has to be in the FUTURE.</li>";
2223  }
2224  }
2225  }
2226 
2228  for (k = 1; k <=3; k++)
2229  {
2230  g_desc = cgi("FE" + to_string(k) + "_desc");
2231  g_amount = cgi("FE" + to_string(k) + "_amount");
2232  g_years = cgi("FE" + to_string(k) + "_years");
2233  if (g_desc + g_amount + g_years != "")
2234  {
2235 
2236  if (atof(g_years.c_str()) > 0)
2237  {
2238  the_goal.set_amount(g_amount);
2239  g_age_fl = this->age(0) + atof(g_years.c_str());
2240  the_goal.set_realization_age(to_string(g_age_fl), this->age(0));
2241  the_goal.set_from_date(mNbr2dateStr(age2monthNbr(g_age_fl)));
2242  the_goal.set_till_date(the_goal.from_date);
2243  the_goal.set_goal_type(to_string(goal_type_s2i["amount@date"]));
2244  the_goal.set_description(g_desc);
2245  the_goal.set_currency(this->currency);
2246  the_goal.set_priority("7");
2247  the_goal.set_frequency("O");
2248  the_goal.set_max_shortfall("0");
2249  the_goal.add_to_db();
2250  }
2251  else
2252  {
2253  error_message = error_message + "<li>The foreseeable spendings have to be in the FUTURE.</li>";
2254  }
2255  }
2256  }
2257 
2259  for (k = 1; k <=3; k++)
2260  {
2261  g_desc = cgi("LD" + to_string(k) + "_desc");
2262  g_amount = cgi("LD" + to_string(k) + "_amount");
2263  g_age = cgi("LD" + to_string(k) + "_age");
2264 
2265  if (g_desc + g_amount + g_age != "")
2266  {
2267 
2268  g_age_fl = atof(g_age.c_str());
2269  if (g_age_fl > age(0))
2270  {
2271  the_goal.set_amount(g_amount);
2272  the_goal.set_realization_age(g_age, this->age(0));
2273  the_goal.set_from_date(mNbr2dateStr(age2monthNbr(g_age_fl)));
2274  the_goal.set_till_date(the_goal.from_date);
2275  the_goal.set_goal_type(to_string(goal_type_s2i["amount@date"]));
2276  the_goal.set_description(g_desc);
2277  the_goal.set_currency(this->currency);
2278  the_goal.set_priority("9");
2279  the_goal.set_frequency("O");
2280  the_goal.set_max_shortfall("0");
2281  the_goal.add_to_db();
2282  }
2283  else
2284  {
2285  error_message = error_message + "<li>The spending for your kids has to be in the FUTURE.</li>";
2286  }
2287  }
2288  }
2289 
2290  if (error_message == "")
2291  {
2293  hh.show_toolBar("goals",get_full_name());
2294  oGoal.list(investor_id, true); // show the t_before_list and list existing and show input form for new
2295  hh.aside(t_aside["goalInfo"]);
2296  hh.footer("goals","goal");
2297  }
2298  else
2299  {
2300  hh.header(0);
2301  hh.show_toolBar("register");
2303  hh.aside(t_aside["goalHelpFail"]);
2304  hh.footer("goals","goal");
2305  }
2306 
2307 } // goal_help_save
2308 
2315 {
2316  struct tm theDate = get_tm(0);
2317  int i;
2318  cout << endl;
2319  cout << "<button id=\"btnShowSP" << g << "\">Show</button>";
2320  cout << "<button id=\"btnHideSP" << g << "\">Hide</button>";
2321  cout << "<div id=\"savingsPlan" << g << "\">";
2322  cout << endl;
2323  cout << "<table border=\"1\" class=\"savingPlan\">";
2324  //cout << "<tr><th>Date</th><th>Amount</th><th>Currency</th></tr>" << endl;
2325  cout << "<tr><th>Date</th><th>Amount</th></tr>" << endl;
2326  for (i=0; i<= oInvProbl->goalZ[g].realization_monthNbr;i++)
2327  {
2328  if (oInvProbl->goalZ[g].saving_plan[i] > 0)
2329  { // only show an entry in the table if there are savings
2330  cout << "<tr>";
2331  cout << "<td>" << tm2DateStr(theDate) << "</td>";
2332  //cout << "<td>" << to_string(std::printf("%.2f",oInvProbl->goalZ[g].saving_plan[i])) << "</td>";
2333  cout << "<td>" << curr_format(oInvProbl->goalZ[g].saving_plan[i], oInvProbl->goalZ[g].currency) << "</td>";
2334  //cout << "<td>" << oInvProbl->goalZ[g].currency << "</td>";
2335  cout << "</tr>" << endl;
2336  }
2337  if (theDate.tm_mon <= 10) theDate.tm_mon++;
2338  else
2339  {
2340  theDate.tm_year++;
2341  theDate.tm_mon = 0;
2342  }
2343  }
2344  cout << "</table></div>";
2345  cout << "<button id=\"btnHide2SP" << g << "\">Hide Savings Plan</button>"; // second hide button under the list
2346 }
2347 
2348 
2357 {
2358  int g, m;
2359  unsigned mNbr, ac;
2360  std::map<int, float> portfolio_composition;
2361  float savings_for_goal;
2362 
2363  cout << "<div class=\"alert alert-info\">\n";
2364  cout << "<h2>Total Portfolio</h2>\n";
2365  cout << "<p>While all goals can be managed in separate portfolios, it might as well suit you to keep all your assets in one portfolio. If you choose to do so, it should look more or less as follows.<br>Below we show the content of your ideal portfolio on different short time horizons. This should allow you to decide on what benchmark you need for the next year.</p>";
2366  cout << "<p>On longer horizons, we recommended to re-run and update this tool in the future (eg. once per year) and adapt your portfolio accordingly.</p>\n";
2367  cout << "<p>Below we show your average composition on " + to_string(oConfig.total_portf_monthNbrs.size()) + " different horizons so that you can choose to hold a portfolio equal to the average or make it evolve.</p>\n";
2368  cout << "<ul>";
2369  for (mNbr = 1; mNbr <= oConfig.total_portf_monthNbrs.size(); mNbr++)
2370  {
2371  for(ac=1; ac <= NBR_ASSET_CLASSES; ac++) portfolio_composition[ac] = 0;
2372  for (g = 1; g <= oInvProbl->get_nbr_goals(); g++)
2373  {
2374  savings_for_goal = 0;
2375  for (m = 0; m <= min(oConfig.total_portf_monthNbrs[mNbr-1], oInvProbl->goalZ[g].realization_monthNbr); m++)
2376  {
2377  savings_for_goal += (oInvProbl->goalZ[g].saving_plan[m]);// - oInvProbl->goalZ[g].means_goal[m] - ((m == oInvProbl->goalZ[g].realization_monthNbr)?oInvProbl->goalZ[g].amount:0.0));
2378  //cout << "<br>oInvProbl->goalZ[" << g << "].means_goal[" << m << "])" << oInvProbl->goalZ[g].means_goal[m];
2379  }
2380  for (ac=1; ac <= NBR_ASSET_CLASSES; ac++)
2381  {
2382  portfolio_composition[ac] += oInvProbl->goalZ[g].benchmark[ac] * savings_for_goal;
2383  }
2384  }
2385  // output the results
2386  cout << "<li>On a horizon of " << to_string(oConfig.total_portf_monthNbrs[mNbr-1]) << " months your portfolio should look approximately as follows:<br>";
2387  parse_bm(portfolio_composition, 1000 + mNbr); // add 1000 to avoid re-using an existing number (assuming the user uses less than 1000 goals
2388  cout << "</li>\n";
2389  }
2390  cout << "</ul>";
2391  cout << "</div>\n";
2392 
2393 }
2394 
2398 void investor_ui::parse_simulation_duration_form(int nbrMonths, string action)
2399 {
2400  int nYrs = (int)floor(nbrMonths / 12);
2401  int nMnths = nbrMonths - nYrs * 12;
2402  cout << "<div class=\"alert alert-info\">";
2403  cout << "\n<form method=\"post\" action=\"" + oConfig.soft_url + "\" id=\"simulation_duration\">\n";
2404  cout << "<fieldset>\n";
2405  cout << "<h2>" << t_simulation_duration << "</h2>";
2406  cout << "<ol>\n";
2407  cout << "<li>\n";
2408  cout << "<label for=\"nYears\" id=\"follow_up_nbrYrs\" align=\"left\">years</label>"
2409  << "<input type=\"number\" name=\"nYears\" autofocus=\"true\" required min=\"0\" max=\"" << (int)(MAX_MNTHS_2_SIMULATE / 12) << "\" placeholder=\"1\" value=\"" << nYrs << "\">\n";
2410  cout << "</li>\n<li>";
2411  cout << "<label for=\"nMonths\" id=\"follow_up_nbrMonths\" >months</label><input type=\"number\" name=\"nMonths\" autofocus=\"false\" required min=\"0\" max=\"" << MAX_MNTHS_2_SIMULATE << "\" placeholder=\"0\" value=\"" << nMnths << "\">\n";
2412  cout << "</li>\n<li>";
2413  cout << "<button class=\"btn btn-primary\" type=\"submit\" value=\"Submit\" id=\"sim_dur\">Simulate Again</button>\n&nbsp;";
2414 // cout << "<button type=\"reset\" value=\"reset\">Reset</button>\n&nbsp;";
2415  cout << "</li></ol>\n";
2416 cout << "</fieldset>";
2417  cout << "<input type=\"hidden\" name=\"a\" value=\"" << action << "\" />&nbsp;\n";
2418  cout << "</form>\n";
2419  cout << "</div>";
2420 }
2421 
2426 {
2427  cout << "<div class=\"alert alert-info\">";
2428  cout << "<H2>How this simulation over " << months2yms(oSim->get_nbrMonths2simulate()) << " worked out</H2>";
2429  oSim->plot_market_evol();
2430  cout << "<div id=\"chartMEvol\" style=\"height:350px; width:650px;\"></div>";
2431  cout << "<p>To see another simulation: " << "<button class=\"btn btn-primary\" type=\"submit\" value=\"Submit\" id=\"sim_dur\">Simulate Again</button>\n&nbsp;</p>";
2432  cout << "</div>";
2433 }
string soft_url
const string t_Desirability
string get_full_name()
string round2str(float x, int nbr_digits=0)
void plot_market_evol()
bool set_password(const string &s)
cash_flow oCF
Definition: efp.cpp:200
void load_covar(int person, char person_type= 'i')
void reload_ER(int person, char person_type= 'i')
TODO: the ER and assetClass_mu as well as the covar and assetClass_covar are redundant ==> eliminate ...
bool is_valid_dateStr(string theDate)
unordered_map< string, unordered_map< string, string > > t_personalize
const string css_dir
bool set_last_name(const string &s)
string button_to(string go_to, string description, char type_redir)
const string t_b_currency
Definition: texts_Eng_UK.h:32
const string t_Asset_Class
Definition: texts_Eng_UK.h:16
bool exists()
Definition: bona.class.cpp:382
bool set_investor_id(const string &s)
std::map< int, string > get_assetList()
void personalize_ERvol_table()
string dateStr2Age(string the_date)
struct tm birth_date
bool add_to_db()
int get_nbrMonths2simulate()
returns the number of months to simulate as in "37"
goal oGoal
Definition: efp.cpp:198
void show_home_screen_form()
std::map< int, int > desirability
std::map< int, string > asset_class_names
this variable is to be filled out when needed
void bs_modal(string title, string content, string id="myModal", string b1_text="", string b1_url="")
unordered_map< string, string > t_feedback_post
Definition: texts_Eng_UK.h:154
void personalize_set_general()
const string t_collapse
Definition: texts_Eng_UK.h:25
string currency
the default currency for that customer
void reload_covar(int person, char what2do, char person_type= 'i')
bool set_max_shortfall(string shortfall)
unordered_map< string, string > t_feedback
Definition: texts_Eng_UK.h:140
void aside(const string &textLine)
const string t_Knowledge
bool set_currency(const std::string &s)
float age(int Mnbr=0)
sql::ResultSet * res
bool set_first_name(const string &s)
string from_date
bool set_description(const std::string &s)
const string t_save
Definition: texts_Eng_UK.h:20
void show_register_form_body()
unordered_map< int, string > t_plotlabels_evol
Definition: texts_Eng_UK.h:199
cls_currency oCurrency
Definition: efp.cpp:187
void update_last_activity_at()
bool set_description(string desc)
void parse_form_open_personalize(string the_content)
const string t_Experience
string months2yms(int m)
bool set_goal_type(string g_type)
saves the benchmark and savings plan, !!! TODO
const string t_Register
Definition: texts_Eng_UK.h:28
bool delete_bona()
Definition: bona.class.cpp:350
void header(int iid=0, bool addSavingsPlan=false, bool addPlots=false)
unordered_map< int, string > goal_type_i2s
Definition: efp.cpp:168
asset_class oAssetClass
Definition: efp.cpp:190
sql::Statement * stmt
std::map< int, int > knowledge
const string t_personalize1
bool add_to_db()
void parse_simulation_insight(simulation *oSim)
#define MAX_MNTHS_2_SIMULATE
the maximum number of months that we allow to visualize a simulation
Definition: efp.cpp:92
const string t_info_curr
#define SIMULATE_TILL_DEFAULT
the standard age to stop the simulation
Definition: efp.cpp:75
bool set_asset_id(const std::string &s)
void personalize_vol_table()
void show_edit_form(int iid)
Definition: asset.class.cpp:63
void save_ER(int person=0, char person_type= 'i')
string add0(int x, int n=1)
void parse_dashboard()
bool set_amount(const std::string &s)
void init_personalize()
string collapse_open(string parent_id, string title, int nbr, bool add_triangle=true, bool is_open=true, string xtra_body_class="")
#define NBR_ASSET_CLASSES
the nunmber of asset classes (not dynamically updated!)
Definition: efp.cpp:97
void parse_simulation_duration_form(int nbrMonths, string action="s")
string error_message
global message variables
Definition: efp.cpp:132
html_helper hh
const string t_cancel
Definition: texts_Eng_UK.h:23
void prepare_javaVars_colors(int g, int followup_mnth)
float simulate_till_age
string dropDown_currency(string defaultCurr="EUR")
int age2monthNbr(float theAge)
string password
bool set_user_name(const string &s)
const string tbl_prefix
tables start with "" + oConfig.tbl_prefix + "_" if the prefix is eg. "tbl" then we have "tbl_invesotr...
bool set_simulate_till_age(const string &s)
tm get_tm(int monthNbr=0)
global functions
void show_edit_form(int iid, bool showExisting=false)
Definition: bona.class.cpp:108
void personalize_covar_table()
void personalize_ER_table()
string curr_format(float dv, string the_curr="")
bool load()
Definition: asset.class.cpp:42
void personalize_set_vol()
#define MIN_YEARS_TO_SIMULATE
the minimal number of years that can be simulated with this tool
Definition: efp.cpp:76
asset oAsset
Definition: efp.cpp:193
string dropDown_assetClass(int defaultAC=0)
string tm2DateStr(tm tmDate)
unordered_map< string, string > t_regFrm
Definition: texts_Eng_UK.h:77
bool set_from_date(string f_date)
void set_max_exposure()
sets the max_exposure vector based on the experience, knowledge and desirability
string last_name
void parse_bm(std::map< int, float > benchmark, int ref_number)
const string t_clear_form
Definition: texts_Eng_UK.h:24
bool set_currency(string curr)
std::map< int, int > experience
void solve()
allocates means (with a benchmark) to goals
void personalize_reload(string action)
bool set_currency(const string &s)
bool runSQL(string s)
string user_name
void parse_form_close_personalize(string the_content, bool show_reload=true)
bool set_priority(string imp)
check if exists, if not then add the default
db_helper db
Definition: efp.cpp:183
void show_account_form_body()
const string t_Login
Definition: texts_Eng_UK.h:27
bool set_curr(string the_curr)
std::map< int, column > tbl
Definition: bona.class.cpp:14
string get_box_color_class(string the_color)
const string t_reset
Definition: texts_Eng_UK.h:19
bool save_preferences()
sets the experience, knowledge and desirability vectors
bool load_fromEnv()
Definition: bona.class.cpp:336
void load_ER(int person=0, char person_type= 'i')
int get_from_db(string investorID, string password)
string parse_user_info(bool parse_wrapper=true)
bool set_scale(string scale_type, int ac, int val)
const bool merge_ER_vol
true to show ER and vol together in one table in the "Personalize" screen
const string t_disclaimer
const string t_b_date
Definition: texts_Eng_UK.h:33
void javaGraph(int g, string xtra_var="", string xtra_label="", int followup_mnth=0)
bool set_asset_class(const std::string &s)
Cgicc cgi
Definition: efp.cpp:129
string first_name
void show_inventory_form()
std::map< int, float > max_exposure
the maximum exposure per asset class
void show_toolBar(string tab_name, string usrName="")
bool save()
Definition: bona.class.cpp:276
void parse_savings_plan(investment_problem *oInvProbl, int g)
void footer(string tab_name, string extraInfo="")
std::vector< int > total_portf_monthNbrs
the month numbers used to show the total portfolio composition
bool asset_delete()
string collapse_close(string parent_id="", int nbr=0, bool add_triangle=true)
bool load_fromDB()
Definition: bona.class.cpp:44
void list_assets(int iid)
bool save()
unordered_map< string, string > t_errMsg
Definition: texts_Eng_UK.h:86
void dateStr2tm(string dStr, tm *target_tm)
bool set_investor_id_fromEnv()
void show_inventory_form_body()
std::map< int, std::map< int, float > > covar
bool set_realization_age(string real_age, float actual_age)
string std_message
Definition: efp.cpp:133
bool set_till_date(string t_date)
const string t_simulation_duration
Definition: texts_Eng_UK.h:29
void personalize_set_corr()
const string t_Max_Exp
void show_goal_help_form_body()
const string t_info_bdate
const string assetClassColors
std::map< int, float > ER
void load_preferences()
sets the experience, knowledge and desirability vectors
void cout_box_color(string the_color)
static const double a[]
Definition: normdist.h:5
void save_covar(int person, char person_type= 'i')
config oConfig
mysql connection mysql connector from dev.mysql.com
Definition: efp.cpp:149
std::map< int, aGOAL > goalZ
map containing all goals
void parse_javaGraph(int g, string xtra_var="", string xtra_label="")
plots the chartOverview
void parse_goal_box(investment_problem *oInvProbl, int g, string s_var="", string s_desc="")
void show_total_portfolio(investment_problem *oInvProbl)
const string t_info_simtill
const string t_reload
string mNbr2dateStr(int monthNbr=0)
char layout
Presentation.
bool exists(int iid)
const string t_show_extra_info
Definition: texts_Eng_UK.h:104
bool set_investor(const std::string &s)
bool set_frequency(string freq)
void personalize_pref_table()
void show_login_form_body()
void personalize_set_prefs()
unordered_map< string, string > t_aside
Definition: texts_Eng_UK.h:40
bool set_birth_date(const string &s)
void list(int iid, bool editable=true)
Definition: bona.class.cpp:157
unordered_map< string, int > goal_type_s2i
Global lists.
Definition: efp.cpp:160
bool set_amount(string amnt)
Needs goal_type to be set first.
const string t_sim_till
Definition: texts_Eng_UK.h:34
int months2simulate()