/* Copyright 2010 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 . */ #include "KissCount.h" KissCount::KissCount(const char* bdd_filename) : _user(NULL) { wxRect rect = wxDisplay().GetGeometry(); _wxUI = new wxUI(this, wxT("KissCount"), wxPoint(50, 50), wxSize(rect.width-rect.x, rect.height-rect.y)); _wxUI->SetLanguage(wxLocale::GetSystemLanguage()); _wxUI->Show(true); _wxUI->Centre(); _wxUI->Disable(); try { _db = new Database(bdd_filename, this); } catch (std::string s) { _wxUI->Close(true); throw s; } _wxUI->ChangeUser(); _wxUI->Enable(); } KissCount::~KissCount() { delete _db; delete _wxUI; if (_user) delete _user; } std::list KissCount::GetUsers() { return _db->GetUsers(); } bool KissCount::IsValidUser(const wxString& user, const wxString& password) { return _db->IsValidUser(user, password) ; } void KissCount::LoadUser(const wxString& user) { if (_user) delete _user; _user = _db->LoadUser(user) ; if (_user) _wxUI->LoadUser(); } void KissCount::LoadYear(int year, bool force) { if (!force && _user->_operations[year] != NULL) return; if (_user->_operations[year] != NULL) { delete _user->_operations[year]; _user->_operations[year] = NULL; } _db->LoadYear(_user, year); } User* KissCount::GetUser() { return _user; } double KissCount::GetAccountAmount(const wxString& id, int month, int year) { return _db->GetAccountAmount(id, month, year); } void KissCount::UpdateOperation(Operation& op) { // Unlink op.transfert = wxT(""); _user->LinkOrUnlinkOperation(op); _db->UpdateOperation(op); // Link _user->LinkOrUnlinkOperation(op); } wxString KissCount::AddOperation(Operation& op) { wxString ret = _db->AddOperation(_user, op); if (op.transfert.Length()) _user->LinkOrUnlinkOperation(op); return ret; } void KissCount::DeleteOperation(Operation& op) { if (op.transfert.Length()) { op.transfert = wxT(""); _user->LinkOrUnlinkOperation(op); } _db->DeleteOperation(op); } void KissCount::DeleteOperations(int month, int year) { _db->DeleteOperations(_user, month, year); if (month != -1) (*_user->_operations[year]).erase(month); if (month == -1 || !_user->_operations[year]->size()) { delete _user->_operations[year]; _user->_operations.erase(year); } } double KissCount::MetaAmount(const wxString& id) { return _db->MetaAmount(id); } double KissCount::MetaPositiveAmount(const wxString& id) { return _db->MetaPositiveAmount(id); } void KissCount::SetAccountAmount(int month, int year, const wxString& accountId, double amount) { _db->SetAccountAmount(month, year, accountId, amount); } wxString KissCount::AddAccount(Account& ac) { wxDateTime curDate; ac.id = _db->AddAccount(_user, ac); _user->_accounts.push_back(ac); curDate.SetToCurrent(); SetAccountAmount((int)curDate.GetMonth(), curDate.GetYear(), ac.id, 0.0); return ac.id; } bool sortAccounts(Account ac1, Account ac2) { if (ac1._default) return true; if (ac2._default) return false; return (ac1.name.Cmp(ac2.name) < 0); } void KissCount::UpdateAccount(Account& ac) { std::vector::iterator it; int i; _db->UpdateAccount(ac); for (i=0, it=_user->_accounts.begin(); it !=_user->_accounts.end(); it++, i++) if (it->id == ac.id) _user->_accounts[i] = ac; if (ac._default) std::sort(_user->_accounts.begin(), _user->_accounts.end(), sortAccounts); } void KissCount::DeleteAccount(Account& ac) { std::vector::iterator it; int i; _db->DeleteAccount(_user, ac); for (i=0, it=_user->_accounts.begin(); it !=_user->_accounts.end(); it++, i++) if (it->id == ac.id) { _user->_accounts.erase(_user->_accounts.begin()+i); break; } } void KissCount::AddSharedAccount(Account& ac, const wxString& granted) { _db->AddSharedAccount(ac, granted); } void KissCount::RemoveSharedAccount(Account& ac, const wxString& granted) { _db->RemoveSharedAccount(ac, granted); } std::map KissCount::getSharedAccountOwners(const wxString& account) { return _db->getSharedAccountOwners(account); } wxString KissCount::getSharedAccountOwner(const wxString& account) { return _db->getSharedAccountOwner(account); } wxString KissCount::AddCategory(Category& category) { wxString id; id = _db->AddCategory(_user, category); category.id = id; _user->_categories.push_back(category); _user->_categoriesFonts.push_back(ExtractFont(wxT(""))); return id; } void KissCount::UpdateCategory(Category& category) { _db->UpdateCategory(category); for (int i=0; i<_user->GetCategoriesNumber();i++) if (_user->_categories[i].id == category.id) { _user->_categories[i] = category; _user->_categoriesFonts[i] = ExtractFont(category.font); break; } } void KissCount::DeleteCategory(Category& category) { _db->DeleteCategory(_user, category); for (int i=0; i<_user->GetCategoriesNumber();i++) if (_user->_categories[i].id == category.id) { _user->_categories.erase(_user->_categories.begin()+i); _user->_categoriesFonts.erase(_user->_categoriesFonts.begin()+i); break; } } std::map > KissCount::GetAllOperations() { return _db->GetAllOperations(_user); } void KissCount::GenerateMonth(int monthFrom, int yearFrom, int monthTo, int yearTo) { std::vector::iterator it, it2; std::map meta; Operation op; _db->GenerateMonth(_user, monthFrom, yearFrom, monthTo, yearTo); if (!_user->_operations[yearTo]) _user->_operations[yearTo] = new std::map >(); if (monthFrom != -1 && yearFrom != -1) { LoadYear(yearFrom, false); for(it = (*_user->_operations[yearFrom])[monthFrom].begin(); it != (*_user->_operations[yearFrom])[monthFrom].end(); it++) { if (!it->fix_cost) continue; op = *it; op.month = monthTo; op.year = yearTo; op.checked = false; op.id = AddOperation(op); op.childs.clear(); if (op.meta) meta[it->id] = op.id; (*_user->_operations[yearTo])[monthTo].push_back(op); } // Re Generate parents for(it = (*_user->_operations[yearTo])[monthTo].begin(); it != (*_user->_operations[yearTo])[monthTo].end(); it++) { if (it->parent.Length()) { it->parent = meta[it->parent]; UpdateOperation(*it); for(it2 = (*_user->_operations[yearTo])[monthTo].begin(); it2 != (*_user->_operations[yearTo])[monthTo].end(); it2++) if (it2->id == it->parent) { it2->childs.push_back(it->id); break; } } } } _wxUI->GenerateMonth(monthTo, yearTo); } void KissCount::ChangePassword(const wxString& password) { _db->ChangePassword(_user, password); } bool KissCount::UserExists(const wxString& name) { return _db->UserExists(name); } void KissCount::ChangeName(const wxString& name) { _db->ChangeName(_user, name); _user->_name = name; } void KissCount::NewUser(const wxString& name) { wxDateTime curDate; Account ac = { /*.id = */wxT(""), /*.name = */_("Account 1"), /*.number = */wxT(""), /*.shared = */false, /*.blocked = */false, /*._default = */true, /*.is_owner = */true}; Category cat ; _db->NewUser(name); if (_user) delete _user; _user = _db->LoadUser(name) ; curDate.SetToCurrent(); AddAccount(ac); cat.parent = wxT("0") ; cat.name = _("Fix") ; cat.backcolor = OWN_YELLOW ; cat.forecolor = *wxBLACK; AddCategory(cat); cat.parent = wxT("0") ; cat.name = _("Groceries") ; cat.backcolor = OWN_GREEN; cat.forecolor = *wxBLACK; AddCategory(cat); cat.parent = wxT("0") ; cat.name = _("Hobbies") ; cat.backcolor = OWN_GREEN; cat.forecolor = *wxBLACK; AddCategory(cat); cat.parent = wxT("0") ; cat.name = _("Operating exepense") ; cat.backcolor = OWN_GREEN; cat.forecolor = *wxBLACK; AddCategory(cat); cat.parent = wxT("0") ; cat.name = _("Unexpected") ; cat.backcolor = OWN_GREEN; cat.forecolor = *wxBLACK; AddCategory(cat); cat.parent = wxT("0") ; cat.name = _("Other") ; cat.backcolor = OWN_GREEN; cat.forecolor = *wxBLACK; AddCategory(cat); SetOperationOrder(wxT("ASC")); _db->GenerateMonth(_user, -1, -1, (int)curDate.GetMonth(), curDate.GetYear()); } void KissCount::KillMe() { _wxUI->KillMe(); _db->KillMe(_user); delete _user; _user = NULL; _wxUI->ChangeUser(); } void KissCount::SetLanguage(wxLanguage language) { _user->_preferences[wxT("language")] = wxString::Format(wxT("%d"), language) ; _db->UpdatePreference(_user, wxT("language")); } /* ASC (default) or DESC */ void KissCount::SetOperationOrder(const wxString& order) { _user->_preferences[wxT("operation_order")] = order; _db->UpdatePreference(_user, wxT("operation_order")); } std::vector* KissCount::Search(wxString* description, wxDateTime* dateFrom, wxDateTime* dateTo, wxString* amountFrom, wxString* amountTo, std::vector categories, int types, std::vector accounts) { return _db->Search(_user, description, dateFrom, dateTo, amountFrom, amountTo, categories, types, accounts, true); } bool KissCount::SearchPreviousOperation(Operation* res, Operation& op, int month, int year) { std::vector* operations; wxDateTime* date ; //wxDateSpan threeMonths(0, 3); Not working :( std::vector v; int i; month -= 3; if (month < 0) { year -= 1; month += 12; } date = new wxDateTime(0, (wxDateTime::Month)month, year); operations = _db->Search(_user, &op.description, date, NULL, NULL, NULL, v, op.fix_cost ? FIX_OP : NON_FIX_OP, v, false); delete date; if (!operations->size()) { delete operations; return false; } for(i=operations->size()-1; i>=0; i--) if (!(*operations)[i].meta) { *res = (*operations)[i]; delete operations; return true; } delete operations; return false; } void KissCount::GetStats(int monthFrom, int yearFrom, int monthTo, int yearTo, std::map > >* accountAmounts, std::map* categories) { wxString monthF = wxString::Format(wxT("%d"), monthFrom); wxString monthT = wxString::Format(wxT("%d"), monthTo); wxString yearF = wxString::Format(wxT("%d"), yearFrom); wxString yearT = wxString::Format(wxT("%d"), yearTo); _db->GetStats(_user, monthF, yearF, monthT, yearT, accountAmounts, categories); } void KissCount::GetMonthStats(int month, int year, int nbDays, std::map >* operations, std::map* categories) { wxString monthS = wxString::Format(wxT("%d"), month); wxString yearS = wxString::Format(wxT("%d"), year); _db->GetMonthStats(_user, monthS, yearS, nbDays, operations, categories); } std::map* KissCount::GetNotChecked(int month, int year) { return _db->GetNotChecked(_user, month, year); } wxFont KissCount::ExtractFont(wxString strFont) { long int pos, pointSize, family, style, weight; wxString faceName; if (!strFont.Length()) { DEFAULT_FONT(f); return f; } pos = strFont.Find(wxT(";")); if (pos != -1) { strFont.SubString(0, pos).ToLong(&pointSize); strFont = strFont.SubString(pos+1, strFont.Length()); } pos = strFont.Find(wxT(";")); if (pos != -1) { strFont.SubString(0, pos).ToLong(&family); strFont = strFont.SubString(pos+1, strFont.Length()); } pos = strFont.Find(wxT(";")); if (pos != -1) { strFont.SubString(0, pos).ToLong(&style); strFont = strFont.SubString(pos+1, strFont.Length()); } pos = strFont.Find(wxT(";")); if (pos != -1) { strFont.SubString(0, pos).ToLong(&weight); strFont = strFont.SubString(pos+1, strFont.Length()); } faceName = strFont; return wxFont(pointSize, family, style, weight, false, faceName) ; } wxString KissCount::CompactFont(const wxFont& font) { wxString res = wxString::Format(wxT("%d;%d;%d;%d;"), font.GetPointSize(), font.GetFamily(), font.GetStyle(), font.GetWeight()); res += font.GetFaceName(); return res; }