1 /**
2 *  Copyright Mikael H�gdahl - triyana@users.sourceforge.net
3 *
4 *  This source is distributed under the terms of the Q Public License version 1.0,
5 *  created by Trolltech (www.trolltech.com).
6 */
7 
8 #include <table/PortfolioData.h>
9 #include <db/Account.h>
10 #include <db/DBFactory.h>
11 #include <db/Portfolio.h>
12 #include <db/Portfolio2.h>
13 #include <db/Security.h>
14 #include <gui/XTrader.h>
15 #include <Resource.h>
16 #include <MHDate.h>
17 #include <MHString.h>
18 #include <FL/Fl.H>
19 
20 
21 
22 /**
23 *  @param Security* - The security object to load price data for. Caller is responsible for deleting object
24 */
PortfolioData(Account * a)25 PortfolioData::PortfolioData (Account* a) :
26 BaseData () {
27     aAccount        = *a;
28     aVector           = new MHVector (500);
29     aVectorSecurity = new MHVector (500);
30     aVectorTotal    = new MHVector (500);
31     aVectorBalance  = new MHVector (500);
32     aChoiceEvent    = MHUtil::Allocate (Portfolio::EV_TRANSFER, 31);
33 
34     Portfolio::Load (&aAccount, aVector);
35 
36     for (int f = 0; f < Portfolio::EV_TRANSFER; f++)
37         STRNCPY (aChoiceEvent[f], Portfolio::GetEventName(f), 30)
38     reload ("Security");
39     calcBalance ();
40 }
41 
42 
43 
44 /**
45 *
46 */
~PortfolioData()47 PortfolioData::~PortfolioData () {
48     MHUtil::Delete (aChoiceEvent, Portfolio::EV_TRANSFER);
49     if (aChoiceSecurity)
50         MHUtil::Delete (aChoiceSecurity, aVectorSecurity->Size() + 1);
51     aVector->Erase ();
52     aVectorSecurity->Erase ();
53     aVectorTotal->Erase ();
54     aVectorBalance->Erase ();
55     delete aVector;
56     delete aVectorSecurity;
57     delete aVectorTotal;
58     delete aVectorBalance;
59 }
60 
61 
62 
63 /**
64 *
65 */
add()66 void PortfolioData::add () {
67     insert (aVector->Size());
68 }
69 
70 
71 
72 /**
73 *
74 */
align(int row,int col)75 Fl_Align PortfolioData::align (int row, int col) {
76     switch (col) {
77         case 4:
78         case 5:
79         case 6:
80         case 7:
81         case 8:
82             return FL_ALIGN_RIGHT;
83 
84         case 0:
85         case 1:
86         case 2:
87         case 3:
88         default:
89             return FL_ALIGN_LEFT;
90     }
91 }
92 
93 
94 
95 /**
96 *  Calc. transaction balance
97 */
calcBalance()98 void PortfolioData::calcBalance () {
99     double balance = aAccount.GetBalance();
100 
101     aVectorTotal->Erase ();
102     aVectorBalance->Erase ();
103 
104     for (int f = 0; f < aVector->Size(); f++) {
105         Portfolio2* p2 = (Portfolio2*) (*aVector)[f];
106 
107         balance += p2->CashValue();
108         aVectorTotal->Push (new MHString (p2->CashValue()));
109         aVectorBalance->Push (new MHString (balance));
110     }
111 }
112 
113 
114 
115 /**
116 *
117 */
choice(int row,int col,int & size,int & selected,char * label)118 const char** PortfolioData::choice (int row, int col, int& size, int& selected, char* label) {
119     int         f;
120     Portfolio*  p = (Portfolio*) aVector->Get (row);
121 
122     switch (col) {
123         case 1:
124             //  Portfolio events
125             size     = Portfolio::EV_TRANSFER;
126             selected = 0;
127             for (f = 0; f < Portfolio::EV_TRANSFER; f++) {
128                 if (strcmp (Portfolio::GetEventName(p->GetEvent()), aChoiceEvent[f]) == 0) {
129                     selected = f;
130                     break;
131                 }
132             }
133               return (char const**) aChoiceEvent;
134 
135         case 3:
136             //  Security for portfolio buy/sell/dividend event
137             size     = aVectorSecurity->Size() + 1;
138             selected = 0;
139 
140             for (f = 0; f < aVectorSecurity->Size(); f++) {
141                 Security* s = (Security*) (*aVectorSecurity)[f];
142                 if (s->GetID() == p->GetSecurityID()) {
143                     selected = f + 1;
144                     break;
145                 }
146             }
147             strncpy (label, STRING(SELECT_SECURITY), 99);
148             return (char const**) aChoiceSecurity;
149     }
150 
151     return 0;
152 }
153 
154 
155 
156 /**
157 *
158 */
editor_type(int row,int col,bool force_custom)159 FL_TABLE_EDITOR PortfolioData::editor_type (int row, int col, bool force_custom) {
160     switch (col) {
161         case 0:
162         case 2:
163             return FL_TEXT_EDITOR;
164 
165         case 1:
166             return FL_LIST_EDITOR;
167 
168         case 3:
169             return FL_DLG_LIST_EDITOR;
170 
171         case 7:
172         case 8:
173             return FL_NO_EDITOR;
174 
175         default:
176             return FL_FLOAT_EDITOR;
177     }
178 }
179 
180 
181 
182 /**
183 *
184 */
erase(int row)185 void PortfolioData::erase (int row) {
186     if (row >= 0 && row < aVector->Size()) {
187         aVector->Erase (row);
188         dirty (true);
189     }
190 }
191 
192 
193 
194 /**
195 *
196 */
insert(int row)197 void PortfolioData::insert (int row) {
198     MHDate     d;
199     Portfolio* p = new Portfolio (d.Get (MHDate::LONG_DATE), Portfolio::EV_IN, 0, 0.0, 0.0, 0.0, 0, 0, "");
200 
201     aVector->Insert (p, row);
202     aVectorTotal->Insert (new MHString(), row);
203     aVectorBalance->Insert (new MHString(), row);
204     dirty (true);
205 }
206 
207 
208 
209 /**
210 *
211 */
reload(const char * message)212 void PortfolioData::reload (const char* message) {
213     if (strcmp (message, "Security") == 0) {
214         Portfolio::LoadSecurities (aVector);
215 
216         if (aVectorSecurity->Size() > 0) MHUtil::Delete (aChoiceSecurity, aVectorSecurity->Size() + 1);
217         aVectorSecurity->Erase ();
218         Security::Load (aVectorSecurity);
219         aVectorSecurity->Sort (Security::SORT_NAME);
220 
221         aChoiceSecurity = MHUtil::Allocate (aVectorSecurity->Size() + 1, 31);
222         STRNCPY (aChoiceSecurity[0], " ", 30)
223         for (int f = 1; f <= aVectorSecurity->Size(); f++) {
224             Security* s = (Security*) (*aVectorSecurity)[f - 1];
225             STRNCPY (aChoiceSecurity[f], s->GetName()->Get(), 30)
226         }
227     }
228     else if (strcmp (message, "Account") == 0) {
229         calcBalance ();
230     }
231 }
232 
233 
234 
235 /**
236 *
237 */
save()238 int PortfolioData::save () {
239     Portfolio::Save (&aAccount, aVector);
240     calcBalance ();
241     dirty (false);
242     XTrader::SetInfo (STRING(DATA_SAVED));
243     XTrader::SendMessage (0, "Portfolio", "changed", "", &aAccount);
244     return -1;
245 }
246 
247 
248 
249 /**
250 *
251 */
sort(int col,bool ascending)252 void PortfolioData::sort (int col, bool ascending) {
253 }
254 
255 
256 
257 /**
258 *
259 */
value(const char * data,int row,int col)260 bool PortfolioData::value (const char* data, int row, int col) {
261     Portfolio* p  = (Portfolio*) (*aVector)[row];
262 
263     switch (col) {
264         case 0:
265             if (strcmp (p->GetDate()->Get(), data) == 0) return true;
266             if (MHDate::ValidDate (data) == false)
267                 return false;
268             p->SetDate (data);
269             break;
270 
271         case 1: {
272             for (int f = 0; f < Portfolio::EV_TRANSFER; f++) {
273                 if (strcmp (Portfolio::GetEventName(f), data) == 0) {
274                     p->SetEvent ((Portfolio::EVENT)f);
275                     break;
276                 }
277             }
278             break;
279         }
280 
281         case 2:
282             p->SetMemo (data);
283             break;
284 
285         case 3:
286             if (strcmp (data, "") == 0)
287                 p->SetSecurityID (0);
288             else {
289                 for (int f = 0; f < aVectorSecurity->Size(); f++) {
290                     Security* s = (Security*) (*aVectorSecurity)[f];
291 
292                     if (strcmp (s->GetName()->Get(), data) == 0) {
293                         if (p->GetEvent() >= Portfolio::EV_USE_SECURITY)
294                             p->SetSecurityID (s->GetID());
295                         else
296                             p->SetSecurityID (0);
297                         break;
298                     }
299                 }
300             }
301             p->LoadSecurity ();
302             break;
303 
304         case 4:
305             p->SetVolume (atof(data));
306             break;
307 
308         case 5:
309             p->SetPrice (atof(data));
310             break;
311 
312         case 6:
313             p->SetCourtage (atof(data));
314             break;
315     }
316 
317     if (p->GetEvent() < Portfolio::EV_USE_SECURITY) {
318         p->SetVolume (0.0);
319         p->SetCourtage (0.0);
320         p->SetSecurityID (0);
321         p->LoadSecurity ();
322     }
323 
324     dirty (true);
325     return true;
326 }
327 
328 
329 
330 /**
331 *
332 */
value(int row,int col)333 const char* PortfolioData::value (int row, int col) {
334     if (row == FL_LABEL_ROW)
335         return aAccount.GetAccount()->Get();
336     else if (row == FL_HEADER_ROW) {
337         switch (col) {
338             case 0:
339                 return STRING(DATE);
340 
341             case 1:
342                 return STRING(TYPE);
343 
344             case 2:
345                 return STRING(MEMO);
346 
347             case 3:
348                 return STRING(SECURITY);
349 
350             case 4:
351                 return STRING(VOLUME);
352 
353             case 5:
354                 return STRING(PRICE);
355 
356             case 6:
357                 return STRING(COURTAGE);
358 
359             case 7:
360                 return STRING(TOTAL);
361 
362             case 8:
363                 return STRING(BALANCE);
364 
365             default:
366                 return "";
367         }
368     }
369     else {
370         Portfolio* p = (Portfolio*) (*aVector)[row];
371 
372         switch (col) {
373             case 0:
374                 return p->GetDate()->Get();
375 
376             case 1:
377                 return p->GetEventName(p->GetEvent());
378 
379             case 2:
380                 return p->GetMemo()->Get();
381 
382             case 3:
383                 return p->GetSecurity()->GetName()->Get();
384 
385             case 4:
386                 snprintf (aBuff, 30, "%.2f", p->GetVolume());
387                 return aBuff;
388 
389             case 5:
390                 snprintf (aBuff, 30, "%.2f", p->GetPrice());
391                 return aBuff;
392 
393             case 6:
394                 snprintf (aBuff, 30, "%.2f", p->GetCourtage());
395                 return aBuff;
396 
397             case 7:
398                 return ((MHString*) (*aVectorTotal)[row])->Get();
399 
400             case 8:
401                 return ((MHString*) (*aVectorBalance)[row])->Get();
402 
403             default:
404                 return "";
405         }
406     }
407 }
408 
409 
410 
411 /**
412 *
413 */
width(int col)414 int PortfolioData::width (int col) {
415     switch (col) {
416         case 2:
417         case 3:
418             return XTrader::FontSize() * 8;
419 
420         default:
421             return XTrader::FontSize() * 6;
422     }
423 }
424