diff --git a/controller/KissCount.cpp b/controller/KissCount.cpp index a806522..3498423 100644 --- a/controller/KissCount.cpp +++ b/controller/KissCount.cpp @@ -1,6 +1,6 @@ #include "KissCount.h" -KissCount::KissCount() +KissCount::KissCount() : _user(NULL) { _wxUI = new wxUI(this, _("KissCount"), wxPoint(50, 50), wxSize(1024, 768)); @@ -26,6 +26,7 @@ KissCount::~KissCount() { delete _db; delete _wxUI; + if (_user) delete _user; } std::list KissCount::GetUsers() @@ -40,5 +41,24 @@ bool KissCount::IsValidUser(wxString user, wxString password) void KissCount::LoadUser(wxString user) { - + if (_user) delete _user; + _user = _db->LoadUser(user) ; + _wxUI->LoadUser(); +} + +void KissCount::LoadYear(int year, bool force=false) +{ + if (!force && _user->_operations[year] != NULL) return; + + if (_user->_operations[year] != NULL) + { + delete _user->_operations[year]; + } + + _db->LoadYear(_user, year); +} + +User* KissCount::GetUser() +{ + return _user; } diff --git a/controller/KissCount.h b/controller/KissCount.h index 74166eb..549e9c6 100644 --- a/controller/KissCount.h +++ b/controller/KissCount.h @@ -20,10 +20,13 @@ class KissCount std::list GetUsers(); bool IsValidUser(wxString user, wxString password); void LoadUser(wxString user); + void LoadYear(int year, bool force=false); + User* GetUser(); private: wxUI* _wxUI; Database* _db; + User* _user; }; #endif diff --git a/init.sql b/init.sql index ac65a4d..2a98fd7 100644 --- a/init.sql +++ b/init.sql @@ -1,5 +1,6 @@ CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR(255), password VARCHAR(255)); CREATE TABLE account(id INTEGER PRIMARY KEY, user REFERENCES user(id), name VARCHAR(255), number VARCHAR(255), amount INTEGER, shared CHAR(1), default_account CHAR(1)); +CREATE TABLE account_amount(id INTEGER PRIMARY KEY, account REFERENCES account(id), year INTEGER, month INTEGER, amount INTEGER); CREATE TABLE operation(id INTEGER PRIMARY KEY, user REFERENCES user(id), account REFERENCES account(id), year INTEGER, month INTEGER, day INTEGER, amount INTEGER, description VARCHAR(255), category VARCHAR(255), fix_cost CHAR(1)); CREATE TABLE preference(id INTEGER PRIMARY KEY, user REFERENCES user(id), type VARCHAR(255), name VARCHAR(255), value VARCHAR(255)); CREATE TABLE default_preference(id INTEGER PRIMARY KEY, type VARCHAR(255), name VARCHAR(255), value VARCHAR(255)); @@ -8,5 +9,8 @@ INSERT INTO default_preference ("type", "value") VALUES ("category", "Courses"); INSERT INTO default_preference ("type", "value") VALUES ("category", "Loisirs"); INSERT INTO default_preference ("type", "value") VALUES ("category", "Frais de fonctionnement"); INSERT INTO default_preference ("type", "value") VALUES ("category", "Exceptionnel"); +-- No password INSERT INTO user ("id", "name", "password") VALUES ("0", "Greg", "da39a3ee5e6b4b0d3255bfef95601890afd80709"); INSERT INTO account ("id", "user", "name", "number", "amount", "shared", "default_account") VALUES ("0", "0", "Compte courant", "000", "1234", "0", "1"); +INSERT INTO operation ("id", "user", "account", "year", "month", "day", "amount", "description", "category", "fix_cost") VALUES ("0", "0", "0", "2010", "0", "0", "1234", "Opé 1", "Cat 1", "1"); +INSERT INTO operation ("id", "user", "account", "year", "month", "day", "amount", "description", "category", "fix_cost") VALUES ("1", "0", "0", "2010", "0", "1", "5678", "Opé 2", "Cat 2", "0"); diff --git a/model/Account.h b/model/Account.h index d486f83..149fada 100644 --- a/model/Account.h +++ b/model/Account.h @@ -5,17 +5,6 @@ #include #include -struct operation { - wxString id; - unsigned int day; - unsigned int month; - unsigned int year; - int amount; - wxString description; - wxString category; - bool fix_cost; -} ; - class Account { public: diff --git a/model/Database.cpp b/model/Database.cpp index 6fa7881..34860dc 100644 --- a/model/Database.cpp +++ b/model/Database.cpp @@ -1,15 +1,17 @@ #include "Database.h" + // if (!_db.CheckSyntax(req)) + // { + // wxString s = req; + // std::cout << s.mb_str() << " is invalid !\n" ; + // code_if_syntax_fail; + // return return_value; + // } + #define EXECUTE_SQL_QUERY_WITH_CODE(req, res, return_value, code_if_fail, code_if_syntax_fail) \ do{\ try\ {\ - if (!_db.CheckSyntax(req)) \ - {\ - std::cout << req << " is invalid !\n" ; \ - code_if_syntax_fail; \ - return return_value;\ - } \ res = _db.ExecuteQuery(req);\ }\ catch (wxSQLite3Exception e)\ @@ -61,7 +63,7 @@ void Database::CreateDatabase() getline(init_script, line); wxline = wxString(line.c_str(), wxConvUTF8); wxline.Trim(false); - if (!wxline.Length() || wxline.StartsWith(_("#"))) continue; + if (!wxline.Length() || wxline.StartsWith(_("--"))) continue; if (!_db.CheckSyntax(wxline)) { std::cout << line << " is invalid !\n" ; @@ -113,11 +115,9 @@ bool Database::IsValidUser(wxString user, wxString password) blk_SHA1_Final(sha, &sha_ctx); for(int i=0; i<20; i++) - wxSHA += wxString::Format(wxT("%02F"), (int)sha[i]); + wxSHA += wxString::Format(wxT("%02x"), (int)sha[i]); req = _("SELECT name FROM user WHERE name='") + user + _("' AND password='") + wxSHA + _("'"); - std::cout << req.mb_str() << "\n"; - EXECUTE_SQL_QUERY(req, set, false); res = set.NextRow() ; @@ -149,7 +149,7 @@ User* Database::LoadUser(wxString name) set.Finalize(); - req = _("SELECT * FROM account WHERE user='") + user->_id + _("' ORDER BY default DESC, name ASC"); + req = _("SELECT * FROM account WHERE user='") + user->_id + _("' ORDER BY default_account DESC, name ASC"); EXECUTE_SQL_QUERY_WITH_CODE(req, set, NULL, {delete user;}, {delete user;}); @@ -169,13 +169,13 @@ User* Database::LoadUser(wxString name) if (!user->_accounts.empty()) { it = user->_accounts.begin(); - req = _("SELECT DISTINCT year FROM operation WHERE account IN(") + (*it)->_id; + req = _("SELECT DISTINCT year FROM operation WHERE account IN('") + (*it)->_id; it++; for (;it != user->_accounts.end(); it++) { - req += _(", ") + (*it)->_id ; + req += _("', '") + (*it)->_id ; } - req += _(") ORDER BY year ASC"); + req += _("') ORDER BY year ASC"); EXECUTE_SQL_QUERY_WITH_CODE(req, set, NULL, {delete user;}, {delete user;}); @@ -188,3 +188,40 @@ User* Database::LoadUser(wxString name) return user; } + +void Database::LoadYear(User* user, int year) +{ + wxSQLite3ResultSet set; + wxString req; + std::list::iterator it; + + if (user->_operations[year] == NULL) + user->_operations[year] = new std::map >(); + + it = user->_accounts.begin(); + req = _("SELECT * FROM operation WHERE account IN('") + (*it)->_id; + it++; + for (;it != user->_accounts.end(); it++) + { + req += _("', '") + (*it)->_id ; + } + req += _("') ORDER BY fix_cost DESC, year,month,day ASC"); + + EXECUTE_SQL_QUERY(req, set, ); + + while (set.NextRow()) + { + operation op; + op.id = set.GetAsString(_("id")); + op.day = set.GetInt(_("day")); + op.month = set.GetInt(_("month")); + op.year = set.GetInt(_("year")); + op.amount = set.GetInt(_("amount")); + op.description = set.GetAsString(_("description")); + op.category = set.GetAsString(_("category")); + op.fix_cost = set.GetBool(_("fix_cost")); + (*user->_operations[op.year])[op.month].push_back(op); + } + + set.Finalize(); +} diff --git a/model/Database.h b/model/Database.h index 9a0445c..8bc7ef5 100644 --- a/model/Database.h +++ b/model/Database.h @@ -22,6 +22,7 @@ class Database bool IsValidUser(wxString user, wxString password); User* LoadUser(wxString name); + void LoadYear(User* user, int year); private: wxSQLite3Database _db; diff --git a/model/User.h b/model/User.h index 59e4ab2..c51d14e 100644 --- a/model/User.h +++ b/model/User.h @@ -6,6 +6,17 @@ #include "Account.h" #include "Preferences.h" +struct operation { + wxString id; + unsigned int day; + unsigned int month; + unsigned int year; + int amount; + wxString description; + wxString category; + bool fix_cost; +} ; + class User { public: diff --git a/view/AccountPanel.cpp b/view/AccountPanel.cpp index 89c73f0..39b21e0 100644 --- a/view/AccountPanel.cpp +++ b/view/AccountPanel.cpp @@ -5,10 +5,14 @@ AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*parent)), { wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); wxChartPanel* chart ; + SetSizer(hbox); _pie = new PiePlot(); _grid.CreateGrid(10, 7); + _grid.SetColLabelSize(0); + _grid.SetRowLabelSize(0); + //_grid.EnableGridLines(false); chart = new wxChartPanel(this); chart->SetChart(new Chart(_pie, _("Cost repartition"))); @@ -16,6 +20,93 @@ AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*parent)), hbox->Add(&_grid, 0); hbox->Add(chart, 0); + ChangeUser(); + Fit(); SetMinSize(GetSize()); } + +void AccountPanel::ChangeUser() +{ + User* user = _kiss->GetUser(); + int curYear; + std::map >* >::iterator it; + wxDateTime curDate; + + curDate.SetToCurrent(); + for(it = user->_operations.begin(); it != user->_operations.end(); it++) + { + if ((int)it->first <= curDate.GetYear()) + curYear = it->first; + _tree.AddRoot(wxString::Format(wxT("%d"), it->first)); + } + + LoadYear(curYear); +} + +void AccountPanel::LoadYear(int year) +{ + User* user = _kiss->GetUser(); + int curMonth = -1; + std::map >::iterator it; + wxDateTime curDate; + wxTreeItemId parentNode, curMonthNode; + + if (user->_operations[year] != NULL) + { + ShowMonth(year, 0); + return; + } + + _kiss->LoadYear(year); + + curDate.SetToCurrent(); + parentNode = _tree.GetSelection(); + + for (it = user->_operations[year]->begin(); it != user->_operations[year]->end(); it++) + { + if (year == curDate.GetYear() && (int)it->first <= curDate.GetMonth()) + { + curMonth = it->first; + curMonthNode = _tree.AppendItem(parentNode, months[it->first]); + } + else if(curMonth == -1) + { + curMonthNode = _tree.AppendItem(parentNode, months[it->first]); + curMonth++; + } + else + _tree.AppendItem(parentNode, months[it->first]); + } + + _tree.Expand(parentNode); + _tree.SelectItem(curMonthNode, true); + + ShowMonth(year, curMonth); +} + +void AccountPanel::ShowMonth(int year, int month) +{ + std::list operations; + User* user = _kiss->GetUser(); + + _wxUI->SetTitle(user->_name + _(" - ") + months[month]); + + // Operations are ordered + operations = (*user->_operations[year])[month]; + + _grid.CreateGrid(10, 7); + // Creating headers + _grid.SetColSize (0, _grid.GetColSize(0)*4); + // SetCellBackgroundColour (int row, int col, const wxColour &colour); + // SetCellFont (int row, int col, const wxFont &font); + // SetCellValue (int row, int col, const wxString &s); + // GetColSize (int col) const ; + // SetColSize (int col, int width); + // AppendRows (int numRows=1, bool updateLabels=true); + // InsertRows (int pos=0, int numRows=1, bool updateLabels=true); + // SetReadOnly(row, col, bool) + Fit(); + SetMinSize(GetSize()); +} + diff --git a/view/AccountPanel.h b/view/AccountPanel.h index aa5e2f0..1475b40 100644 --- a/view/AccountPanel.h +++ b/view/AccountPanel.h @@ -9,6 +9,8 @@ #include #include "wxUI.h" +#include +#include "GridAccount.h" class wxUI; class KissCount; @@ -16,14 +18,16 @@ class KissCount; class AccountPanel: public wxPanel { public: - AccountPanel(KissCount* kiss, wxUI *parent); + void ChangeUser(); + void LoadYear(int year); + void ShowMonth(int year, int month); private: KissCount* _kiss; wxUI* _wxUI; wxTreeCtrl _tree; - wxGrid _grid; + GridAccount _grid; PiePlot* _pie; }; diff --git a/view/UsersDialog.cpp b/view/UsersDialog.cpp index fa78b7a..5e59c4e 100644 --- a/view/UsersDialog.cpp +++ b/view/UsersDialog.cpp @@ -47,6 +47,7 @@ UsersDialog::UsersDialog(KissCount* kiss, wxUI *parent) : wxDialog(&(*parent), - Center(); SetSizer(vbox); + _users->SetFocus(); Layout(); } diff --git a/view/wxUI.cpp b/view/wxUI.cpp index cf005b9..d269af0 100644 --- a/view/wxUI.cpp +++ b/view/wxUI.cpp @@ -5,6 +5,8 @@ BEGIN_EVENT_TABLE(wxUI, wxFrame) EVT_MENU(ID_About, wxUI::OnAbout) END_EVENT_TABLE() +wxString months[12] = {_("january"), _("february"), _("march"), _("april"), _("may"), _("june"), _("july"), _("august"), _("september"), _("october"), _("november"), _("december")} ; + wxUI::wxUI(KissCount* kiss, const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, -1, title, pos, size), _kiss(kiss) { diff --git a/view/wxUI.h b/view/wxUI.h index 853d0cd..8fa2cd1 100644 --- a/view/wxUI.h +++ b/view/wxUI.h @@ -10,6 +10,8 @@ class KissCount; class AccountPanel; +extern wxString months[12]; + class wxUI: public wxFrame { public: @@ -22,6 +24,7 @@ public: void ChangeUser(); void LoadUser(); + DECLARE_EVENT_TABLE(); private: