diff --git a/controller/KissCount.cpp b/controller/KissCount.cpp index 2e56dbc..d018ed6 100644 --- a/controller/KissCount.cpp +++ b/controller/KissCount.cpp @@ -63,3 +63,8 @@ User* KissCount::GetUser() { return _user; } + +double KissCount::GetAccountAmount(wxString id, int month, int year) +{ + return _db->GetAccountAmount(id, month, year); +} diff --git a/controller/KissCount.h b/controller/KissCount.h index 5fcecb3..66b8041 100644 --- a/controller/KissCount.h +++ b/controller/KissCount.h @@ -20,7 +20,8 @@ class KissCount void LoadUser(wxString user); void LoadYear(int year, bool force=false); User* GetUser(); - + double GetAccountAmount(wxString id, int month, int year); + private: wxUI* _wxUI; Database* _db; diff --git a/init.sql b/init.sql index ef7e4b3..bffa17e 100644 --- a/init.sql +++ b/init.sql @@ -12,10 +12,10 @@ INSERT INTO default_preference ("type", "name", "value") VALUES ("category", "na -- No password INSERT INTO user ("id", "name", "password") VALUES ("0", "Greg", "da39a3ee5e6b4b0d3255bfef95601890afd80709"); INSERT INTO account ("id", "user", "name", "number", "shared", "default_account") VALUES ("0", "0", "Compte Courant", "000" , "0", "1"); -INSERT INTO account_amount("id", "account", "year", "month", "amount") VALUES("0", "0", "2010", "0", "1000"); -INSERT INTO operation ("id", "user", "account", "year", "month", "day", "amount", "description", "category", "fix_cost") VALUES ("0", "0", "0", "2010", "4", "0", "1234", "Opé 1", "0", "1"); -INSERT INTO operation ("id", "user", "account", "year", "month", "day", "amount", "description", "category", "fix_cost") VALUES ("1", "0", "0", "2010", "4", "1", "-56", "Opé 2", "1", "0"); -INSERT INTO operation ("id", "user", "account", "year", "month", "day", "amount", "description", "category", "fix_cost") VALUES ("2", "0", "0", "2010", "4", "29", "-2056", "Opé 3", "2", "0"); +INSERT INTO account_amount("id", "account", "year", "month", "amount") VALUES("0", "0", "2010", "5", "1000"); +INSERT INTO operation ("id", "user", "account", "year", "month", "day", "amount", "description", "category", "fix_cost") VALUES ("0", "0", "0", "2010", "5", "0", "1234", "Opé 1", "0", "1"); +INSERT INTO operation ("id", "user", "account", "year", "month", "day", "amount", "description", "category", "fix_cost") VALUES ("1", "0", "0", "2010", "5", "1", "-56", "Opé 2", "1", "0"); +INSERT INTO operation ("id", "user", "account", "year", "month", "day", "amount", "description", "category", "fix_cost") VALUES ("2", "0", "0", "2010", "5", "29", "-2056", "Opé 3", "2", "0"); INSERT INTO preference ("user", "type", "name", "value") VALUES ("0", "category", "name", "Fixe"); INSERT INTO preference ("user", "type", "name", "value") VALUES ("0", "category", "name", "Courses"); INSERT INTO preference ("user", "type", "name", "value") VALUES ("0", "category", "name", "Loisirs"); diff --git a/model/Database.cpp b/model/Database.cpp index 442e125..8baddbc 100644 --- a/model/Database.cpp +++ b/model/Database.cpp @@ -232,3 +232,26 @@ void Database::LoadYear(User* user, int year) set.Finalize(); } + +double Database::GetAccountAmount(wxString id, int month, int year) +{ + wxSQLite3ResultSet set; + wxString req; + double res; + + req = _("SELECT amount FROM account_amount WHERE account='") + id ; + req += _("' AND month='") + wxString::Format(_("%d"), month); + req += _("' AND year='") + wxString::Format(_("%d"), year); + req += _("'"); + + EXECUTE_SQL_QUERY(req , set, 0.0); + + if (set.NextRow()) + res = set.GetDouble(_("amount")); + else + res = 0.0; + + set.Finalize(); + + return res; +} diff --git a/model/Database.h b/model/Database.h index 8bc7ef5..17a7555 100644 --- a/model/Database.h +++ b/model/Database.h @@ -23,6 +23,7 @@ class Database User* LoadUser(wxString name); void LoadYear(User* user, int year); + double GetAccountAmount(wxString id, int month, int year); private: wxSQLite3Database _db; diff --git a/model/User.cpp b/model/User.cpp index c9114c0..f7844f7 100644 --- a/model/User.cpp +++ b/model/User.cpp @@ -32,3 +32,13 @@ int User::GetCategoriesNumber() { return _preferences._categories.size(); } + +int User::GetAccountsNumber() +{ + return _accounts.size(); +} + +int User::GetOperationsNumber(int month, int year) +{ + return (*_operations[year])[month].size(); +} diff --git a/model/User.h b/model/User.h index 883f720..b427a73 100644 --- a/model/User.h +++ b/model/User.h @@ -41,6 +41,8 @@ public: wxString GetCategoryName(wxString catId); wxString GetAccountName(wxString accountId); int GetCategoriesNumber(); + int GetAccountsNumber(); + int GetOperationsNumber(int month, int year); }; #endif diff --git a/view/AccountPanel.cpp b/view/AccountPanel.cpp index 8f61fe0..8dd2d8f 100644 --- a/view/AccountPanel.cpp +++ b/view/AccountPanel.cpp @@ -2,16 +2,21 @@ static wxString colsName[] = {_("Description"), _("Date"), _("Debit"), _("Credit"), _("Category"), _("Account"), _("")}; -AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*parent)), _kiss(kiss), _wxUI(parent), _tree(this, -1) +BEGIN_EVENT_TABLE(AccountPanel, wxPanel) + EVT_GRID_CMD_CELL_CHANGE(OPS_GRID_ID, AccountPanel::OnOperationModified) +END_EVENT_TABLE() + +AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*parent)), _kiss(kiss), _wxUI(parent), _tree(this, CALENDAR_TREE_ID) { wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); + wxBoxSizer *vbox2 = new wxBoxSizer(wxVERTICAL); wxChartPanel* chart ; int i ; + DEFAULT_FONT(font); User* user = _kiss->GetUser(); std::map::iterator accountIt; std::map::iterator it; - DEFAULT_FONT(font); wxColour categoryColors[] = {wxColour(0x00, 0x45, 0x86), wxColour(0xFF, 0x3E, 0x0E), wxColour(0xFF, 0xD3, 0x20), @@ -60,17 +65,69 @@ AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*parent)), _pie->SetLegend(new Legend(wxBOTTOM, wxCENTER)); - _grid = new GridAccount(this, -1); - _grid->CreateGrid(1, NUMBER_COLS); + _grid = new GridAccount(this, OPS_GRID_ID); + _grid->CreateGrid(1, NUMBER_COLS_OPS); _grid->SetColLabelSize(0); _grid->SetRowLabelSize(0); + _accountsGrid = new wxGrid(this, ACCOUNTS_GRID_ID); + _accountsGrid->CreateGrid(0, NUMBER_COLS_ACCOUNTS); + _accountsGrid->SetRowLabelSize(0); + + _accountsGrid->SetDefaultCellFont(font); + + _accountsGrid->SetColLabelValue(ACCOUNT_NUMBER, _("Account number")); + _accountsGrid->SetColLabelValue(ACCOUNT_NAME, _("Account name")); + _accountsGrid->SetColLabelValue(ACCOUNT_INIT, _("Initial value")); + _accountsGrid->SetColLabelValue(ACCOUNT_CUR, _("Current value")); + _accountsGrid->SetColLabelValue(ACCOUNT_FINAL, _("Final value")); + + _accountsGrid->AutoSizeColumns(true); + _statsGrid = new wxGrid(this, -1); _statsGrid->CreateGrid(user->GetCategoriesNumber()+1+6, 2); _statsGrid->SetColLabelSize(0); _statsGrid->SetRowLabelSize(0); _statsGrid->EnableEditing(false); + InitStatsGrid(user); + + chart = new wxChartPanel(this); + chart->SetChart(new Chart(_pie, _("Cost repartition"))); + chart->Fit(); + chart->Layout(); + chart->SetMinSize(// chart->GetSize() + wxSize(200,250)); + hbox->Add(&_tree, 0); + vbox2->Add(_accountsGrid, 0); + vbox2->Add(-1, 10); + vbox2->Add(_grid, 0); + hbox->Add(vbox2, 0); + vbox->Add(_statsGrid, 0); + vbox->Add(-1, 10); + vbox->Add(chart, 0); + hbox->Add(-1, 10); + hbox->Add(vbox, 0); + + ChangeUser(); + + Fit(); + SetMinSize(GetSize()); +} + +AccountPanel::~AccountPanel() +{ + delete[] _categoriesValues; + delete[] _categories; + delete[] _accounts; +} + +void AccountPanel::InitStatsGrid(User* user) +{ + int i; + + DEFAULT_FONT(font); + _statsGrid->SetDefaultCellFont(font); _statsGrid->SetCellValue(TOTAL_CREDIT, 0, _("Total Credit")); @@ -90,32 +147,6 @@ AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*parent)), _statsGrid->SetCellValue(CUR_CREDIT, 0, _("Cur Credit")); _statsGrid->SetCellValue(CUR_DEBIT, 0, _("Cur Debit")); _statsGrid->SetCellValue(REMAINS, 0, _("Remains")); - - chart = new wxChartPanel(this); - chart->SetChart(new Chart(_pie, _("Cost repartition"))); - chart->Fit(); - chart->Layout(); - chart->SetMinSize(// chart->GetSize() - wxSize(200,250)); - hbox->Add(&_tree, 0); - hbox->Add(_grid, 0); - vbox->Add(_statsGrid, 0); - vbox->Add(-1, 10); - vbox->Add(chart, 0); - hbox->Add(-1, 10); - hbox->Add(vbox, 0); - - ChangeUser(); - - Fit(); - SetMinSize(GetSize()); -} - -AccountPanel::~AccountPanel() -{ - delete[] _categoriesValues; - delete[] _categories; - delete[] _accounts; } void AccountPanel::ChangeUser() @@ -179,7 +210,7 @@ void AccountPanel::LoadYear(int year) ShowMonth(year, curMonth); } -#define SET_ROW_COLOR(row, color) for(int i=0; iSetCellBackgroundColour(row, i, color);\ } @@ -188,7 +219,7 @@ void AccountPanel::ShowMonth(int year, int month) { std::list operations; std::list::iterator it; - int fixCosts = 0; + _fixCosts = 0; int curLine = 0; User* user = _kiss->GetUser(); DEFAULT_FONT(font); @@ -197,18 +228,19 @@ void AccountPanel::ShowMonth(int year, int month) int i; _curMonth = month; - _wxUI->SetTitle(user->_name + _(" - ") + months[month]); + _wxUI->SetTitle(user->_name + _(" - ") + months[month] + _(" ") + wxString::Format(wxT("%d"), year)); // Operations are ordered _curOperations = &((*user->_operations[year])[month]); - _grid->CreateGrid(1, NUMBER_COLS); + //_grid->Clear(); + _grid->CreateGrid(1, NUMBER_COLS_OPS); // Creating headers _grid->SetColSize (0, _grid->GetColSize(0)*3); _grid->SetDefaultCellFont(font); font.SetWeight(wxFONTWEIGHT_BOLD); - for(i=0; iSetCellValue(0, i, colsName[i]); _grid->SetCellBackgroundColour(0, i, OWN_CYAN); @@ -236,26 +268,26 @@ struct operation { wxString description; wxString category; bool fix_cost; -enum {DESCRIPTION, DATE, DEBIT, CREDIT, CATEGORY, ACCOUNT, VIEW, NUMBER_COLS}; +enum {DESCRIPTION, DATE, DEBIT, CREDIT, CATEGORY, ACCOUNT, VIEW, NUMBER_COLS_OPS}; } ; */ for (;it->fix_cost && it != _curOperations->end(); it++) { - _grid->AppendRows(); curLine++; - fixCosts++; + _fixCosts++; + _grid->AppendRows(); SET_ROW_COLOR(curLine, OWN_YELLOW); _grid->SetCellValue(curLine, DESCRIPTION, it->description); _grid->SetCellValue(curLine, DATE, wxString::Format(wxT("%02d/%02d/%d"), it->day+1, it->month+1, it->year)); + _grid->SetCellEditor(curLine, DATE, new CalendarEditor(it->day, it->month, it->year)); if (it->amount < 0) _grid->SetCellValue(curLine, DEBIT, wxString::Format(wxT("%.2lf"), -it->amount)); else _grid->SetCellValue(curLine, CREDIT, wxString::Format(wxT("%.2lf"), it->amount)); _grid->SetCellEditor(curLine, DEBIT, new wxGridCellFloatEditor(-1, 2)); _grid->SetCellEditor(curLine, CREDIT, new wxGridCellFloatEditor(-1, 2)); - categoryEditor = new wxGridCellChoiceEditor(user->GetCategoriesNumber()+1, _categories, false); - _grid->SetCellEditor(curLine, CATEGORY, categoryEditor); - _grid->SetCellValue(curLine, CATEGORY, user->GetCategoryName(it->category)); + _grid->SetCellValue(curLine, CATEGORY, _("Fixe")); + _grid->SetReadOnly(curLine, CATEGORY); accountEditor = new wxGridCellChoiceEditor(user->_accounts.size()+1, _accounts, false); _grid->SetCellEditor(curLine, ACCOUNT, accountEditor); _grid->SetCellValue(curLine, ACCOUNT, user->GetAccountName(it->account)); @@ -264,22 +296,24 @@ enum {DESCRIPTION, DATE, DEBIT, CREDIT, CATEGORY, ACCOUNT, VIEW, NUMBER_COLS}; _grid->AppendRows(); curLine++; SET_ROW_COLOR(curLine, OWN_YELLOW); - categoryEditor = new wxGridCellChoiceEditor(user->_preferences._categories.size()+1, _categories, false); - _grid->SetCellEditor(curLine, CATEGORY, categoryEditor); + _grid->SetCellValue(curLine, CATEGORY, _("Fixe")); + _grid->SetReadOnly(curLine, CATEGORY); + _grid->SetCellEditor(curLine, DATE, new CalendarEditor(it->day, it->month, it->year)); _grid->SetCellEditor(curLine, DEBIT, new wxGridCellFloatEditor(-1, 2)); _grid->SetCellEditor(curLine, CREDIT, new wxGridCellFloatEditor(-1, 2)); accountEditor = new wxGridCellChoiceEditor(user->_accounts.size()+1, _accounts, false); _grid->SetCellEditor(curLine, ACCOUNT, accountEditor); - _grid->_fixCosts = ++fixCosts; + _grid->_fixCosts = _fixCosts+1; for (; it != _curOperations->end(); it++) { - _grid->AppendRows(); curLine++; + _grid->AppendRows(); SET_ROW_COLOR(curLine, OWN_GREEN); _grid->SetCellValue(curLine, DESCRIPTION, it->description); _grid->SetCellValue(curLine, DATE, wxString::Format(wxT("%02d/%02d/%d"), it->day+1, it->month+1, it->year)); + _grid->SetCellEditor(curLine, DATE, new CalendarEditor(it->day, it->month, it->year)); if (it->amount < 0) _grid->SetCellValue(curLine, DEBIT, wxString::Format(wxT("%.2lf"), -it->amount)); else @@ -299,6 +333,7 @@ enum {DESCRIPTION, DATE, DEBIT, CREDIT, CATEGORY, ACCOUNT, VIEW, NUMBER_COLS}; SET_ROW_COLOR(curLine, OWN_GREEN); categoryEditor = new wxGridCellChoiceEditor(user->_preferences._categories.size()+1, _categories, false); _grid->SetCellEditor(curLine, CATEGORY, categoryEditor); + _grid->SetCellEditor(curLine, DATE, new CalendarEditor(it->day, it->month, it->year)); _grid->SetCellEditor(curLine, DEBIT, new wxGridCellFloatEditor(-1, 2)); _grid->SetCellEditor(curLine, CREDIT, new wxGridCellFloatEditor(-1, 2)); accountEditor = new wxGridCellChoiceEditor(user->_accounts.size()+1, _accounts, false); @@ -307,19 +342,55 @@ enum {DESCRIPTION, DATE, DEBIT, CREDIT, CATEGORY, ACCOUNT, VIEW, NUMBER_COLS}; _grid->AutoSizeColumn(CATEGORY, false); _grid->AutoSizeColumn(ACCOUNT, false); + InitAccountsGrid(user, month, year); + UpdateStats(); Fit(); SetMinSize(GetSize()); } +void AccountPanel::InitAccountsGrid(User* user, int month, int year) +{ + std::map::iterator it; + int curLine = 0; + Account account ; + double value; + int i, a; + DEFAULT_FONT(font); + + font.SetWeight(wxFONTWEIGHT_BOLD); + + for (i=0, it = user->_accounts.begin(); it != user->_accounts.end(); i++, it++, curLine++) + { + _accountsGrid->AppendRows(); + account = user->_accounts[it->first]; + + _accountsGrid->SetCellValue(curLine, ACCOUNT_NUMBER, account.number); + _accountsGrid->SetCellValue(curLine, ACCOUNT_NAME, account.name); + value = _kiss->GetAccountAmount(it->first, month, year); + _accountsGrid->SetCellValue(curLine, ACCOUNT_INIT, wxString::Format(wxT("%.2lf"), value)); + _accountsGrid->SetCellEditor(curLine, ACCOUNT_INIT, new wxGridCellFloatEditor(-1, 2)); + for (a=0; aSetReadOnly(curLine, a, a != ACCOUNT_INIT); + _accountsGrid->SetCellFont(curLine, ACCOUNT_CUR, font); + + _accountsIndexes[it->first] = i; + _accountsInitValues[it->first] = value; + + } +} + void AccountPanel::UpdateStats() { int i; User* user = _kiss->GetUser(); std::list::iterator it; - double curCredit, curDebit, totalCredit, totalDebit, remains; + double curCredit, curDebit, totalCredit, totalDebit, remains, value; wxDateTime curDate; + std::map curAccountAmount, finalAccountAmount; + std::map::iterator doubleIt; + std::map::iterator intIt; curDate.SetToCurrent(); @@ -328,20 +399,34 @@ void AccountPanel::UpdateStats() for (i=0; iGetCategoriesNumber()+1; i++) _categoriesValues[i] = 0.0; + for (doubleIt=_accountsInitValues.begin(); doubleIt!=_accountsInitValues.end(); doubleIt++) + { + curAccountAmount[doubleIt->first] = _accountsInitValues[doubleIt->first]; + finalAccountAmount[doubleIt->first] = _accountsInitValues[doubleIt->first]; + } + for (it=_curOperations->begin(); it!=_curOperations->end(); it++) { if (it->amount > 0) { if (curDate.GetDay() >= it->day && curDate.GetMonth() >= (int)it->month && curDate.GetYear() >= (int)it->year) - curCredit += it->amount; + { + curCredit += it->amount; + curAccountAmount[it->account] += it->amount; + } totalCredit += it->amount; + finalAccountAmount[it->account] += it->amount; } else { _categoriesValues[_categoriesIndexes[user->GetCategoryName(it->category)]] += -it->amount ; if (curDate.GetDay() >= it->day && curDate.GetMonth() >= (int)it->month && curDate.GetYear() >= (int)it->year) - curDebit += -it->amount; + { + curDebit += -it->amount; + curAccountAmount[it->account] += it->amount; + } totalDebit += -it->amount; + finalAccountAmount[it->account] += it->amount; } } @@ -356,6 +441,45 @@ void AccountPanel::UpdateStats() for(i=0; iGetCategoriesNumber()+1; i++) _statsGrid->SetCellValue(CATS_STATS+i, 1, wxString::Format(wxT("%.2lf"), _categoriesValues[i])); - + + for (intIt=_accountsIndexes.begin(); intIt!=_accountsIndexes.end(); intIt++) + { + i = _accountsIndexes[intIt->first]; + value = curAccountAmount[intIt->first]; + _accountsGrid->SetCellValue(i, ACCOUNT_CUR, wxString::Format(wxT("%.2lf"), value)); + _accountsGrid->SetCellTextColour(i, ACCOUNT_CUR, (value >= 0.0) ? wxColor(0x00, 0x00, 0x00) : wxColor(0xFF, 0x00, 0x00)); + value = finalAccountAmount[intIt->first]; + _accountsGrid->SetCellValue(i, ACCOUNT_FINAL, wxString::Format(wxT("%.2lf"), value)); + } + _pie->DatasetChanged(_dataset); } + +void AccountPanel::OnOperationModified(wxGridEvent& event) +{ + User* user = _kiss->GetUser(); + int row = event.GetRow()-1; + + // Modify a fix operation + if (row < _fixCosts) + { + std::cout << "Fix modified\n"; + } + // Add a fixCost + else if (row == _fixCosts) + { + std::cout << "Fix added\n"; + } + // Modify an operation + else if (row <= user->GetOperationsNumber(_curMonth, _curYear)) + { + row--; + std::cout << "Op modified\n"; + } + // Add an operation + else + { + row--; + std::cout << "Op added\n"; + } +} diff --git a/view/AccountPanel.h b/view/AccountPanel.h index 0e76a2e..9a63896 100644 --- a/view/AccountPanel.h +++ b/view/AccountPanel.h @@ -6,6 +6,7 @@ #include #include #include +#include "CalendarEditor.h" #define OWN_CYAN wxColour(0x99, 0xCC, 0xFF) #define OWN_YELLOW wxColour(0xFF, 0xFF, 0x99) @@ -15,9 +16,11 @@ #define DEFAULT_FONT_SIZE 12 #define DEFAULT_FONT(font_name) wxFont font_name(DEFAULT_FONT_SIZE, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, DEFAULT_FONT_NAME); -enum {DESCRIPTION, DATE, DEBIT, CREDIT, CATEGORY, ACCOUNT, VIEW, NUMBER_COLS}; +enum {DESCRIPTION, DATE, DEBIT, CREDIT, CATEGORY, ACCOUNT, VIEW, NUMBER_COLS_OPS}; +enum {ACCOUNT_NUMBER, ACCOUNT_NAME, ACCOUNT_INIT, ACCOUNT_CUR, ACCOUNT_FINAL, NUMBER_COLS_ACCOUNTS}; enum {CUR_CREDIT, CUR_DEBIT, TOTAL_CREDIT, TOTAL_DEBIT, REMAINS, STATS_ROW, CATS_STATS}; +enum {CALENDAR_TREE_ID=10, OPS_GRID_ID, ACCOUNTS_GRID_ID}; #include #include "wxUI.h" #include @@ -36,21 +39,29 @@ public: void LoadYear(int year); void ShowMonth(int year, int month); + void OnOperationModified(wxGridEvent& event); + private: KissCount* _kiss; wxUI* _wxUI; wxTreeCtrl _tree; GridAccount* _grid; - wxGrid *_statsGrid; + wxGrid *_statsGrid, *_accountsGrid; PiePlot* _pie; double *_categoriesValues; - std::map _categoriesIndexes; + std::map _categoriesIndexes, _accountsIndexes; std::list* _curOperations; int _curMonth, _curYear; wxString* _categories, *_accounts; + std::map _accountsInitValues; CategorySimpleDataset* _dataset; + int _fixCosts; + void InitStatsGrid(User* user); + void InitAccountsGrid(User* user, int month, int year); void UpdateStats(); + + DECLARE_EVENT_TABLE(); }; #endif