KissCount

KissCount Git Source Tree

Root/src/view/AccountPanel.cpp

1/*
2 Copyright 2010-2012 Grégory Soutadé
3
4 This file is part of KissCount.
5
6 KissCount is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 KissCount is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with KissCount. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include <QHeaderView>
21#include <QGroupBox>
22#include <QMessageBox>
23
24#include "AccountPanel.hpp"
25#include "grid/FloatDelegate.hpp"
26#include "GenerateDialog.hpp"
27#include "SnapshotsDialog.hpp"
28
29enum {ACCOUNT_NUMBER, ACCOUNT_NAME, ACCOUNT_INIT, ACCOUNT_CUR, ACCOUNT_FINAL, NUMBER_COLS_ACCOUNTS};
30enum {CUR_CREDIT, CUR_DEBIT, TOTAL_CREDIT, TOTAL_DEBIT, BALANCE, CATS_STATS};
31
32enum {VIRTUAL_MODE=0, REAL_MODE, CHECK_MODE};
33
34AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent, bool lowResolution) :
35 KissPanel(kiss, parent, lowResolution), _curMonth(-1), _curYear(-1), _inModification(false)
36{
37 Init(kiss, parent, 0);
38}
39
40AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent, bool lowResolution, int month=-1, int year=-1, int mode=VIRTUAL_MODE) : KissPanel(kiss, parent, lowResolution), _curMonth(month), _curYear(year), _inModification(false)
41{
42 Init(kiss, parent, mode);
43}
44
45void AccountPanel::Init(KissCount* kiss, wxUI *parent, int curMode)
46{
47 QHBoxLayout *hbox = new QHBoxLayout;
48 QHBoxLayout *hbox2 = new QHBoxLayout;
49 QVBoxLayout *vbox = new QVBoxLayout;
50 QVBoxLayout *vbox2 = new QVBoxLayout;
51 QVBoxLayout *vbox3 = new QVBoxLayout;
52 int i;
53 User* user = _kiss->GetUser();
54 std::vector<Account>::iterator accountIt;
55 std::vector<Category>::iterator categoryIt;
56
57 _icons[KissPanel::LOW_RES_ICON] = USER_LOW_ICON;
58 _icons[KissPanel::HIGH_RES_ICON] = USER_ICON;
59
60 setLayout(hbox);
61
62 _tree = new QTreeWidget(this);
63 _tree->headerItem()->setHidden(true);
64 _tree->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
65 connect(_tree, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(OnTreeChange(QTreeWidgetItem*, int)));
66 _tree->setContextMenuPolicy(Qt::CustomContextMenu);
67 connect(_tree, SIGNAL(customContextMenuRequested ( const QPoint & )), this, SLOT(OnTreeRightClick(const QPoint &)));
68
69 _calendar = new QCalendarWidget(this);
70 _calendar->setGridVisible(false);
71 _calendar->setFirstDayOfWeek(Qt::Monday);
72 _calendar->setNavigationBarVisible(false);
73 _calendar->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
74 _calendar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
75 connect(_calendar, SIGNAL(selectionChanged ()), this, SLOT(OnCalendarChange()));
76
77 _accounts = new QString[user->GetAccountsNumber()];
78 for (i=0,
79 accountIt = user->_accounts.begin();
80 accountIt != user->_accounts.end();
81 accountIt++, i++)
82 _accounts[i] = accountIt->name;
83
84 _categories = new QString[user->GetCategoriesNumber()] ;
85 for(i=0, categoryIt = user->_categories.begin();
86 categoryIt != user->_categories.end();
87 categoryIt++, i++)
88 {
89 _categories[i] = _(categoryIt->name.toStdString().c_str()) ;
90 _categoriesIndexes[categoryIt->name] = i;
91 }
92
93 _categoriesValues = new int[user->GetCategoriesNumber()];
94
95 _grid = new GridAccount(_kiss, this, true, true, true);
96 _grid->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
97
98 _accountsGrid = new QTableWidget(this);
99 _accountsGrid->setColumnCount(NUMBER_COLS_ACCOUNTS);
100 _accountsGrid->setRowCount(0);
101 _accountsGrid->verticalHeader()->setHidden(true);
102
103 _accountsGrid->resizeColumnsToContents();
104 _accountsGrid->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
105
106 connect(_accountsGrid, SIGNAL(cellChanged(int, int)), this, SLOT(OnAccountModified(int, int)));
107
108 _statsGrid = new QTableWidget(this);
109 _statsGrid->verticalHeader()->setHidden(true);
110 _statsGrid->horizontalHeader()->setHidden(true);
111 _statsGrid->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
112
113 _costRepartitionBanner = new CostRepartitionBanner(_kiss, this, _categories);
114
115 QGroupBox *groupBox = new QGroupBox(_("Mode"));
116
117 _virtual = new QRadioButton(_("Virtual"));
118 _real = new QRadioButton(_("Real"));
119 _check = new QRadioButton(_("Check"));
120
121 switch(curMode)
122 {
123 case VIRTUAL_MODE: _virtual->setChecked(true); break;
124 case REAL_MODE: _real->setChecked(true); break;
125 case CHECK_MODE: _check->setChecked(true); break;
126 default: _virtual->setChecked(true); break;
127 }
128
129 {
130QVBoxLayout *vbox = new QVBoxLayout;
131vbox->addWidget(_virtual);
132vbox->addWidget(_real);
133vbox->addWidget(_check);
134groupBox->setLayout(vbox);
135 }
136
137 connect(_virtual, SIGNAL(clicked()), this, SLOT(OnModeChange()));
138 connect(_real, SIGNAL(clicked()), this, SLOT(OnModeChange()));
139 connect(_check, SIGNAL(clicked()), this, SLOT(OnModeChange()));
140
141 // _tree.SetIndent(5);
142
143 QPushButton* buttonGroup = new QPushButton(_("Group"));
144 QPushButton* buttonUnGroup = new QPushButton(_("UnGroup"));
145 QPushButton* buttonUpdateNextMonths = new QPushButton(_("Update next months"));
146 QPushButton* buttonSnapshots = new QPushButton(_("Snapshots"));
147
148 connect(buttonGroup, SIGNAL(clicked()), this, SLOT(OnGroup()));
149 connect(buttonUnGroup, SIGNAL(clicked()), this, SLOT(OnUnGroup()));
150 connect(buttonUpdateNextMonths, SIGNAL(clicked()), this, SLOT(OnUpdateNextMonths()));
151 connect(buttonSnapshots, SIGNAL(clicked()), this, SLOT(OnSnapshots()));
152
153 vbox3->addWidget(_tree);
154 vbox3->addWidget(buttonUpdateNextMonths);
155 vbox3->addStretch(1);
156 vbox3->addWidget(buttonGroup);
157 vbox3->addWidget(buttonUnGroup);
158 vbox3->addStretch(1);
159 vbox3->addWidget(buttonSnapshots);
160 vbox3->addStretch(1);
161 vbox3->addWidget(groupBox);
162
163 hbox->addLayout(vbox3);
164 hbox2->addWidget(_accountsGrid, 2);
165 hbox2->addWidget(_calendar);
166 vbox2->addLayout(hbox2);
167 vbox2->addWidget(_grid, 1);
168 hbox->addLayout(vbox2);
169 vbox->addWidget(_statsGrid);
170 vbox->addWidget(_costRepartitionBanner);
171 hbox->addLayout(vbox);
172
173 ChangeUser();
174
175 layout();
176}
177
178AccountPanel::~AccountPanel()
179{
180 delete[] _categoriesValues;
181 delete[] _categories;
182 delete[] _accounts;
183}
184
185KissPanel* AccountPanel::CreatePanel()
186{
187 int mode;
188
189 if (_virtual->isChecked()) mode = VIRTUAL_MODE;
190 else if (_real->isChecked()) mode = REAL_MODE;
191 else if (_check->isChecked()) mode = CHECK_MODE;
192
193 return new AccountPanel(_kiss, _wxUI, _lowResolution, _curMonth, _curYear, mode);
194}
195
196QString AccountPanel::GetToolTip()
197{
198 return _("Operations");
199}
200
201void AccountPanel::InitStatsGrid(User* user)
202{
203 DEFAULT_FONT(font);
204
205 if (!_statsGrid->rowCount())
206 {
207_statsGrid->setColumnCount(2);
208 //_statsGrid->EnableEditing(false);
209 }
210 else
211 {
212 _statsGrid->clear();
213 }
214 _statsGrid->setRowCount(CATS_STATS); // Headers
215
216 _statsGrid->setItem(TOTAL_CREDIT, 0, new QTableWidgetItem(_("Total Credit")));
217 _statsGrid->setItem(TOTAL_DEBIT, 0, new QTableWidgetItem(_("Total Debit")));
218
219 font.setBold(true);
220
221 _statsGrid->setItem(CUR_CREDIT, 0, new QTableWidgetItem(_("Cur Credit")));
222 _statsGrid->setItem(CUR_DEBIT, 0, new QTableWidgetItem(_("Cur Debit")));
223 _statsGrid->setItem(TOTAL_CREDIT, 0, new QTableWidgetItem(_("Total Credit")));
224 _statsGrid->setItem(TOTAL_DEBIT, 0, new QTableWidgetItem(_("Total Debit")));
225 _statsGrid->setItem(BALANCE, 0, new QTableWidgetItem(_("Balance")));
226
227 _statsGrid->setItem(CUR_CREDIT, 1, new QTableWidgetItem(""));
228 _statsGrid->setItem(CUR_DEBIT, 1, new QTableWidgetItem(""));
229 _statsGrid->setItem(TOTAL_CREDIT, 1, new QTableWidgetItem(""));
230 _statsGrid->setItem(TOTAL_DEBIT, 1, new QTableWidgetItem(""));
231 _statsGrid->setItem(BALANCE, 1, new QTableWidgetItem(""));
232
233 _statsGrid->item(CUR_DEBIT, 0)->setFont(font);
234 _statsGrid->item(CUR_CREDIT, 0)->setFont(font);
235 _statsGrid->item(BALANCE, 0)->setFont(font);
236 _statsGrid->item(BALANCE, 1)->setFont(font);
237
238 _statsGrid->item(CUR_CREDIT, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
239 _statsGrid->item(CUR_DEBIT, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
240 _statsGrid->item(TOTAL_CREDIT, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
241 _statsGrid->item(TOTAL_DEBIT, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
242 _statsGrid->item(BALANCE, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
243
244 _statsGrid->resizeColumnToContents(0);
245
246 _costRepartitionBanner->Reset();
247}
248
249void AccountPanel::ChangeUser()
250{
251 User* user = _kiss->GetUser();
252 int curYear = -1, year;
253 QDate curDate = QDate::currentDate();
254 QTreeWidgetItem* curNode=0, *node;
255 std::map<int, std::vector<int> > ops;
256 std::map<int, std::vector<int> >::iterator it;
257
258 ops = _kiss->GetAllOperations();
259
260 InitStatsGrid(user);
261
262 _tree->clear();
263
264 if (ops.size())
265 {
266year = (_curYear == -1) ? curDate.year() : _curYear;
267 for(it = ops.begin(); it != ops.end(); it++)
268 {
269 node = new QTreeWidgetItem(QStringList(QString::number(it->first)));
270 if ((int)it->first <= year)
271 {
272 curYear = it->first;
273curNode = node;
274 }
275 _tree->addTopLevelItem(node);
276 }
277 if (curYear != -1)
278 {
279 _tree->setCurrentItem(curNode);
280 LoadYear(curYear, true);
281 }
282 }
283 else
284 {
285curNode = new QTreeWidgetItem(QStringList(QString::number(curDate.year())));
286_tree->addTopLevelItem(curNode);
287 }
288 layout();
289}
290
291void AccountPanel::LoadYear(int year, bool showMonth)
292{
293 User* user = _kiss->GetUser();
294 int curMonth = -1, month;
295 QTreeWidgetItem* parentNode, *curMonthNode = 0;
296 std::map<int, std::vector<int> > ops ;
297 std::vector<int>::iterator it;
298 QDate curDate = QDate::currentDate();
299
300 if (user->_operations[year] && _tree->currentItem()->childCount())
301 {
302 if (showMonth)
303 ShowMonth(-1, year);
304 return;
305 }
306
307 _curYear = year ;
308 _kiss->LoadYear(year);
309 ops = _kiss->GetAllOperations();
310
311 parentNode = _tree->currentItem();
312
313 if (!parentNode)
314parentNode = _tree->topLevelItem(0);
315
316 if (_curMonth == -1)
317 {
318if (_curYear == curDate.year())
319 month = curDate.month()-1;
320else
321 month = 0;
322 }
323
324 for (it = ops[year].begin(); it != ops[year].end(); it++)
325 {
326if (!curMonthNode || (year == _curYear && *it <= month))
327 {
328 curMonth = *it;
329 curMonthNode = new QTreeWidgetItem(QStringList(wxUI::months[*it]));
330 parentNode->addChild(curMonthNode);
331 }
332else
333 parentNode->addChild(new QTreeWidgetItem(QStringList(wxUI::months[*it])));
334 }
335
336 _tree->expandItem(parentNode);
337 layout();
338 if (showMonth)
339 {
340_tree->setCurrentItem(curMonthNode);
341 ShowMonth(curMonth, year);
342 }
343
344 _wxUI->layout();
345}
346
347void AccountPanel::ShowMonth(int month, int year)
348{
349 // std::vector<Operation> operations;
350 // _fixCosts = 0;
351 User* user = _kiss->GetUser();
352 // std::vector<Category>::iterator categoryIt;
353 std::map<unsigned int, std::vector<Operation> >::iterator monthIt;
354 QDate curDate = QDate::currentDate();
355 QDate dateStart = QDate::currentDate();
356 QDate dateEnd = QDate::currentDate();
357
358 if (month == -1)
359 {
360 // Near month
361 if (year == curDate.year())
362 {
363 for (monthIt = user->_operations[year]->begin(); monthIt != user->_operations[year]->end(); monthIt++)
364 {
365 if ((int)monthIt->first+1 <= curDate.month())
366 {
367 month = monthIt->first;
368 }
369 }
370 }
371
372 // First month
373 if (month == -1)
374 {
375 monthIt = user->_operations[year]->begin();
376 if (user->_operations[year]->size() == 0 && year == curDate.year())
377 month = curDate.month();
378 else
379 month = monthIt->first;
380 }
381 }
382
383 _curYear = year;
384 _curMonth = month;
385 _wxUI->setWindowTitle(user->_name + " - " + wxUI::months[month] + " " + QString::number(year));
386
387 // if (_grid->GetNumberRows() > 1)
388 // _grid->DeleteRows(1, _grid->GetNumberRows()-1);
389
390 // Operations are ordered
391 _curOperations = &((*user->_operations[year])[month]);
392
393 _grid->LoadOperations(_curOperations, _curMonth, _curYear);
394
395 disconnect(_accountsGrid, SIGNAL(cellChanged(int, int)), this, SLOT(OnAccountModified(int, int)));
396
397 InitAccountsGrid(user, month, year);
398
399 connect(_accountsGrid, SIGNAL(cellChanged(int, int)), this, SLOT(OnAccountModified(int, int)));
400
401 dateStart.setDate(_curYear, _curMonth+1, 1);
402 dateEnd.setDate(_curYear, _curMonth+1, dateStart.daysInMonth());
403 _calendar->setDateRange(dateStart, dateEnd);
404 if (curDate.month() == (_curMonth+1) && curDate.year() == year)
405_calendar->setSelectedDate (curDate) ;
406 else if ((curDate.month()-1) > month || curDate.year() > year)
407_calendar->setSelectedDate (dateEnd) ;
408 else if ((curDate.month()-1) < month || curDate.year() < year)
409_calendar->setSelectedDate(dateStart) ;
410
411 UpdateStats();
412
413 layout();
414}
415
416void AccountPanel::InitAccountsGrid(User* user, int month, int year)
417{
418 std::vector<Account>::iterator it;
419 int curLine = 0;
420 int value;
421 int i, nbAccounts;
422 QTableWidgetItem* item;
423 QString v;
424 DEFAULT_FONT(font);
425
426 font.setBold(true);
427
428 if (_accountsGrid->rowCount())
429 _accountsGrid->clear();
430
431 _accountsGrid->setHorizontalHeaderItem(ACCOUNT_NUMBER, new QTableWidgetItem(_("Account number")));
432 _accountsGrid->setHorizontalHeaderItem(ACCOUNT_NAME, new QTableWidgetItem(_("Account name")));
433 _accountsGrid->setHorizontalHeaderItem(ACCOUNT_INIT, new QTableWidgetItem(_("Initial value")));
434 _accountsGrid->setHorizontalHeaderItem(ACCOUNT_CUR, new QTableWidgetItem(_("Current value")));
435 _accountsGrid->setHorizontalHeaderItem(ACCOUNT_FINAL, new QTableWidgetItem(_("Final value")));
436
437 for(i=0; i<NUMBER_COLS_ACCOUNTS; i++)
438 {
439_accountsGrid->horizontalHeaderItem(i)->setFont(font);
440 }
441
442 FloatDelegate* floatEditor = new FloatDelegate(_accountsGrid);
443 _accountsGrid->setItemDelegateForColumn(ACCOUNT_INIT, floatEditor);
444
445 nbAccounts = 0;
446 for (it = user->_accounts.begin(); it != user->_accounts.end(); it++)
447 {
448if (!it->hidden) nbAccounts++;
449 }
450
451 _accountsGrid->setRowCount(nbAccounts);
452
453 for (it = user->_accounts.begin(); it != user->_accounts.end(); it++, curLine++)
454 {
455if (it->hidden)
456{
457 value = _kiss->GetAccountAmount(it->id, month, year);
458 _accountsInitValues[it->id] = value;
459 curLine--;
460 continue;
461}
462
463 if (it->shared)
464 _accountsGrid->setItem(curLine, ACCOUNT_NUMBER, new QTableWidgetItem(it->number + "*"));
465 else
466 _accountsGrid->setItem(curLine, ACCOUNT_NUMBER, new QTableWidgetItem(it->number));
467
468 _accountsGrid->setItem(curLine, ACCOUNT_NAME, new QTableWidgetItem(it->name));
469 value = _kiss->GetAccountAmount(it->id, month, year);
470
471 _accountsGrid->setItem(curLine, ACCOUNT_INIT, new QTableWidgetItem(v.sprintf("%.2lf", (double)value/100)));
472 _accountsGrid->setItem(curLine, ACCOUNT_CUR, new QTableWidgetItem(""));
473 _accountsGrid->setItem(curLine, ACCOUNT_FINAL, new QTableWidgetItem(""));
474 for (i=0; i<NUMBER_COLS_ACCOUNTS; i++)
475{
476 item = _accountsGrid->item(curLine, i);
477 if (i != ACCOUNT_INIT)
478item->setFlags(item->flags() & ~Qt::ItemIsEditable);
479 if (i == ACCOUNT_CUR)
480item->setFont(font);
481}
482 _accountsInitValues[it->id] = value;
483 _accountsGrid->item(curLine, ACCOUNT_INIT)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
484 _accountsGrid->item(curLine, ACCOUNT_CUR)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
485 _accountsGrid->item(curLine, ACCOUNT_FINAL)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
486 }
487
488 _accountsGrid->resizeColumnsToContents();
489}
490
491void AccountPanel::UpdateStats()
492{
493 int i;
494 User* user = _kiss->GetUser();
495 std::vector<Operation>::iterator it;
496 int curCredit, curDebit, totalCredit, totalDebit, balance, value, value2, percents;
497 std::map<int, int> curAccountAmount, finalAccountAmount;
498 std::map<int, int>::iterator intIt;
499 std::vector<Account>::iterator accountIt;
500 unsigned int day;
501 int mode;
502 std::map<int, int>* notChecked = 0;
503 std::map<int, int>* virtuals = 0;
504 Account account;
505 Operation op;
506 bool blocked_account ;
507 QString v;
508
509 _inModification = true;
510
511 if (_virtual->isChecked()) mode = VIRTUAL_MODE;
512 else if (_real->isChecked()) mode = REAL_MODE;
513 else if (_check->isChecked()) mode = CHECK_MODE;
514
515 curCredit = curDebit = totalCredit = totalDebit = percents = 0.0;
516
517 if (mode == CHECK_MODE)
518 notChecked = _kiss->GetNotChecked(_curMonth, _curYear);
519
520 if (mode == REAL_MODE || mode == CHECK_MODE)
521 virtuals = _kiss->GetVirtualAmount(_curMonth, _curYear);
522
523 day = _calendar->selectedDate().day()-1;
524
525 for (i=0; i<user->GetCategoriesNumber(); i++)
526 _categoriesValues[i] = 0.0;
527
528 for (intIt=_accountsInitValues.begin(); intIt!=_accountsInitValues.end(); intIt++)
529 {
530 curAccountAmount[intIt->first] = _accountsInitValues[intIt->first];
531 finalAccountAmount[intIt->first] = _accountsInitValues[intIt->first];
532
533 if (mode == REAL_MODE || mode == CHECK_MODE)
534 {
535 curAccountAmount[intIt->first] += -(*virtuals)[intIt->first];
536 finalAccountAmount[intIt->first] += -(*virtuals)[intIt->first];
537 }
538 }
539
540 for (it=_curOperations->begin(); it!=_curOperations->end(); it++)
541 {
542 if (it->meta) continue;
543
544 op = *it;
545 blocked_account = false;
546
547if ((mode == REAL_MODE || mode == CHECK_MODE) && op._virtual)
548 continue;
549
550if (mode == CHECK_MODE && !op.checked)
551 continue;
552
553account = user->GetAccount(op.account);
554
555if (account.blocked)
556{
557 if (op.transfert && op.amount > 0)
558 {
559// A Transfert on a blocked account must be considered as a debit
560op.amount = -op.amount;
561// op.transfert = 0;
562blocked_account = true;
563 }
564 // else
565 // continue;
566 }
567
568if (op.amount >= 0)
569{
570 if (!op.transfert && !account.blocked)
571totalCredit += op.amount;
572
573 if (day >= op.day)
574 {
575if (!op.transfert && !account.blocked)
576 curCredit += op.amount;
577curAccountAmount[op.account] += op.amount;
578 }
579 finalAccountAmount[op.account] += op.amount;
580}
581else
582{
583 if ((!op.transfert || account.blocked) && user->GetCategoryName(op.category) != _("Unknown"))
584_categoriesValues[_categoriesIndexes[user->GetCategoryName(op.category)]] += -op.amount ;
585
586 if (!op.transfert || account.blocked)
587totalDebit += -op.amount;
588
589 if (day >= op.day)
590 {
591if (!op.transfert || account.blocked)
592 curDebit += -op.amount;
593 }
594
595 if (blocked_account)
596op.amount = -op.amount;
597
598 if (day >= op.day)
599curAccountAmount[op.account] += op.amount;
600 finalAccountAmount[op.account] += op.amount;
601}
602 }
603
604 balance = totalCredit - totalDebit;
605 _statsGrid->item(CUR_CREDIT, 1)->setText(v.sprintf("%.2lf", (double)curCredit/100));
606 _statsGrid->item(CUR_DEBIT, 1)->setText(v.sprintf("%.2lf", (double)curDebit/100));
607 _statsGrid->item(TOTAL_CREDIT, 1)->setText(v.sprintf("%.2lf", (double)totalCredit/100));
608 _statsGrid->item(TOTAL_DEBIT, 1)->setText(v.sprintf("%.2lf", (double)totalDebit/100));
609
610 _statsGrid->item(BALANCE, 1)->setText(v.sprintf("%.2lf", (double)balance/100));
611 _statsGrid->item(BALANCE, 1)->setForeground((balance >= 0) ? QBrush(Qt::green) : QBrush(Qt::red));
612
613 for (i=0, accountIt=user->_accounts.begin(); accountIt!=user->_accounts.end(); accountIt++, i++)
614 {
615if (accountIt->hidden)
616{
617 i--;
618 continue;
619}
620
621 if (mode != CHECK_MODE)
622 {
623 value = _accountsInitValues[accountIt->id];
624 if (mode == REAL_MODE)
625 value -= (*virtuals)[accountIt->id];
626 _accountsGrid->item(i, ACCOUNT_INIT)->setText(v.sprintf("%.2lf", (double)value/100));
627 value = curAccountAmount[accountIt->id];
628 _accountsGrid->item(i, ACCOUNT_CUR)->setText(v.sprintf("%.2lf", (double)value/100));
629 _accountsGrid->item(i, ACCOUNT_CUR)->setForeground((value >= 0) ? QBrush(Qt::black) : QBrush(Qt::red));
630 value = finalAccountAmount[accountIt->id];
631 _accountsGrid->item(i, ACCOUNT_FINAL)->setText(v.sprintf("%.2lf", (double)value/100));
632 }
633 else
634 {
635 value = _accountsInitValues[accountIt->id] - (*virtuals)[accountIt->id];
636 value2 = (*notChecked)[accountIt->id];
637
638 _accountsGrid->item(i, ACCOUNT_INIT)->setText(v.sprintf("%.2lf (%.2lf)", (double)value/100, (double)(value-value2)/100));
639 value = curAccountAmount[accountIt->id];
640 _accountsGrid->item(i, ACCOUNT_CUR)->setText(v.sprintf("%.2lf (%.2lf)", (double)value/100, (double)(value-value2)/100));
641 _accountsGrid->item(i, ACCOUNT_CUR)->setForeground((value >= 0) ? QBrush(Qt::black) : QBrush(Qt::red));
642 value = finalAccountAmount[accountIt->id];
643 _accountsGrid->item(i, ACCOUNT_FINAL)->setText(v.sprintf("%.2lf (%.2lf)", (double)value/100, (double)(value-value2)/100));
644 }
645 }
646
647 _costRepartitionBanner->UpdateCosts(_categoriesValues, totalDebit);
648
649 _accountsGrid->resizeColumnToContents(ACCOUNT_INIT);
650 _accountsGrid->resizeColumnToContents(ACCOUNT_CUR);
651 _accountsGrid->resizeColumnToContents(ACCOUNT_FINAL);
652
653 if (notChecked) delete notChecked;
654 if (virtuals) delete virtuals;
655
656 _statsGrid->resizeColumnToContents(1);
657
658 layout();
659
660 _inModification = false;
661}
662
663void AccountPanel::OnOperationModified()
664{
665 UpdateStats();
666
667 layout();
668}
669
670void AccountPanel::OnAccountModified(int row, int column)
671{
672 User* user = _kiss->GetUser();
673 int amount;
674 int id = user->GetAccountId(_accounts[row]);
675
676 if (_inModification || column != ACCOUNT_INIT) return;
677
678 amount = _accountsGrid->item(row, column)->text().replace(".", "").toInt();
679 _kiss->SetAccountAmount(id, _curMonth, _curYear, amount);
680 _accountsInitValues[id] = amount;
681
682 UpdateStats();
683}
684
685void AccountPanel::OnTreeRightClick(const QPoint & pos)
686{
687 QMenu menu(this);
688
689 menu.addAction(_("Generate month"), this, SLOT(OnMenuGenerate()));
690 menu.addSeparator();
691 if (_tree->columnCount() >= 1)
692menu.addAction(_("Delete"), this, SLOT(OnMenuDelete()));
693
694 menu.exec(QCursor::pos());
695}
696
697void AccountPanel::OnTreeChange (QTreeWidgetItem * item, int column)
698{
699 int month=-1, year;
700 int i;
701 QString monthString;
702
703 item = _tree->currentItem ();
704
705 if (!item) return;
706
707 monthString = item->text(column);
708
709 for (i=0; i<12; i++)
710 {
711 if (monthString == wxUI::months[i])
712 {
713 month = i;
714 break;
715 }
716 }
717
718 if (month == -1)
719 {
720 year = monthString.toInt();
721
722 // Error
723 if (year == 0)
724 {
725 return;
726 }
727
728 if (year == _curYear)
729 {
730 return;
731 }
732
733 // _tree.CollapseAll();
734 // _tree.Expand(event.GetItem());
735 LoadYear(year, true);
736 }
737 else
738 {
739item = item->parent();
740 year = item->text(column).toInt();
741
742 // Error
743 if (year == 0)
744 {
745 return;
746 }
747
748 if (year != _curYear || month != _curMonth)
749 {
750 ShowMonth(month, year);
751 }
752 }
753
754}
755
756void AccountPanel::GetTreeSelection(int* month, int* year)
757{
758 QString monthString;
759 int i;
760 bool ok;
761
762 *month = -1; *year = -1;
763
764 monthString = _tree->currentItem()->text(0);
765 for (i=0; i<12; i++)
766 if (monthString == wxUI::months[i])
767 {
768 *month = i;
769 break;
770 }
771
772 if (*month == -1)
773 {
774 *year = monthString.toInt(&ok);
775
776 // Error
777 if (!ok)
778 {
779 *month = -1;
780 *year = -1;
781 return;
782 }
783 }
784 else
785 {
786*year = _tree->currentItem()->parent()->text(0).toInt(&ok);
787
788 // Error
789 if (!ok)
790 {
791 *month = -1;
792 *year = -1;
793 return;
794 }
795 }
796}
797
798void AccountPanel::OnMenuGenerate()
799{
800 int month, year;
801 QDate curDate = QDate::currentDate();
802
803 GetTreeSelection(&month, &year);
804
805 if (month == -1 && year == curDate.year())
806 {
807 month = _curMonth;
808 }
809
810 _wxUI->setEnabled(false);
811 GenerateDialog g(_kiss, _wxUI, month, year);
812 g.setModal(true);
813 g.exec();
814 _wxUI->setEnabled(true);
815}
816
817void AccountPanel::OnMenuDelete()
818{
819 int month, year, i;
820 QString message;
821 QTreeWidgetItem* curNode, *node ;
822 std::map<int, std::vector<int> > ops ;
823
824 GetTreeSelection(&month, &year);
825
826 ops = _kiss->GetAllOperations();
827
828 if (ops.size() == 1 && (ops[year].size() == 1 || month == -1))
829 {
830 QMessageBox::critical(0, _("Error"), _("It must be at least one month !"));
831 return;
832 }
833
834 message = _("Are you sure want to delete ");
835 if (month != -1)
836 message += wxUI::months[month] + " ";
837 message += QString::number(year);
838
839 message += _(" operations ?");
840
841 if (QMessageBox::question(0, "KissCount", message, QMessageBox::Yes|QMessageBox::No) == QMessageBox::No)
842 return;
843
844 curNode = _tree->currentItem();
845
846 if (ops[year].size() == 1 && month != -1)
847 curNode = curNode->parent();
848
849 _kiss->DeleteOperations(month, year);
850
851 i = _tree->indexOfTopLevelItem(curNode);
852 if (i == -1)
853 {
854node = _tree->itemBelow(curNode);
855
856if (!node)
857 node = _tree->itemAbove(curNode);
858
859curNode->parent()->removeChild(curNode);
860 _tree->setCurrentItem(node);
861 }
862 else
863 {
864delete _tree->takeTopLevelItem(i);
865if (i) i--;
866 _tree->setCurrentItem(_tree->topLevelItem(i));
867curNode = _tree->topLevelItem(i);
868if (!curNode->childCount())
869 LoadYear(curNode->text(0).toInt());
870_tree->setCurrentItem(curNode->child(curNode->childCount()-1));
871 }
872
873 if (!node)
874 ChangeUser();
875 else
876 {
877 GetTreeSelection(&month, &year);
878 if (month == -1)
879 month = ops[year][0];
880 ShowMonth(month, year);
881_wxUI->NeedReload();
882 }
883}
884
885void AccountPanel::GenerateMonth(int month, int year)
886{
887 QString s;
888 const QString syear = s.sprintf("%d", year);
889 QList<QTreeWidgetItem *> items = _tree->findItems(syear, Qt::MatchExactly|Qt::MatchRecursive);
890 QTreeWidgetItem *root, *itemYear = 0, *itemMonth;
891 std::map<int, std::vector<int> > ops ;
892 std::vector<int>::iterator it ;
893
894 int i;
895
896 ops = _kiss->GetAllOperations();
897
898 // Year not found
899 if (items.size() == 0)
900 {
901for(i=0; i<_tree->topLevelItemCount(); i++)
902{
903 root = _tree->topLevelItem(i);
904 if (root->text(0).toInt() > year)
905break;
906}
907itemYear = new QTreeWidgetItem(QStringList(syear));
908_tree->insertTopLevelItem(i, itemYear);
909_tree->setCurrentItem(itemYear);
910 }
911 else
912itemYear = items[0];
913
914 for(i=0, it = ops[year].begin(); it != ops[year].end(); it++, i++)
915 {
916if (*it > month)
917 break;
918 }
919
920 if (i) i--;
921 itemMonth = new QTreeWidgetItem(QStringList(wxUI::months[month]));
922 itemYear->insertChild(i, itemMonth);
923 _tree->setCurrentItem(itemMonth);
924
925 ShowMonth(month, year);
926 _wxUI->NeedReload();
927}
928
929void AccountPanel::OnShow()
930{
931 User* user = _kiss->GetUser();
932
933 if (_curMonth != -1)
934_wxUI->setWindowTitle(user->_name + " - " + wxUI::months[_curMonth] + " " + QString::number(_curYear));
935 else
936_wxUI->setWindowTitle(user->_name);
937}
938
939void AccountPanel::OnCalendarChange()
940{
941 UpdateStats();
942}
943
944void AccountPanel::OnModeChange()
945{
946 UpdateStats();
947}
948
949void AccountPanel::OnGroup()
950{
951 if (_grid)
952_grid->Group();
953}
954
955void AccountPanel::OnUnGroup()
956{
957 if (_grid)
958_grid->UnGroup();
959}
960
961void AccountPanel::OnUpdateNextMonths()
962{
963 int *cur_amounts, amount, i;
964 User* user = _kiss->GetUser();
965 bool has_values, accounts_updated = false;
966 int cur_month = 0, cur_year = 0, delta_computed = 0;
967 int last_month, last_year;
968 bool *valid_account;
969
970 cur_amounts = new int[user->_accounts.size()] ;
971 valid_account = new bool[user->_accounts.size()] ;
972
973 cur_month = _curMonth;
974 cur_year = _curYear;
975
976 for (i=0; i<(int)user->_accounts.size(); i++)
977 {
978cur_amounts[i] = _kiss->GetAccountAmount(user->_accounts[i].id, cur_month, cur_year, &has_values, false);
979valid_account[i] = has_values;
980 }
981
982 while (1)
983 {
984delta_computed = 0;
985
986for (i=0; i<(int)user->_accounts.size(); i++)
987{
988 if (!valid_account[i]) continue;
989 cur_amounts[i] += _kiss->CalcAccountAmount(user->_accounts[i].id, cur_month, cur_year, &has_values);
990 if (has_values)
991delta_computed++;
992}
993
994if (!delta_computed) break;
995
996if (cur_month == 11)
997{
998 cur_month = 0;
999 cur_year++;
1000}
1001else
1002 cur_month++;
1003
1004for (i=0; i<(int)user->_accounts.size(); i++)
1005{
1006 if (!valid_account[i]) continue;
1007 amount = _kiss->GetAccountAmount(user->_accounts[i].id, cur_month, cur_year, &has_values, false);
1008 if (!has_values)
1009 {
1010valid_account[i] = false;
1011continue;
1012 }
1013 if (amount != cur_amounts[i])
1014 {
1015accounts_updated = true;
1016_kiss->SetAccountAmount(user->_accounts[i].id, cur_month, cur_year, cur_amounts[i]);
1017last_month = cur_month; last_year = cur_year;
1018 }
1019}
1020 }
1021
1022 if (accounts_updated)
1023 {
1024QString message = _("Accounts updated until ") + wxUI::months[last_month] + " " + QString::number(last_year);
1025
1026QMessageBox::information(0, "KissCount", message);
1027 }
1028 else
1029QMessageBox::information(0, "KissCount", _("Any account updated !"));
1030
1031 delete[] cur_amounts;
1032}
1033
1034void AccountPanel::OnSnapshots()
1035{
1036 SnapshotsDialog u(_kiss, _wxUI);
1037 u.exec();
1038}

Archive Download this file