422 lines
9.5 KiB
C++
422 lines
9.5 KiB
C++
/*
|
|
Copyright 2010-2012 Grégory Soutadé
|
|
|
|
This file is part of KissCount.
|
|
|
|
KissCount is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
KissCount is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with KissCount. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <algorithm>
|
|
|
|
#include <QString>
|
|
|
|
#include <view/view.hpp>
|
|
#include "User.hpp"
|
|
|
|
User::User(Database* db) : _db(db)
|
|
{}
|
|
|
|
User::~User()
|
|
{
|
|
InvalidateOperations();
|
|
}
|
|
|
|
void User::InvalidateOperations()
|
|
{
|
|
std::map<unsigned int, std::map<unsigned int, std::vector<Operation> >* >::iterator it;
|
|
std::vector<Category>::iterator it2;
|
|
int i;
|
|
|
|
for (it = _operations.begin(); it != _operations.end(); it++)
|
|
{
|
|
if (_operations[it->first])
|
|
{
|
|
delete it->second;
|
|
}
|
|
}
|
|
|
|
_operations.clear();
|
|
|
|
std::sort(_accounts.begin(), _accounts.end(), Account());
|
|
std::sort(_categories.begin(), _categories.end(), Category());
|
|
|
|
for (i=0, it2=_categories.begin(); it2 !=_categories.end(); it2++, i++)
|
|
{
|
|
_categoriesFonts[i] = KissCount::ExtractFont(it2->font);
|
|
}
|
|
}
|
|
|
|
Category User::GetCategory(int catId)
|
|
{
|
|
Category cat;
|
|
std::vector<Category>::iterator it = std::find(_categories.begin(), _categories.end(), catId);
|
|
|
|
if (it !=_categories.end()) return *it;
|
|
|
|
if (_db->LoadCategory(catId, "", cat))
|
|
return cat;
|
|
|
|
cat.id = 0;
|
|
cat.parent = 0;
|
|
cat.name = _("Unknown");
|
|
cat.font = "";
|
|
cat.backcolor = view::OWN_GREEN;
|
|
cat.forecolor = Qt::black;
|
|
|
|
return cat;
|
|
}
|
|
|
|
QString User::GetCategoryName(int catId)
|
|
{
|
|
Category cat;
|
|
std::vector<Category>::iterator it = std::find(_categories.begin(), _categories.end(), catId);
|
|
|
|
if (it !=_categories.end()) return it->name;
|
|
|
|
if (_db->LoadCategory(catId, "", cat))
|
|
return cat.name;
|
|
|
|
return _("Unknown") ;
|
|
}
|
|
|
|
int User::GetCategoryId(const QString& catName) throw (CategoryNotFound)
|
|
{
|
|
std::vector<Category>::iterator it;
|
|
Category cat;
|
|
|
|
for (it=_categories.begin(); it !=_categories.end(); it++)
|
|
if (_(it->name.toStdString().c_str()) == catName)
|
|
return it->id;
|
|
|
|
if ( _db->LoadCategory(0, catName, cat))
|
|
return cat.id;
|
|
|
|
throw CategoryNotFound();
|
|
}
|
|
|
|
const QFont User::GetCategoryFont(int catId)
|
|
{
|
|
DEFAULT_FONT(f);
|
|
Category cat;
|
|
|
|
for (unsigned int i=0; i<_categories.size(); i++)
|
|
if (_categories[i].id == catId)
|
|
return _categoriesFonts[i];
|
|
|
|
if (_db->LoadCategory(catId, "", cat))
|
|
return KissCount::ExtractFont(cat.font);
|
|
|
|
return f;
|
|
}
|
|
|
|
void User::AddCategory(const Category& cat)
|
|
{
|
|
_categories.push_back(cat);
|
|
_categoriesFonts.push_back(KissCount::ExtractFont(""));
|
|
}
|
|
|
|
void User::UpdateCategory(const Category& cat)
|
|
{
|
|
std::vector<Category>::iterator it = std::find(_categories.begin(), _categories.end(), cat.id);
|
|
|
|
if (it !=_categories.end())
|
|
{
|
|
*it = cat;
|
|
_categoriesFonts[it-_categories.begin()] = KissCount::ExtractFont(cat.font);
|
|
}
|
|
}
|
|
|
|
void User::DeleteCategory(const Category& cat)
|
|
{
|
|
std::vector<Category>::iterator it = std::find(_categories.begin(), _categories.end(), cat.id);
|
|
|
|
if (it !=_categories.end())
|
|
{
|
|
int pos = it - _categories.begin();
|
|
_categories.erase(_categories.begin()+pos);
|
|
_categoriesFonts.erase(_categoriesFonts.begin()+pos);
|
|
}
|
|
}
|
|
|
|
Tag User::GetTag(int tagId)
|
|
{
|
|
Tag tag;
|
|
std::vector<Tag>::iterator it = std::find(_tags.begin(), _tags.end(), tagId);
|
|
|
|
if (it !=_tags.end()) return *it;
|
|
|
|
if (_db->LoadTag(tagId, "", tag))
|
|
return tag;
|
|
|
|
tag.id = 0;
|
|
tag.name = "";
|
|
|
|
return tag;
|
|
}
|
|
|
|
QString User::GetTagName(int tagId)
|
|
{
|
|
Tag tag;
|
|
std::vector<Tag>::iterator it = std::find(_tags.begin(), _tags.end(), tagId);
|
|
|
|
if (it !=_tags.end()) return it->name;
|
|
|
|
if (_db->LoadTag(tagId, "", tag))
|
|
return tag.name;
|
|
|
|
return _("Unknown") ;
|
|
}
|
|
|
|
int User::GetTagId(const QString& tagName) throw (TagNotFound)
|
|
{
|
|
std::vector<Tag>::iterator it;
|
|
Tag tag;
|
|
|
|
for (it=_tags.begin(); it !=_tags.end(); it++)
|
|
if (_(it->name.toStdString().c_str()) == tagName)
|
|
return it->id;
|
|
|
|
if ( _db->LoadTag(0, tagName, tag))
|
|
return tag.id;
|
|
|
|
throw TagNotFound();
|
|
}
|
|
|
|
void User::AddTag(const Tag& tag)
|
|
{
|
|
_tags.push_back(tag);
|
|
}
|
|
|
|
void User::UpdateTag(const Tag& tag)
|
|
{
|
|
std::vector<Tag>::iterator it = std::find(_tags.begin(), _tags.end(), tag.id);
|
|
|
|
if (it !=_tags.end())
|
|
{
|
|
*it = tag;
|
|
}
|
|
}
|
|
|
|
void User::DeleteTag(const Tag& tag)
|
|
{
|
|
std::vector<Tag>::iterator it = std::find(_tags.begin(), _tags.end(), tag.id);
|
|
|
|
if (it !=_tags.end())
|
|
{
|
|
int pos = it - _tags.begin();
|
|
_tags.erase(_tags.begin()+pos);
|
|
}
|
|
}
|
|
|
|
Account User::GetAccount(int accountId) throw (AccountNotFound)
|
|
{
|
|
std::vector<Account>::iterator it = std::find(_accounts.begin(), _accounts.end(), accountId);
|
|
|
|
if (it != _accounts.end())
|
|
return *it;
|
|
|
|
throw AccountNotFound();
|
|
}
|
|
|
|
QString User::GetAccountName(int accountId)
|
|
{
|
|
std::vector<Account>::iterator it = std::find(_accounts.begin(), _accounts.end(), accountId);
|
|
|
|
if (it != _accounts.end()) return it->name;
|
|
|
|
return _("Unknown") ;
|
|
}
|
|
|
|
int User::GetAccountId(const QString& accountName) throw (AccountNotFound)
|
|
{
|
|
std::vector<Account>::iterator it;
|
|
for (it=_accounts.begin(); it !=_accounts.end(); it++)
|
|
if (it->name == accountName)
|
|
return it->id;
|
|
|
|
throw AccountNotFound();
|
|
}
|
|
|
|
int User::GetAccountIdFromAccountNumber(const QString& accountNumber) throw (AccountNotFound)
|
|
{
|
|
std::vector<Account>::iterator it;
|
|
for (it=_accounts.begin(); it !=_accounts.end(); it++)
|
|
if (it->number == accountNumber)
|
|
return it->id;
|
|
|
|
throw AccountNotFound();
|
|
}
|
|
|
|
void User::AddAccount(Account& ac)
|
|
{
|
|
_accounts.push_back(ac);
|
|
}
|
|
|
|
void User::UpdateAccount(Account& ac)
|
|
{
|
|
std::vector<Account>::iterator it = std::find(_accounts.begin(), _accounts.end(), ac.id);
|
|
|
|
if (it != _accounts.end())
|
|
*it = ac;
|
|
}
|
|
|
|
void User::DeleteAccount(Account& ac)
|
|
{
|
|
std::vector<Account>::iterator it = std::find(_accounts.begin(), _accounts.end(), ac.id);
|
|
|
|
if (it != _accounts.end())
|
|
_accounts.erase(it);
|
|
}
|
|
|
|
int User::GetCategoriesNumber()
|
|
{
|
|
return _categories.size();
|
|
}
|
|
|
|
int User::GetTagsNumber()
|
|
{
|
|
return _tags.size();
|
|
}
|
|
|
|
int User::GetAccountsNumber()
|
|
{
|
|
return _accounts.size();
|
|
}
|
|
|
|
int User::GetOperationsNumber(int month, int year)
|
|
{
|
|
return (*_operations[year])[month].size();
|
|
}
|
|
|
|
QString User::GetLanguage()
|
|
{
|
|
return _preferences["language"];
|
|
// long val;
|
|
|
|
// if (!res.Length())
|
|
// return wxLANGUAGE_ENGLISH ;
|
|
|
|
// res.ToLong(&val);
|
|
|
|
// return (wxLanguage)val;
|
|
}
|
|
|
|
void User::LinkOrUnlinkOperation(Operation& op)
|
|
{
|
|
std::vector<Operation>::iterator it;
|
|
Account account, account2;
|
|
|
|
if (!_operations[op.year])
|
|
_db->LoadYear(this, op.year);
|
|
|
|
if (!_operations[op.year])
|
|
return;
|
|
|
|
// Not Linked
|
|
if (!op.transfert)
|
|
{
|
|
for (it = (*_operations[op.year])[op.month].begin(); it != (*_operations[op.year])[op.month].end(); it++)
|
|
{
|
|
if (it->id != op.id && it->transfert == op.id)
|
|
{
|
|
it->transfert = 0;
|
|
it->_virtual = false;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
// Linked
|
|
else
|
|
{
|
|
for (it = (*_operations[op.year])[op.month].begin(); it != (*_operations[op.year])[op.month].end(); it++)
|
|
{
|
|
if (it->id != op.id && it->id == op.transfert)
|
|
{
|
|
account = GetAccount(it->account);
|
|
account2 = GetAccount(op.account);
|
|
it->transfert = op.id;
|
|
it->_virtual = account._virtual || account2._virtual;
|
|
op._virtual = account._virtual || account2._virtual;
|
|
return;
|
|
}
|
|
}
|
|
op.transfert = 0;
|
|
op._virtual = false;
|
|
}
|
|
}
|
|
|
|
bool User::Group(std::vector<Operation>* ops, const Operation& op)
|
|
{
|
|
std::vector<Operation>::iterator it;
|
|
std::vector<int>::iterator it2;
|
|
|
|
for (it = ops->begin(); it != ops->end(); it++)
|
|
{
|
|
if (it->id == op.parent)
|
|
{
|
|
it2 = std::find(it->childs.begin(), it->childs.end(), op.id);
|
|
if (it2 == it->childs.end())
|
|
it->childs.push_back(op.id);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false ;
|
|
}
|
|
|
|
void User::Group(const Operation& op)
|
|
{
|
|
std::vector<Operation>::iterator it;
|
|
|
|
if (!Group(&(*_operations[op.year])[op.month], op)
|
|
&& _db->LoadOperation(this, op.parent))
|
|
{
|
|
it = std::find ((*_operations[op.year])[op.month].begin(), (*_operations[op.year])[op.month].end(), op.parent);
|
|
if (it != (*_operations[op.year])[op.month].end())
|
|
it->childs.push_back(op.id);
|
|
}
|
|
}
|
|
|
|
void User::UnGroup(const Operation& op)
|
|
{
|
|
std::vector<Operation>::iterator it;
|
|
std::vector<int>::iterator it2;
|
|
|
|
for (it = (*_operations[op.year])[op.month].begin(); it != (*_operations[op.year])[op.month].end(); it++)
|
|
{
|
|
if (it->id == op.parent)
|
|
{
|
|
for (it2 = it->childs.begin(); it2 != it->childs.end(); it2++)
|
|
if (*it2 == op.id)
|
|
{
|
|
it->childs.erase(it2);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void User::ResolveGroups(int year)
|
|
{
|
|
unsigned int i;
|
|
std::map<unsigned int, std::vector<Operation> >::iterator it;
|
|
|
|
for (it = _operations[year]->begin(); it != _operations[year]->end(); it++)
|
|
{
|
|
for (i=0; i<it->second.size(); i++)
|
|
if (it->second[i].parent)
|
|
Group(((*_operations[year])[it->first])[i]);
|
|
}
|
|
}
|