Add shared account management

This commit is contained in:
2010-10-24 16:04:56 +02:00
parent d800f23029
commit 28c92d3b28
17 changed files with 655 additions and 237 deletions

View File

@@ -211,7 +211,7 @@ std::list<wxString> Database::GetUsers()
while (set.NextRow())
{
res.push_front(set.GetAsString(0));
res.push_back(set.GetAsString(0));
}
set.Finalize();
@@ -251,7 +251,7 @@ User* Database::LoadUser(const wxString& name)
if (!set.NextRow())
return NULL;
user = new User();
user = new User(this);
user->_id = set.GetAsString(wxT("id"));
user->_name = set.GetAsString(wxT("name"));
@@ -277,7 +277,7 @@ User* Database::LoadUser(const wxString& name)
}
set.Finalize();
req = wxT("SELECT * FROM account WHERE id IN (SELECT id FROM shared_account WHERE user='") + user->_id + wxT("') ORDER BY name ASC");
req = wxT("SELECT * FROM account WHERE id IN (SELECT account FROM shared_account WHERE user='") + user->_id + wxT("') ORDER BY name ASC");
EXECUTE_SQL_QUERY_WITH_CODE(req, set, NULL, {delete user;}, {delete user;});
@@ -621,7 +621,103 @@ void Database::DeleteOperations(User* user, int month, int year)
req += wxT(" AND month='") + wxString::Format(wxT("%d"), month) + wxT("'");
EXECUTE_SQL_UPDATE(req, );
}
bool Database::LoadOperation(User* user, const wxString& id)
{
wxSQLite3ResultSet set;
wxString req;
bool ret = false;
std::vector<Operation>::iterator it;
req = wxT("SELECT * FROM operation WHERE id='") + id + wxT("'");
EXECUTE_SQL_QUERY(req, set, false);
if (set.NextRow())
{
Operation op;
op.id = set.GetAsString(wxT("id"));
op.parent = set.GetAsString(wxT("parent"));
op.account = set.GetAsString(wxT("account"));
op.day = set.GetInt(wxT("day"));
op.month = set.GetInt(wxT("month"));
op.year = set.GetInt(wxT("year"));
op.amount = set.GetDouble(wxT("amount"));
op.description = set.GetAsString(wxT("description"));
op.category = set.GetAsString(wxT("category"));
op.fix_cost = set.GetBool(wxT("fix_cost"));
op.checked = set.GetBool(wxT("checked"));
op.transfert = set.GetAsString(wxT("transfert"));
op.formula = set.GetAsString(wxT("formula"));
op.meta = set.GetBool(wxT("meta"));
for (it = (*user->_operations[op.year])[op.month].begin();
it != (*user->_operations[op.year])[op.month].end();
it++)
{
if (!op.fix_cost && it->fix_cost) continue;
if (op.fix_cost && !it->fix_cost)
{
it--;
break;
}
if (it->day > op.day)
{
it--;
break;
}
}
if (it == (*user->_operations[op.year])[op.month].end())
(*user->_operations[op.year])[op.month].push_back(op);
else
(*user->_operations[op.year])[op.month].insert(it, op);
// if (op.fix_cost)
// else
// (*user->_operations[op.year])[op.month].push_back(op);
ret = true;
}
set.Finalize();
return ret;
}
// We may not have access to all operations if we have a shared account
double Database::MetaAmount(const wxString& id)
{
wxSQLite3ResultSet set;
wxString req;
double res = 0.0;
req = wxT("SELECT SUM(amount) as amount FROM operation WHERE parent='") + id + wxT("'");
EXECUTE_SQL_QUERY(req, set, false);
if (set.NextRow())
res = set.GetDouble(wxT("amount"));
set.Finalize();
return res;
}
// Idem
double Database::MetaPositiveAmount(const wxString& id)
{
wxSQLite3ResultSet set;
wxString req;
double res = 0.0;
req = wxT("SELECT SUM(amount) as amount FROM operation WHERE amount > 0 AND parent='") + id + wxT("'");
EXECUTE_SQL_QUERY(req, set, false);
if (set.NextRow())
res = set.GetDouble(wxT("amount"));
set.Finalize();
return res;
}
void Database::SetAccountAmount(int month, int year, const wxString& accountId, double amount)
@@ -697,7 +793,7 @@ void Database::UpdateAccount(Account& ac)
if (!ac.shared && ac.is_owner)
{
req = wxT("DELETE FROM shared_account WHERE id='") + ac.id + wxT("'");
req = wxT("DELETE FROM shared_account WHERE account='") + ac.id + wxT("'");
EXECUTE_SQL_UPDATE(req, );
}
@@ -706,45 +802,66 @@ void Database::UpdateAccount(Account& ac)
void Database::DeleteAccount(User* user, Account& ac)
{
wxString req;
wxSQLite3ResultSet set;
if (ac.is_owner)
{
if (ac.shared)
{
req = wxT("DELETE FROM shared_account WHERE id='") + ac.id + wxT("'");
req = wxT("DELETE FROM shared_account WHERE account='") + ac.id + wxT("'");
EXECUTE_SQL_UPDATE(req, );
}
req = wxT("DELETE FROM account WHERE id='") + ac.id + wxT("'");
EXECUTE_SQL_UPDATE(req, );
}
else
{
req = wxT("DELETE FROM shared_account WHERE user='") + user->_id + wxT("'");
req = wxT("DELETE FROM account_amount WHERE account='") + ac.id + wxT("'");
EXECUTE_SQL_UPDATE(req, );
req = wxT("SELECT COUNT(user) AS cnt FROM shared_account WHERE id='") + ac.id + wxT("'");
EXECUTE_SQL_QUERY(req, set, );
if (!set.GetInt(wxT("cnt")))
{
ac.shared = false;
UpdateAccount(ac);
}
}
else
RemoveSharedAccount(ac, user->_id);
}
void Database::AddSharedAccount(Account& ac, const wxString& granted)
{
wxString req;
wxSQLite3ResultSet set;
req = wxT("INSERT INTO shared_account ('id', 'user') VALUES ('") + ac.id + wxT("', '") + granted + wxT("'");
req = wxT("SELECT id FROM user WHERE name='") + granted + wxT("'");
EXECUTE_SQL_QUERY(req, set, );
req = wxT("INSERT INTO shared_account ('account', 'user') VALUES ('") + ac.id + wxT("', '") + set.GetAsString(wxT("id")) + wxT("')");
EXECUTE_SQL_UPDATE(req, );
if (!ac.shared)
{
ac.shared = true;
UpdateAccount(ac);
}
}
void Database::RemoveSharedAccount(Account& ac, const wxString& granted)
{
wxString req;
wxSQLite3ResultSet set;
req = wxT("DELETE FROM shared_account WHERE user='") + granted + wxT("' AND account='") + ac.id + wxT("'");
EXECUTE_SQL_UPDATE(req, );
req = wxT("SELECT COUNT(user) AS cnt FROM shared_account WHERE account='") + ac.id + wxT("'");
EXECUTE_SQL_QUERY(req, set, );
if (!set.GetInt(wxT("cnt")))
{
ac.shared = false;
UpdateAccount(ac);
}
}
wxString Database::AddCategory(User* user, Category& category)
@@ -817,6 +934,35 @@ void Database::DeleteCategory(User* user, Category& category)
EXECUTE_SQL_UPDATE(req, );
}
bool Database::LoadCategory(const wxString& id, const wxString& name, Category& category)
{
wxSQLite3ResultSet set;
wxString req;
bool ret = false ;
if (id.Length())
req = wxT("SELECT * FROM category WHERE id='") + id + wxT("'");
else
req = wxT("SELECT * FROM category WHERE name='") + name + wxT("'");
EXECUTE_SQL_QUERY(req, set, false);
if (set.NextRow())
{
category.id = set.GetAsString(wxT("id"));
category.parent = set.GetAsString(wxT("parent"));
category.name = set.GetAsString(wxT("name"));
category.backcolor = wxColour(set.GetAsString(wxT("backcolor")));
category.forecolor = wxColour(set.GetAsString(wxT("forecolor")));
category.font = set.GetAsString(wxT("font"));
ret = true;
}
set.Finalize();
return ret;
}
std::map<int, std::vector<int> > Database::GetAllOperations(User* user)
{
wxString req, req2, reqUnion;
@@ -1016,33 +1162,26 @@ void Database::KillMe(User* user)
if (!user->_accounts.empty())
{
for (it = user->_accounts.begin(); it != user->_accounts.end(); it++)
DeleteAccount(user, *it);
it = user->_accounts.begin();
req = wxT("DELETE FROM account_amount WHERE account IN('") + it->id;
if (it->is_owner)
req = wxT("DELETE FROM operation WHERE account IN('") + it->id;
else
req = wxT("DELETE FROM operation WHERE account IN('-1");
it++;
for (;it != user->_accounts.end(); it++)
{
req += wxT("', '") + it->id ;
if (it->is_owner)
req += wxT("', '") + it->id ;
}
req += wxT("')");
EXECUTE_SQL_UPDATE(req, );
it = user->_accounts.begin();
req = wxT("DELETE FROM operation WHERE account IN('") + it->id;
it++;
for (;it != user->_accounts.end(); it++)
{
req += wxT("', '") + it->id ;
}
req += wxT("')");
req += wxT(" OR user='") + user->_id + wxT("'");
req += wxT(" OR (user='") + user->_id + wxT("' AND account='')");
EXECUTE_SQL_UPDATE(req, );
}
req = wxT("DELETE FROM account WHERE user='") + user->_id + wxT("'");
EXECUTE_SQL_UPDATE(req, );
req = wxT("DELETE FROM category WHERE user='") + user->_id + wxT("'");
EXECUTE_SQL_UPDATE(req, );
@@ -1281,7 +1420,7 @@ void Database::GetStats(User* user, const wxString& monthFrom, const wxString& y
std::map<wxString, double>* Database::GetNotChecked(User* user, int month, int year)
{
std::vector<Account>::iterator accountIt;
std::vector<Account>::iterator accountIt;
std::map<wxString, double>* res = new std::map<wxString, double>;
wxSQLite3ResultSet set;
wxString req;
@@ -1304,3 +1443,44 @@ std::vector<Account>::iterator accountIt;
return res;
}
std::map<wxString, wxString> Database::getSharedAccountOwners(const wxString& account)
{
std::map<wxString, wxString> res;
wxSQLite3ResultSet set, set2;
wxString req;
req = wxT("SELECT user FROM shared_account WHERE account='") + account + wxT("'");
EXECUTE_SQL_QUERY(req, set, res);
while(set.NextRow())
{
req = wxT("SELECT name FROM user WHERE id='") + set.GetAsString(wxT("user")) + wxT("'");
EXECUTE_SQL_QUERY(req, set2, res);
res[set2.GetAsString(wxT("name"))] = set.GetAsString(wxT("user"));
}
return res;
}
wxString Database::getSharedAccountOwner(const wxString& account)
{
wxSQLite3ResultSet set, set2;
wxString req;
req = wxT("SELECT user FROM account WHERE id='") + account + wxT("'");
EXECUTE_SQL_QUERY(req, set, wxT(""));
while(set.NextRow())
{
req = wxT("SELECT name FROM user WHERE id='") + set.GetAsString(wxT("user")) + wxT("'");
EXECUTE_SQL_QUERY(req, set2, wxT(""));
}
return set2.GetAsString(wxT("name"));
}

View File

@@ -34,6 +34,7 @@
#define INIT_SCRIPT "init.sql"
class KissCount;
class User;
class Database
{
@@ -50,6 +51,10 @@ public:
wxString AddOperation(User* user, Operation& op);
void DeleteOperation(Operation& op);
void DeleteOperations(User* user, int month, int year);
bool LoadOperation(User* user, const wxString& id);
double MetaAmount(const wxString& id);
double MetaPositiveAmount(const wxString& id);
double GetAccountAmount(const wxString& id, int month, int year);
void SetAccountAmount(int month, int year, const wxString& accountId, double amount);
@@ -57,10 +62,12 @@ public:
void UpdateAccount(Account& ac);
void DeleteAccount(User* user, Account& ac);
void AddSharedAccount(Account& ac, const wxString& granted);
void RemoveSharedAccount(Account& ac, const wxString& granted);
wxString AddCategory(User* user, Category& category);
void UpdateCategory(Category& category);
void DeleteCategory(User* user, Category& category);
bool LoadCategory(const wxString& id, const wxString& name, Category& category);
std::map<int, std::vector<int> > GetAllOperations(User* user);
void GenerateMonth(User* user, int monthFrom, int yearFrom, int monthTo, int yearTo);
@@ -82,6 +89,9 @@ public:
void KillMe(User* user);
bool GetOperation(const wxString& id, Operation* op);
std::map<wxString, wxString> getSharedAccountOwners(const wxString& account);
wxString getSharedAccountOwner(const wxString& account);
std::map<wxString, double>* GetNotChecked(User* user, int month, int year);
private:

View File

@@ -19,6 +19,9 @@
#include "User.h"
User::User(Database* db) : _db(db)
{}
User::~User()
{
std::map<unsigned int, std::map<unsigned int, std::vector<Operation> >* >::iterator it;
@@ -41,6 +44,9 @@ Category User::GetCategory(wxString& catId)
if (it->id == catId)
return *it;
if (_db->LoadCategory(catId, wxT(""), cat))
return cat;
cat.id = wxT("0");
cat.parent = wxT("0");
cat.name = _("Unknown");
@@ -53,32 +59,46 @@ Category User::GetCategory(wxString& catId)
wxString User::GetCategoryName(wxString& catId)
{
Category cat;
std::vector<Category>::iterator it;
for (it=_categories.begin(); it !=_categories.end(); it++)
if (it->id == catId)
return it->name;
if (_db->LoadCategory(catId, wxT(""), cat))
return cat.name;
return _("Unknown") ;
}
wxString User::GetCategoryId(wxString& catName)
{
std::vector<Category>::iterator it;
Category cat;
for (it=_categories.begin(); it !=_categories.end(); it++)
if (it->name == catName)
return it->id;
if ( _db->LoadCategory(wxT(""), catName, cat))
return cat.id;
return wxT("0") ;
}
const wxFont& User::GetCategoryFont(wxString& catId)
const wxFont User::GetCategoryFont(wxString& catId)
{
wxFont f;
Category cat;
for (unsigned int i=0; i<_categories.size(); i++)
if (_categories[i].id == catId)
return _categoriesFonts[i];
if (_db->LoadCategory(catId, wxT(""), cat))
return KissCount::ExtractFont(cat.font);
return f;
}
@@ -176,9 +196,14 @@ void User::Group(const Operation& op)
// Already into childs
if (it2 != it->childs.end()) return;
it->childs.push_back(op.id);
break;
return;
}
}
if (_db->LoadOperation(this, op.parent))
{
(*_operations[op.year])[op.month][(*_operations[op.year])[op.month].size()-1].childs.push_back(op.id);
}
}
void User::UnGroup(const Operation& op)

View File

@@ -28,10 +28,14 @@
#include "Category.h"
#include "Account.h"
#include "Operation.h"
#include "Database.h"
class Database;
class User
{
public:
User(Database* db);
~User();
wxString _id;
@@ -46,7 +50,7 @@ public:
Category GetCategory(wxString& catId);
wxString GetCategoryName(wxString& catId);
wxString GetCategoryId(wxString& catName);
const wxFont& GetCategoryFont(wxString& catId);
const wxFont GetCategoryFont(wxString& catId);
wxString GetAccountName(const wxString& accountId);
wxString GetAccountId(wxString& accountName);
int GetCategoriesNumber();
@@ -57,6 +61,9 @@ public:
void Group(const Operation& op);
void UnGroup(const Operation& op);
void ResolveGroups(int year);
private:
Database* _db;
};
#endif

View File

@@ -20,7 +20,14 @@
#ifndef MODEL_H
#define MODEL_H
class User;
class Database;
class Account;
class Operation;
#include "User.h"
#include "Database.h"
#include "Account.h"
#include "Operation.h"
#endif