diff --git a/controller/KissCount.cpp b/controller/KissCount.cpp index d018ed6..cb7e8f6 100644 --- a/controller/KissCount.cpp +++ b/controller/KissCount.cpp @@ -68,3 +68,18 @@ double KissCount::GetAccountAmount(wxString id, int month, int year) { return _db->GetAccountAmount(id, month, year); } + +void KissCount::UpdateOperation(struct operation op) +{ + _db->UpdateOperation(op); +} + +void KissCount::AddOperation(struct operation op) +{ + _db->AddOperation(_user, op); +} + +void KissCount::DeleteOperation(struct operation op) +{ + _db->DeleteOperation(op); +} diff --git a/controller/KissCount.h b/controller/KissCount.h index 66b8041..1442f78 100644 --- a/controller/KissCount.h +++ b/controller/KissCount.h @@ -21,6 +21,9 @@ class KissCount void LoadYear(int year, bool force=false); User* GetUser(); double GetAccountAmount(wxString id, int month, int year); + void UpdateOperation(struct operation op); + void AddOperation(struct operation op); + void DeleteOperation(struct operation op); private: wxUI* _wxUI; diff --git a/model/Database.cpp b/model/Database.cpp index 8baddbc..cad1759 100644 --- a/model/Database.cpp +++ b/model/Database.cpp @@ -8,6 +8,20 @@ // return return_value; // } +#define EXECUTE_SQL_UPDATE_WITH_CODE(req, return_value, code_if_fail, code_if_syntax_fail) \ + do{\ + try\ + {\ + _db.ExecuteUpdate(req);\ + }\ + catch (wxSQLite3Exception e)\ + {\ + std::cerr << e.GetMessage().mb_str() << "\n" ;\ + code_if_fail; \ + return return_value;\ + }\ +} while(0); + #define EXECUTE_SQL_QUERY_WITH_CODE(req, res, return_value, code_if_fail, code_if_syntax_fail) \ do{\ try\ @@ -24,6 +38,8 @@ #define EXECUTE_SQL_QUERY(req, res, return_value) EXECUTE_SQL_QUERY_WITH_CODE(req, res, return_value, {}, {}) +#define EXECUTE_SQL_UPDATE(req, return_value) EXECUTE_SQL_UPDATE_WITH_CODE(req, return_value, {}, {}) + Database::Database() { std::ifstream bdd_file; @@ -202,7 +218,7 @@ void Database::LoadYear(User* user, int year) std::map::iterator it; if (user->_operations[year] == NULL) - user->_operations[year] = new std::map >(); + user->_operations[year] = new std::map >(); it = user->_accounts.begin(); req = _("SELECT * FROM operation WHERE account IN('") + it->first; @@ -255,3 +271,50 @@ double Database::GetAccountAmount(wxString id, int month, int year) return res; } + +void Database::UpdateOperation(struct operation op) +{ + wxString req; + req = _("UPDATE operation SET ") ; + req += _("account='") + op.account + _("'"); + req += _(", year='") + wxString::Format(_("%d"), op.year) + _("'"); + req += _(", month='") + wxString::Format(_("%d"), op.month) + _("'"); + req += _(", day='") + wxString::Format(_("%d"), op.day) + _("'"); + req += _(", amount='") + wxString::Format(_("%.2lf"), op.amount) + _("'"); + req += _(", description=\"") + op.description + _("\""); + req += _(", category='") + op.category + _("'"); + req += _(" WHERE id='") + op.id + _("'"); + + //std::cout << req.mb_str() << "\n"; + EXECUTE_SQL_UPDATE(req, ); + +} + +void Database::AddOperation(User* user, struct operation op) +{ + wxString req; + req = _("INSERT INTO operation ('user', 'account', 'year', 'month', 'day', 'amount', 'description', 'category', 'fix_cost') VALUES ('") ; + req += user->_id + _("'"); + req += _(", '") + op.account + _("'"); + req += _(", '") + wxString::Format(_("%d"), op.year) + _("'"); + req += _(", '") + wxString::Format(_("%d"), op.month) + _("'"); + req += _(", '") + wxString::Format(_("%d"), op.day) + _("'"); + req += _(", '") + wxString::Format(_("%.2lf"), op.amount) + _("'"); + req += _(", \"") + op.description + _("\""); + req += _(", '") + op.category + _("'"); + if (op.fix_cost) + req += _(", '1'") ; + else + req += _(", '0'") ; + req += _(")"); + + EXECUTE_SQL_UPDATE(req, ); +} + +void Database::DeleteOperation(struct operation op) +{ + wxString req; + req = _("DELETE FROM operation WHERE id='") + op.id + _("'"); + + EXECUTE_SQL_UPDATE(req, ); +} diff --git a/model/Database.h b/model/Database.h index 17a7555..2b8888b 100644 --- a/model/Database.h +++ b/model/Database.h @@ -24,6 +24,11 @@ class Database User* LoadUser(wxString name); void LoadYear(User* user, int year); double GetAccountAmount(wxString id, int month, int year); + + void UpdateOperation(struct operation op); + void AddOperation(User* user, struct operation op); + void DeleteOperation(struct operation op); + private: wxSQLite3Database _db; diff --git a/model/User.cpp b/model/User.cpp index f7844f7..a1d1c78 100644 --- a/model/User.cpp +++ b/model/User.cpp @@ -3,7 +3,7 @@ User::~User() { - std::map >* >::iterator it; + std::map >* >::iterator it; for (it = _operations.begin(); it != _operations.end(); it++) { @@ -21,6 +21,16 @@ wxString User::GetCategoryName(wxString catId) return _preferences._categories[catId]; } +wxString User::GetCategoryId(wxString catName) +{ + std::map::iterator it; + for (it=_preferences._categories.begin(); it !=_preferences._categories.end(); it++) + if (it->second == catName) + return it->first; + + return _("0") ; +} + wxString User::GetAccountName(wxString accountId) { if (_accounts.find(accountId) == _accounts.end()) @@ -28,6 +38,16 @@ wxString User::GetAccountName(wxString accountId) return _accounts[accountId].name; } +wxString User::GetAccountId(wxString accountName) +{ + std::map::iterator it; + for (it=_preferences._categories.begin(); it !=_preferences._categories.end(); it++) + if (it->second == accountName) + return it->first; + + return _("0") ; +} + int User::GetCategoriesNumber() { return _preferences._categories.size(); diff --git a/model/User.h b/model/User.h index b427a73..f38a7a6 100644 --- a/model/User.h +++ b/model/User.h @@ -1,7 +1,7 @@ #ifndef USER_H #define USER_H -#include +#include #include #include "Preferences.h" @@ -35,11 +35,13 @@ public: wxString _name; wxString _password; std::map _accounts; - std::map >* > _operations; + std::map >* > _operations; Preferences _preferences; wxString GetCategoryName(wxString catId); + wxString GetCategoryId(wxString catName); wxString GetAccountName(wxString accountId); + wxString GetAccountId(wxString accountName); int GetCategoriesNumber(); int GetAccountsNumber(); int GetOperationsNumber(int month, int year); diff --git a/view/AccountPanel.cpp b/view/AccountPanel.cpp index 8dd2d8f..216c199 100644 --- a/view/AccountPanel.cpp +++ b/view/AccountPanel.cpp @@ -153,7 +153,7 @@ void AccountPanel::ChangeUser() { User* user = _kiss->GetUser(); int curYear = -1; - std::map >* >::iterator it; + std::map >* >::iterator it; wxDateTime curDate; curDate.SetToCurrent(); @@ -172,7 +172,7 @@ void AccountPanel::LoadYear(int year) { User* user = _kiss->GetUser(); int curMonth = -1; - std::map >::iterator it; + std::map >::iterator it; wxDateTime curDate; wxTreeItemId parentNode, curMonthNode; @@ -217,8 +217,8 @@ void AccountPanel::LoadYear(int year) void AccountPanel::ShowMonth(int year, int month) { - std::list operations; - std::list::iterator it; + std::vector operations; + std::vector::iterator it; _fixCosts = 0; int curLine = 0; User* user = _kiss->GetUser(); @@ -385,7 +385,7 @@ void AccountPanel::UpdateStats() { int i; User* user = _kiss->GetUser(); - std::list::iterator it; + std::vector::iterator it; double curCredit, curDebit, totalCredit, totalDebit, remains, value; wxDateTime curDate; std::map curAccountAmount, finalAccountAmount; @@ -459,27 +459,108 @@ void AccountPanel::OnOperationModified(wxGridEvent& event) { User* user = _kiss->GetUser(); int row = event.GetRow()-1; + struct operation new_op, cur_op; + int op_complete = 5; + wxString value ; + wxDateTime date; + bool need_insertion = false; + + if (event.GetCol() == DEBIT) + _grid->SetCellValue(event.GetRow(), CREDIT, _("")); + else if (event.GetCol() == CREDIT) + _grid->SetCellValue(event.GetRow(), DEBIT, _("")); + + value = _grid->GetCellValue(event.GetRow(), DESCRIPTION); + if (value != _("")) + { + new_op.description = value; + op_complete--; + } + + value = _grid->GetCellValue(event.GetRow(), DATE); + if (value != _("")) + { + date.ParseFormat(value, _("%d/%m/%Y")); + new_op.day = date.GetDay()-1; + new_op.month = date.GetMonth(); + new_op.year = date.GetYear(); + op_complete--; + } + + value = _grid->GetCellValue(event.GetRow(), DEBIT); + if (value != _("")) + { + value.ToDouble(&new_op.amount); + new_op.amount *= -1.0; + op_complete--; + } + + value = _grid->GetCellValue(event.GetRow(), CREDIT); + if (value != _("")) + { + value.ToDouble(&new_op.amount); + op_complete--; + } + + value = _grid->GetCellValue(event.GetRow(), CATEGORY); + if (value != _("")) + { + new_op.category = user->GetCategoryId(value); + op_complete--; + } + + value = _grid->GetCellValue(event.GetRow(), ACCOUNT); + if (value != _("")) + { + new_op.account = user->GetAccountId(value); + op_complete--; + } // Modify a fix operation if (row < _fixCosts) { - std::cout << "Fix modified\n"; + cur_op = (*_curOperations)[row] ; + new_op.id = cur_op.id; + if (cur_op.day != new_op.day) + { + need_insertion = true; + _grid->DeleteRows(row, 1); + _curOperations->erase(_curOperations->begin()+row); + } + else + (*_curOperations)[row] = new_op; + _kiss->UpdateOperation(new_op); } // Add a fixCost else if (row == _fixCosts) { - std::cout << "Fix added\n"; + if (op_complete) return ; + need_insertion = true; } // Modify an operation else if (row <= user->GetOperationsNumber(_curMonth, _curYear)) { - row--; - std::cout << "Op modified\n"; + row--; + cur_op = (*_curOperations)[row] ; + new_op.id = cur_op.id; + if (cur_op.day != new_op.day) + { + need_insertion = true; + _grid->DeleteRows(row+1, 1); + _curOperations->erase(_curOperations->begin()+row); + } + else + (*_curOperations)[row] = new_op; + _kiss->UpdateOperation(new_op); } // Add an operation else { row--; - std::cout << "Op added\n"; + if (op_complete) return ; + need_insertion = true; + } + + UpdateStats(); } diff --git a/view/AccountPanel.h b/view/AccountPanel.h index 9a63896..05490b2 100644 --- a/view/AccountPanel.h +++ b/view/AccountPanel.h @@ -50,7 +50,7 @@ private: PiePlot* _pie; double *_categoriesValues; std::map _categoriesIndexes, _accountsIndexes; - std::list* _curOperations; + std::vector* _curOperations; int _curMonth, _curYear; wxString* _categories, *_accounts; std::map _accountsInitValues;