Add shared account management
This commit is contained in:
@@ -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"));
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user