eFinancialPlanner  V1.0 (proof of concept)
Personal Financial Planning based on Maslowian Portfolio Theory
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
aGOAL.struct.cpp
Go to the documentation of this file.
1 
5 struct aGOAL
6  {
7  public:
8  aGOAL(int investor_id = 0) {this->investor = investor_id;}
9 
11  int goal_id;
12  int investor = 0;
13  int goal_type;
14  float amount;
15  float target_amount;
17  std::map<int, float> means_goal;
18 
19  string description;
20  string currency;
21  int priority;
22  string from_date;
23  string till_date;
24  string frequency;
27 
29  float alpha = 0.1;
32  std::map<int, float> saving_plan;
35  std::map<int, float> benchmark;
36  std::string remarks;
37  string color;
39  bool success;
40  string simulation_string = "";
41  float simulation_endvalue = 0;
42  string s_low = "";
43  string s_exp = "";
44  string s_high = "";
45  string s_goal = "";
46 
47 
49  friend ostream& operator<<(ostream& os, const aGOAL& the_goal);
50 
51 /* void save_this(string g_type, string descr, string curr, string priority,
52  string f_date, string t_date, string f, string r_age,
53  stirng amount, string m_shortfall);
54 */
55 
56 // bool set_unallocated_goal(); --> moved to investment_problem
57  void set_from_db();
58  void set_to_pstmnt();
59  bool save();
60  bool add_to_db();
61  void save_results();
62 
63  bool set_goal_type (string g_type);
64  bool set_amount (string amnt);
65  bool set_description (string desc);
66  bool set_currency (string curr);
67  bool set_priority (string imp);
68  bool set_from_date (string f_date);
69  bool set_till_date (string t_date);
70  bool set_frequency (string freq);
71  bool set_realization_age (string real_age, float actual_age);
72  bool set_max_shortfall (string shortfall);
73  int show_graph_till_MNbr ();
74  };
75 
76 
80 ostream& operator<<(ostream& os, const aGOAL& the_goal)
81 {
82  if (the_goal.goal_type == goal_type_s2i["unallocated"])
83  {
84  os << "The goal <b><i>&quot;" << the_goal.description << "&quot;</i></b> is to show you the resources that are not used by your other goals.";
85  }
86  else if (the_goal.goal_type == goal_type_s2i["income from/to"])
87  {
88  cls_frequency the_freq;
89  the_freq.set_freq(the_goal.frequency);
90  string s = the_freq.get_freq_label();
91  std::transform(s.begin(), s.end(), s.begin(), ::tolower);
92 
93  os << setiosflags(ios::fixed) << setprecision(2)
94  << "The goal <b><i>&quot;" << the_goal.description << "&quot;</i></b> is to achieve"
95  << " an income of " << curr_format(the_goal.amount, the_goal.currency)
96  << " (" << s << ")"
97  << " from " << date_format_dateStr(the_goal.from_date)
98  << " to " << date_format_dateStr(the_goal.till_date) << ".<br>"
99  << "This goal's relative priority is " << the_goal.priority;
100  }
101  else if (the_goal.goal_type == goal_type_s2i["rainy day savings"])
102  {
103  os << setiosflags(ios::fixed) << setprecision(2)
104  << "This goal <b><i>&quot;" << the_goal.description << "&quot;</i></b> is to have a safety layer (\"rainy day savings\") always available."
105  << "The amount that we try to keep available is " << curr_format(the_goal.amount, the_goal.currency)
106  << ".<br>This goal's relative priority is " << the_goal.priority;
107  }
108  else if (the_goal.goal_type == goal_type_s2i["amount asap"])
109  {
110  os << setiosflags(ios::fixed) << setprecision(2)
111  << "This goal <b><i>&quot;" << the_goal.description << "&quot;</i></b> is to obtain the sum of " << curr_format(the_goal.amount, the_goal.currency)
112  << " asap.<br>This goal's relative priority is " << the_goal.priority;
113  }
114  else
115  {
116  os << setiosflags(ios::fixed) << setprecision(2)
117  << "The goal <b><i>&quot;" << the_goal.description << "&quot;</i></b> is to achieve"
118  << " an amount of " << curr_format(the_goal.amount, the_goal.currency)
119  << " at the age of " << setprecision(0) << the_goal.realization_age << ".<br>" <<setprecision(2)
120  << "This goal's relative priority is " << the_goal.priority
121  << " and we accept a maximum shortfall of " << curr_format(the_goal.max_shortfall, the_goal.currency) << ".";
122  }
123  return os;
124 }
125 
126 bool aGOAL::set_goal_type(string g_type)
127 {
128  int g_type_id = atoi(g_type.c_str());
129  unordered_map<int, string>::const_iterator got = goal_type_i2s.find(g_type_id);
130  if (got == goal_type_i2s.end())
131  {
132  error_message = error_message + "<li>the goal_type is not one of the supported types</li>";
133  return false;
134  }
135  else
136  {
137  this->goal_type = g_type_id;
138  return true;
139  }
140 }
141 
142 bool aGOAL::set_amount(string amnt)
143 {
144  this->amount = atof(amnt.c_str()); // returns 0.0 if no valid number is found
145  return true;
146 }
147 
148 bool aGOAL::set_currency(string curr)
149 {
150  cls_currency o_curr;
151  if (o_curr.set_curr(curr))
152  {
153  this->currency = curr;
154  return true;
155  }
156  else
157  {
158  error_message = error_message + "<li>error occured saving the currency --- not a valid currency</li>";
159  return false;
160  }
161 }
162 
163 bool aGOAL::set_description(string desc)
164 {
165  if (desc == "")
166  {
167  this->description = "Please change this text with your own goal-description!";
168  }
169  else
170  {
171  this-> description = desc;
172  }
173  return true;
174 }
175 
176 
177 bool aGOAL::set_priority(string imp)
178 {
179  this->priority = atoi(imp.c_str());
180  return true;
181 }
182 
189 bool aGOAL::set_realization_age(string real_age, float actual_age)
190 {
191  float the_age;
192  the_age = atof(real_age.c_str());
193  if ((the_age < actual_age) || (the_age > (MAX_AGE + 0.0)))
194  {
195  error_message = error_message + "<li>the realization_age of the goal should be a number between your actual age and " + to_string(MAX_AGE + 0) + "(provided: realization age = " + real_age + "; compared to actual age = " + to_string(actual_age) + ".</li>";
196  return false;
197  }
198  else
199  {
200  this->realization_age = the_age;
201 //NOT this->from_date = tm2DateStr(get_tm((the_age - actual_age) * 12));
202 //NOT this->till_date = this->from_date;
203 //NOT override! this->frequency = "O";
204  return true;
205  }
206 }
207 
208 bool aGOAL::set_frequency(string freq)
209 {
210  cls_frequency o_freq;
211  if (o_freq.set_freq(freq))
212  {
213  this->frequency = freq;
214  return true;
215  }
216  else
217  {
218  error_message = error_message + "<li>error saving the frequency information</li>";
219  return false;
220  }
221 }
222 
223 bool aGOAL::set_from_date(string f_date)
224 {
225  if (is_valid_dateStr(f_date))
226  {
227  from_date = f_date;
228  return true;
229  }
230  else
231  {
232  error_message = error_message + "<li>from_date is not a valid date</li>";
233  return false;
234  }
235 }
236 
242 bool aGOAL::set_till_date(string t_date)
243 {
244  struct tm tm_from_date, tm_till_date;
245  dateStr2tm(this->from_date, &tm_from_date);
246  dateStr2tm(t_date, &tm_till_date);
247  if (is_valid_dateStr(t_date))
248  {
249  if (difftime(mktime(&tm_till_date),mktime(&tm_from_date)) >= 0)
250  {
251  till_date = t_date;
252  return true;
253  }
254  else
255  {
256  error_message = error_message + "<li>the till_date must be after the from_date (it cannot precede the from_date)</li>";
257  return false;
258  }
259 
260  }
261  else
262  {
263  error_message = error_message + "<li>till_date is not a valid date</li>";
264  return false;
265  }
266 }
267 
268 bool aGOAL::set_max_shortfall(string shortfall)
269 {
270  float the_sf = atof(shortfall.c_str());
271  if ((this->goal_type != goal_type_s2i["income from/to"]) && (the_sf > this->amount))
272  {
273  std_message = std_message + "<li>are you sure that the shortfall can be higher than the target amount (note: this is saved, but you might want to reconsider)</li>";
274  }
275  this->max_shortfall = the_sf;
276  return true;
277 }
278 
279 
281 {
282  if (this->investor == 0)
283  {
284  error_message = error_message + "<li>Failed to add_to_db, because investor id not set</li>.";
285  return false;
286  }
287  string s;
288  s = "INSERT INTO " + oConfig.tbl_prefix + "_goals (investor, goal_type, description, need_level, realization_age, from_date, ";
289  s = s + "till_date, frequency, amount, currency, max_shortfall, priority) VALUES (?,?,?,?,?,?,?,?,?,?,?,?);";
290 
291  try
292  {
293  db.pstmt = db.con->prepareStatement(s);
294  db.pstmt->setInt ( 1,investor);
295  db.pstmt->setInt ( 2,this->goal_type);
296  db.pstmt->setString( 3,this->description);
297  db.pstmt->setInt ( 4,1);
298  db.pstmt->setDouble( 5,this->realization_age);
299  db.pstmt->setString( 6,this->from_date);
300  db.pstmt->setString( 7,this->till_date);
301  db.pstmt->setString( 8,this->frequency);
302  db.pstmt->setDouble( 9,this->amount);
303  db.pstmt->setString(10,this->currency);
304  db.pstmt->setDouble(11,this->max_shortfall);
305  db.pstmt->setInt (12,this->priority);
306  db.pstmt->execute();
307  }
308 
309  catch (sql::SQLException &e)
310  {
311  #ifdef DEBUG
312  debug_info = debug_info + "# ERR: SQLException in " + __FILE__ + "(" + __FUNCTION__
313  + ") on line " + to_string(__LINE__) + "<br># ERR: " + e.what()
314  + " (MySQL error code: " + to_string(e.getErrorCode())
315  + ", SQLState: " + e.getSQLState() + " )<br>";
316  #endif
317  error_message = error_message + "<li>Sorry, I failed to add the goal <b>&quot;" + this->description + "&quot;</b> to the database. Please, retry!</li>";
318  return false;
319  }
320  return true; // if we're still here, then no exception was thrown and the INSERT INTO was successful.
321 }
322 
328 {
329  string s;
330  s = "UPDATE " + oConfig.tbl_prefix + "_goals SET , goal_type = ?, description = ?, need_level = ?, realization_age = ?, from_date = ?, ";
331  s = s + "till_date = ?, frequency = ?, amount = ?, currency = ?, max_shortfall = ?, priority = ?";
332  s = s + " WHERE investor_id = " + to_string(this->investor) + ";";
333 
334  try
335  {
336  db.pstmt = db.con->prepareStatement(s);
337  set_to_pstmnt();
338  }
339 
340  catch (sql::SQLException &e)
341  {
342  #ifdef DEBUG
343  debug_info = debug_info + "# ERR: SQLException in " + __FILE__ + "(" + __FUNCTION__
344  + ") on line " + to_string(__LINE__) + "<br># ERR: " + e.what()
345  + " (MySQL error code: " + to_string(e.getErrorCode())
346  + ", SQLState: " + e.getSQLState() + " )<br>";
347  #endif
348  error_message = error_message + "<li>Sorry, I failed to save the goal <b>&quot;" + this->description + "&quot;</b> the remains unchanged!</li>";
349  return false;
350  }
351  return true; // if we're still here, then no exception was thrown and the INSERT INTO was successful.
352 
353 }
354 
355 
356 
363 {
364  this->goal_id = db.res->getInt("goal_id");
365  this->investor = db.res->getInt("investor");
366  this->amount = db.res->getDouble("amount");
367  this->goal_type = db.res->getInt("goal_type");
368  this->description = db.res->getString("description");
369  this->realization_age = atof(db.res->getString("realization_age").c_str());
370  this->currency = db.res->getString("currency");
371  this->priority = db.res->getInt("priority");
372  this->from_date = db.res->getString("from_date");
373  this->till_date = db.res->getString("till_date");
374  this->frequency = db.res->getString("frequency");
375  this->max_shortfall = atof(db.res->getString("max_shortfall").c_str());
376 // not loaded:
377 // need_level INT(10) REFERENCES " + oConfig.tbl_prefix + "_need_levels(need_level_id) ON DELETE RESTRICT,
378 
379 }
380 
382 {
383  db.pstmt->setInt ( 1,investor);
384  db.pstmt->setInt ( 2,this->goal_type);
385  db.pstmt->setString( 3,this->description);
386  db.pstmt->setInt ( 4,1); // need level not used right now
387  db.pstmt->setDouble( 5,this->realization_age);
388  db.pstmt->setString( 6,this->from_date);
389  db.pstmt->setString( 7,this->till_date);
390  db.pstmt->setString( 8,this->frequency);
391  db.pstmt->setDouble( 9,this->amount);
392  db.pstmt->setString(10,this->currency);
393  db.pstmt->setDouble(11,this->max_shortfall);
394  db.pstmt->setInt (12,this->priority);
395  db.pstmt->execute();
396 }
397 
string get_freq_label()
bool success
bool is_valid_dateStr(string theDate)
string date_format_dateStr(string s)
string color_followup
std::map< int, float > means_goal
the means implied by the goal (eg. the regular income during retirement for goal type income from/to)...
bool add_to_db()
string color
string s_goal
javaScript variable for the upper quantile
std::string remarks
bool set_max_shortfall(string shortfall)
sql::ResultSet * res
bool set_freq(string the_freq)
string from_date
std::map< int, float > benchmark
int goal_type
(0, "unallocated"), (1, "amount@date"), (2, "income from/to"), (3, "rainy day savings"), (4, "amount asap");
float amount
string s_exp
ostream & operator<<(ostream &os, const aGOAL &the_goal)
void set_to_pstmnt()
bool set_description(string desc)
string simulation_string
a string containing the simulated values of the advised portfolio [45,1000], [45,083, 1100], etc.]]
bool set_goal_type(string g_type)
saves the benchmark and savings plan, !!! TODO
unordered_map< int, string > goal_type_i2s
Definition: efp.cpp:168
string error_message
global message variables
Definition: efp.cpp:132
const string tbl_prefix
tables start with "" + oConfig.tbl_prefix + "_" if the prefix is eg. "tbl" then we have "tbl_invesotr...
string frequency
bool save()
friend ostream & operator<<(ostream &os, const aGOAL &the_goal)
other functions:
string curr_format(float dv, string the_curr="")
float realization_age
aGOAL(int investor_id=0)
constructor
Definition: aGOAL.struct.cpp:8
bool set_from_date(string f_date)
float simulation_endvalue
the last value obtained by the simulation (only used in the Follow-Up screens to allow the evolution ...
bool set_currency(string curr)
void set_from_db()
int realization_monthNbr
float max_shortfall
bool set_priority(string imp)
check if exists, if not then add the default
db_helper db
Definition: efp.cpp:183
bool set_curr(string the_curr)
string description
string s_low
javaScript variable for the lower quantile as [[45,100], [45.1,101],....]
std::map< int, float > saving_plan
variables calculated and allocated during investment_problem.solve() AFTER solution: ...
int optimal_portf
void dateStr2tm(string dStr, tm *target_tm)
bool set_realization_age(string real_age, float actual_age)
sql::Connection * con
string std_message
Definition: efp.cpp:133
bool set_till_date(string t_date)
string s_high
javaScript variable for the expecpted evolution
int goal_id
variables stored in database before investment_problem.solve():
int priority
float realized_shortfall
#define MAX_AGE
the maximum age allowed in the goals
Definition: efp.cpp:66
config oConfig
mysql connection mysql connector from dev.mysql.com
Definition: efp.cpp:149
string till_date
float target_amount
target_amount is for goal_type amount
void save_results()
string currency
float alpha
variables calculated and allocated during investment_problem.solve() BEFORE solution: ...
bool set_frequency(string freq)
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.
sql::PreparedStatement * pstmt
int show_graph_till_MNbr()