Tag management : first version
This commit is contained in:
parent
899dc3db71
commit
57d4b90182
|
@ -3,8 +3,9 @@ CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR(255), password VARCHAR(2
|
|||
CREATE TABLE account(id INTEGER PRIMARY KEY, user REFERENCES user(id), name VARCHAR(255), number VARCHAR(255), shared CHAR(1), blocked CHAR(1), default_account CHAR(1), virtual CHAR(1), hidden CHAR(1));
|
||||
CREATE TABLE shared_account(account REFERENCES account(id), user REFERENCES user(id));
|
||||
CREATE TABLE account_amount(account REFERENCES account(id), year INTEGER, month INTEGER, amount INTEGER, PRIMARY KEY(account, year, month));
|
||||
CREATE TABLE operation(id INTEGER PRIMARY KEY, parent REFERENCES operation(id), user REFERENCES user(id), account REFERENCES account(id) ON DELETE SET NULL, year INTEGER, month INTEGER, day INTEGER, amount INTEGER, description VARCHAR(255), category REFERENCES category(id) ON DELETE SET NULL, fix_cost CHAR(1), checked CHAR(1), formula VARCHAR(255), transfert REFERENCES operation(id), meta CHAR(1), virtual CHAR(1));
|
||||
CREATE TABLE operation(id INTEGER PRIMARY KEY, parent REFERENCES operation(id), user REFERENCES user(id), account REFERENCES account(id) ON DELETE SET NULL, year INTEGER, month INTEGER, day INTEGER, amount INTEGER, description VARCHAR(255), category REFERENCES category(id) ON DELETE SET NULL, fix_cost CHAR(1), checked CHAR(1), formula VARCHAR(255), transfert REFERENCES operation(id), meta CHAR(1), virtual CHAR(1), tag REFERENCES tag(id));
|
||||
CREATE TABLE category(id INTEGER PRIMARY KEY, user REFERENCES user(id), parent REFERENCES category(id) ON DELETE SET NULL, name VARCHAR(255), backcolor VARCHAR(10), forecolor VARCHAR(10), font VARCHAR(255), fix_cost CHAR(1));
|
||||
CREATE TABLE preference(user REFERENCES user(id), name VARCHAR(255), value VARCHAR(255), PRIMARY KEY(user, name));
|
||||
CREATE TABLE import_pattern(user REFERENCES user(id), description VARCHAR(255), pattern VARCHAR(255), account REFERENCES account(id), category REFERENCES category(id), PRIMARY KEY(user, description));
|
||||
INSERT INTO kisscount ("db_version") VALUES ("3");
|
||||
CREATE TABLE tag(id INTEGER PRIMARY KEY, user REFERENCES user(id), name VARCHAR(255));
|
||||
INSERT INTO kisscount ("db_version") VALUES ("4");
|
||||
|
|
|
@ -251,6 +251,33 @@ void KissCount::DeleteCategory(Category& category, int replacement)
|
|||
LoadYear(it->first, true);
|
||||
}
|
||||
|
||||
int KissCount::AddTag(Tag& tag)
|
||||
{
|
||||
tag.id = _db->AddTag(_user, tag);
|
||||
_user->AddTag(tag);
|
||||
|
||||
return tag.id;
|
||||
}
|
||||
|
||||
void KissCount::UpdateTag(Tag& tag)
|
||||
{
|
||||
_db->UpdateTag(tag);
|
||||
_user->UpdateTag(tag);
|
||||
}
|
||||
|
||||
void KissCount::DeleteTag(Tag& tag, int replacement)
|
||||
{
|
||||
std::map<unsigned int, std::map<unsigned int, std::vector<Operation> >* >::iterator it;
|
||||
|
||||
_db->DeleteTag(_user, tag, replacement);
|
||||
_user->DeleteTag(tag);
|
||||
|
||||
for (it= _user->_operations.begin();
|
||||
it != _user->_operations.end();
|
||||
it++)
|
||||
LoadYear(it->first, true);
|
||||
}
|
||||
|
||||
std::map<int, std::vector<int> > KissCount::GetAllOperations()
|
||||
{
|
||||
return _db->GetAllOperations(_user);
|
||||
|
@ -411,10 +438,11 @@ const QString& KissCount::GetOperationOrder()
|
|||
|
||||
std::vector<Operation>* KissCount::Search(QString* description, QDate* dateFrom, QDate* dateTo,
|
||||
int* amountFrom, int* amountTo,
|
||||
std::vector<int> categories, int types, std::vector<int> accounts)
|
||||
std::vector<int> categories,
|
||||
int types, std::vector<int> accounts, std::vector<int> tags)
|
||||
{
|
||||
|
||||
return _db->Search(_user, description, dateFrom, dateTo, amountFrom, amountTo, categories, types, accounts, true);
|
||||
return _db->Search(_user, description, dateFrom, dateTo, amountFrom, amountTo, categories, types, accounts, true, tags);
|
||||
}
|
||||
|
||||
bool KissCount::SearchPreviousOperation(Operation* res, Operation& op, int month, int year, bool limitToType, int index)
|
||||
|
@ -434,9 +462,9 @@ bool KissCount::SearchPreviousOperation(Operation* res, Operation& op, int month
|
|||
QDate date = QDate(year, month, 0);
|
||||
|
||||
if (limitToType)
|
||||
operations = _db->Search(_user, &op.description, &date, 0, 0, 0, v, op.fix_cost ? +Database::FIX_OP : +Database::NON_FIX_OP, v, false);
|
||||
operations = _db->Search(_user, &op.description, &date, 0, 0, 0, v, op.fix_cost ? +Database::FIX_OP : +Database::NON_FIX_OP, v, false, v);
|
||||
else
|
||||
operations = _db->Search(_user, &op.description, &date, 0, 0, 0, v, Database::ALL_OP, v, false);
|
||||
operations = _db->Search(_user, &op.description, &date, 0, 0, 0, v, Database::ALL_OP, v, false, v);
|
||||
|
||||
if (!operations->size())
|
||||
{
|
||||
|
@ -471,16 +499,16 @@ void KissCount::GetHistory(int month, int year, QStringList& list)
|
|||
|
||||
void KissCount::GetStats(int monthFrom, int yearFrom, int monthTo, int yearTo,
|
||||
std::map<int, std::map<int, std::map<int, int> > >* accountAmounts,
|
||||
std::map<int, int>* categories)
|
||||
std::map<int, int>* categories, std::map<int, int>* tags)
|
||||
{
|
||||
_db->GetStats(_user, monthFrom, yearFrom, monthTo, yearTo, accountAmounts, categories);
|
||||
_db->GetStats(_user, monthFrom, yearFrom, monthTo, yearTo, accountAmounts, categories, tags);
|
||||
}
|
||||
|
||||
void KissCount::GetMonthStats(int month, int year, int nbDays,
|
||||
std::map<int, std::vector<int> >* operations,
|
||||
std::map<int, int>* categories)
|
||||
std::map<int, int>* categories, std::map<int, int>* tags)
|
||||
{
|
||||
_db->GetMonthStats(_user, month, year, nbDays, operations, categories);
|
||||
_db->GetMonthStats(_user, month, year, nbDays, operations, categories, tags);
|
||||
}
|
||||
|
||||
void KissCount::UpdateStats()
|
||||
|
|
|
@ -93,6 +93,10 @@ public:
|
|||
void UpdateCategory(Category& category);
|
||||
void DeleteCategory(Category& category, int replacement);
|
||||
|
||||
int AddTag(Tag& tag);
|
||||
void UpdateTag(Tag& tag);
|
||||
void DeleteTag(Tag& tag, int replacement);
|
||||
|
||||
std::map<int, std::vector<int> > GetAllOperations();
|
||||
|
||||
int GenerateMonth(int monthFrom, int yearFrom, int monthTo, int yearTo);
|
||||
|
@ -104,17 +108,18 @@ public:
|
|||
|
||||
std::vector<Operation>* Search(QString* description, QDate* dateFrom, QDate* dateTo,
|
||||
int* amountFrom, int* amountTo,
|
||||
std::vector<int> categories, int types, std::vector<int> accounts);
|
||||
std::vector<int> categories,
|
||||
int types, std::vector<int> accounts, std::vector<int> tags);
|
||||
|
||||
bool SearchPreviousOperation(Operation* res, Operation& op, int month, int year, bool limitToType, int index);
|
||||
|
||||
void GetStats(int monthFrom, int yearFrom, int monthTo, int yearTo,
|
||||
std::map<int, std::map<int, std::map<int, int> > >* accountAmounts,
|
||||
std::map<int, int>* categories);
|
||||
std::map<int, int>* categories, std::map<int, int>* tags);
|
||||
|
||||
void GetMonthStats(int month, int year, int nbDays,
|
||||
std::map<int, std::vector<int> >* operations,
|
||||
std::map<int, int>* categories);
|
||||
std::map<int, int>* categories, std::map<int, int>* tags);
|
||||
void UpdateStats();
|
||||
|
||||
std::map<int, int>* GetNotChecked(int month, int year);
|
||||
|
|
|
@ -187,6 +187,7 @@ static inline void fillOperation(Operation* op, const QSqlRecord& set)
|
|||
op->amount = set.value("amount").toInt();
|
||||
op->description = set.value("description").toString();
|
||||
op->category = set.value("category").toInt();
|
||||
op->tag = set.value("tag").toInt();
|
||||
op->fix_cost = set.value("fix_cost").toBool();
|
||||
op->checked = set.value("checked").toBool();
|
||||
op->transfert = set.value("transfert").toInt();
|
||||
|
@ -219,11 +220,18 @@ static inline void fillCategory(Category* category, const QSqlRecord& set)
|
|||
category->fix_cost = set.value("fix_cost").toBool();
|
||||
}
|
||||
|
||||
static inline void fillTag(Tag* tag, const QSqlRecord& set)
|
||||
{
|
||||
tag->id = set.value("id").toInt();
|
||||
tag->name = set.value("name").toString();
|
||||
}
|
||||
|
||||
User* Database::LoadUser(const QString& name)
|
||||
{
|
||||
User* user;
|
||||
Account account;
|
||||
Category category;
|
||||
Tag tag;
|
||||
ImportPattern importPattern;
|
||||
QString req;
|
||||
QSqlRecord set;
|
||||
|
@ -311,6 +319,19 @@ User* Database::LoadUser(const QString& name)
|
|||
|
||||
query.clear();
|
||||
|
||||
req = QString("SELECT * FROM tag WHERE user='%1' ORDER BY name ASC").arg(user->_id);
|
||||
EXECUTE_SQL_QUERY_WITH_CODE(req, 0, {delete user;}, {delete user;});
|
||||
|
||||
while (query.next())
|
||||
{
|
||||
set = query.record();
|
||||
fillTag(&tag, set);
|
||||
|
||||
user->_tags.push_back(tag);
|
||||
}
|
||||
|
||||
query.clear();
|
||||
|
||||
req = QString("SELECT name, value FROM preference WHERE user='%1' ORDER BY value ASC").arg(user->_id);
|
||||
EXECUTE_SQL_QUERY_WITH_CODE(req, 0, {delete user;}, {delete user;});
|
||||
|
||||
|
@ -549,9 +570,9 @@ void Database::UpdateOperation(User* user, Operation& op, bool checkTransfert)
|
|||
|
||||
ESCAPE_CHARS(op.description);
|
||||
|
||||
req = "UPDATE operation SET parent='%1', account='%2', year='%3', month='%4', day='%5', amount='%6', description=\"%7\", category='%8'" ;
|
||||
req = "UPDATE operation SET parent='%1', account='%2', year='%3', month='%4', day='%5', amount='%6', description=\"%7\", category='%8', tag='%9'" ;
|
||||
req = req.arg((op.parent) ? QString::number(op.parent) : "", QString::number(op.account), QString::number(op.year), QString::number(op.month),
|
||||
QString::number(op.day), v.sprintf("%d", op.amount), op.description, QString::number(op.category));
|
||||
QString::number(op.day), v.sprintf("%d", op.amount), op.description, QString::number(op.category), QString::number(op.tag));
|
||||
req += ", fix_cost='%1', checked='%2', transfert='%3', meta='%4', virtual='%5', formula='%6' WHERE id='%7'";
|
||||
req = req.arg(QString::number(op.fix_cost), QString::number(op.checked), (op.transfert) ? QString::number(op.transfert): "",
|
||||
QString::number(op.meta), QString::number(op._virtual), op.formula, QString::number(op.id));
|
||||
|
@ -571,11 +592,11 @@ int Database::AddOperation(User* user, Operation& op, bool checkTransfert)
|
|||
|
||||
ESCAPE_CHARS(op.description);
|
||||
|
||||
req = "INSERT INTO operation ('user', 'parent', 'account', 'year', 'month', 'day', 'amount', 'description', 'category', 'fix_cost', 'formula', 'transfert', 'meta', 'virtual', 'checked') VALUES ('%1', '%2', '%3', '%4', '%5', '%6', '%7', \"%8\"" ;
|
||||
req = "INSERT INTO operation ('user', 'parent', 'account', 'year', 'month', 'day', 'amount', 'description', 'category', 'tag', 'fix_cost', 'formula', 'transfert', 'meta', 'virtual', 'checked') VALUES ('%1', '%2', '%3', '%4', '%5', '%6', '%7', \"%8\"" ;
|
||||
req = req.arg(QString::number(user->_id), (op.parent) ? QString::number(op.parent): "", QString::number(op.account), QString::number(op.year),
|
||||
QString::number(op.month), QString::number(op.day), v.sprintf("%d", op.amount), op.description);
|
||||
req += ", '%1', '%2', '%3', '%4', '%5', '%6', '%7')";
|
||||
req = req.arg(QString::number(op.category), QString::number(op.fix_cost), op.formula, (op.transfert) ? QString::number(op.transfert): "",
|
||||
req += ", '%1', '%2', '%3', '%4', '%5', '%6', '%7', '%8')";
|
||||
req = req.arg(QString::number(op.category), QString::number(op.tag), QString::number(op.fix_cost), op.formula, (op.transfert) ? QString::number(op.transfert): "",
|
||||
QString::number(op.meta), QString::number(op._virtual), QString::number(op.checked));
|
||||
|
||||
if (!query.exec(req))
|
||||
|
@ -1001,6 +1022,80 @@ bool Database::LoadCategory(int id, const QString& name, Category& category)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int Database::AddTag(User* user, Tag& tag)
|
||||
{
|
||||
QString req;
|
||||
QString backcolor, forecolor;
|
||||
QSqlQuery query(_db);
|
||||
|
||||
req = "INSERT INTO tag ('user', 'name') VALUES ('" ;
|
||||
req += QString::number(user->_id) + "'";
|
||||
req += ", '" + tag.name + "'";
|
||||
req += ")";
|
||||
|
||||
if (!query.exec(req))
|
||||
{
|
||||
QMessageBox::critical(0, _("Error"), _("Update failed !\n") + req);
|
||||
std::cerr << __FUNCTION__ << "\n" ;
|
||||
std::cerr << req.toStdString() << "\n" ;
|
||||
std::cerr << query.lastError().text().toStdString() << "\n" ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return query.lastInsertId().toInt();
|
||||
}
|
||||
|
||||
void Database::UpdateTag(Tag& tag)
|
||||
{
|
||||
QString req;
|
||||
|
||||
req = "UPDATE tag SET" ;
|
||||
req += "name='" + tag.name + "'";
|
||||
req += " WHERE id='" + QString::number(tag.id) + "'";
|
||||
|
||||
EXECUTE_SQL_UPDATE(req, );
|
||||
}
|
||||
|
||||
void Database::DeleteTag(User* user, Tag& tag, int replacement)
|
||||
{
|
||||
QString req;
|
||||
|
||||
req = QString("DELETE FROM tag WHERE id='%1'").arg(tag.id);
|
||||
|
||||
EXECUTE_SQL_UPDATE(req, );
|
||||
|
||||
req = QString("UPDATE operation SET tag='%1' WHERE tag='%2' AND user='%3'")
|
||||
.arg(QString::number(replacement), QString::number(tag.id), QString::number(user->_id));
|
||||
|
||||
EXECUTE_SQL_UPDATE(req, );
|
||||
}
|
||||
|
||||
bool Database::LoadTag(int id, const QString& name, Tag& tag)
|
||||
{
|
||||
QSqlRecord set;
|
||||
QString req;
|
||||
QSqlQuery query(_db);
|
||||
bool ret = false ;
|
||||
|
||||
if (id)
|
||||
req = QString("SELECT * FROM tag WHERE id='%1'").arg(id);
|
||||
else
|
||||
req = QString("SELECT * FROM tag WHERE name='%1'").arg(name);
|
||||
|
||||
EXECUTE_SQL_QUERY(req, false);
|
||||
|
||||
if (query.next())
|
||||
{
|
||||
set = query.record();
|
||||
fillTag(&tag, set);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
query.clear();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::map<int, std::vector<int> > Database::GetAllOperations(User* user)
|
||||
{
|
||||
QString req, req2, reqUnion;
|
||||
|
@ -1211,6 +1306,9 @@ void Database::KillMe(User* user)
|
|||
req = QString("DELETE FROM category WHERE user='%1'").arg(user->_id);
|
||||
EXECUTE_SQL_UPDATE(req, );
|
||||
|
||||
req = QString("DELETE FROM tag WHERE user='%1'").arg(user->_id);
|
||||
EXECUTE_SQL_UPDATE(req, );
|
||||
|
||||
req = QString("DELETE FROM user WHERE id='%1'").arg(user->_id);
|
||||
EXECUTE_SQL_UPDATE(req, );
|
||||
}
|
||||
|
@ -1228,7 +1326,7 @@ void Database::UpdatePreference(User* user, const QString& preference)
|
|||
|
||||
std::vector<Operation>* Database::Search(User* user, QString* description, QDate* dateFrom, QDate* dateTo,
|
||||
int* amountFrom, int* amountTo,
|
||||
std::vector<int> categories, int types, std::vector<int> accounts, bool wildcards)
|
||||
std::vector<int> categories, int types, std::vector<int> accounts, bool wildcards, std::vector<int> tags)
|
||||
{
|
||||
QSqlRecord set;
|
||||
QSqlQuery query(_db);
|
||||
|
@ -1318,6 +1416,20 @@ std::vector<Operation>* Database::Search(User* user, QString* description, QDate
|
|||
req += "')";
|
||||
}
|
||||
|
||||
if (tags.size())
|
||||
{
|
||||
if (firstCond) req += " AND " ; else firstCond = true;
|
||||
req += "category IN ('";
|
||||
it = tags.begin();
|
||||
req += QString::number(*it);
|
||||
it++;
|
||||
|
||||
for (; it != tags.end(); it++)
|
||||
req += "', '" + QString::number(*it) ;
|
||||
|
||||
req += "')";
|
||||
}
|
||||
|
||||
if (types)
|
||||
{
|
||||
if (((types & Database::FIX_OP) && !(types & Database::NON_FIX_OP)) ||
|
||||
|
@ -1398,13 +1510,14 @@ std::vector<Operation>* Database::Search(User* user, QString* description, QDate
|
|||
|
||||
void Database::GetStats(User* user, int monthFrom, int yearFrom, int monthTo,
|
||||
int yearTo, std::map<int, std::map<int, std::map<int, int> > >* accountAmounts,
|
||||
std::map<int, int>* categories)
|
||||
std::map<int, int>* categories, std::map<int, int>* tags)
|
||||
{
|
||||
QSqlRecord set;
|
||||
QSqlQuery query(_db);
|
||||
QString req, req2;
|
||||
std::vector<Account>::iterator accountIt;
|
||||
std::vector<Category>::iterator categoryIt;
|
||||
std::vector<Tag>::iterator tagIt;
|
||||
|
||||
if (!user->_accounts.empty())
|
||||
{
|
||||
|
@ -1473,12 +1586,59 @@ void Database::GetStats(User* user, int monthFrom, int yearFrom, int monthTo,
|
|||
query.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (tags)
|
||||
{
|
||||
for (tagIt = user->_tags.begin(); tagIt != user->_tags.end(); tagIt++)
|
||||
{
|
||||
req = "SELECT SUM(amount) as amount FROM operation AS o1 WHERE tag='" + QString::number(tagIt->id) + "'";
|
||||
accountIt = user->_accounts.begin();
|
||||
req += " AND (account IN('" + QString::number(accountIt->id);
|
||||
accountIt++;
|
||||
for (;accountIt != user->_accounts.end(); accountIt++)
|
||||
{
|
||||
req += "', '" + QString::number(accountIt->id) ;
|
||||
}
|
||||
req += "')";
|
||||
req += " OR user='" + QString::number(user->_id) + "')";
|
||||
|
||||
req += " AND (year > '" + QString::number(yearFrom) + "' OR (year == '" + QString::number(yearFrom) + "' AND month >= '" + QString::number(monthFrom) + "'))";
|
||||
req += " AND (year < '" + QString::number(yearTo) + "' OR (year == '" + QString::number(yearTo) + "' AND month <= '" + QString::number(monthTo) + "'))";
|
||||
req += " AND meta='0'";
|
||||
|
||||
req2 = req + " AND (transfert='' OR transfert IS 0)";
|
||||
req2 += " AND amount < 0";
|
||||
|
||||
EXECUTE_SQL_QUERY(req2, );
|
||||
|
||||
if (query.next())
|
||||
{
|
||||
set = query.record();
|
||||
(*tags)[tagIt->id] = -set.value("amount").toInt();
|
||||
}
|
||||
query.clear();
|
||||
|
||||
// Transfert on blocked accounts must be computed
|
||||
req2 = req + " AND transfert != ''";
|
||||
req2 += " AND (SELECT blocked FROM account WHERE id=o1.account)";
|
||||
req2 += " AND amount > 0";
|
||||
|
||||
EXECUTE_SQL_QUERY(req2, );
|
||||
|
||||
if (query.next())
|
||||
{
|
||||
set = query.record();
|
||||
(*tags)[tagIt->id] += set.value("amount").toInt();
|
||||
}
|
||||
query.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Database::GetMonthStats(User* user, int month, int year, int nbDays,
|
||||
std::map<int, std::vector<int> >* operations,
|
||||
std::map<int, int>* categories)
|
||||
std::map<int, int>* categories, std::map<int, int>* tags)
|
||||
{
|
||||
QSqlRecord set;
|
||||
QSqlQuery query(_db);
|
||||
|
@ -1535,7 +1695,7 @@ void Database::GetMonthStats(User* user, int month, int year, int nbDays,
|
|||
}
|
||||
|
||||
// Fill categories
|
||||
GetStats(user, month, year, month, year, 0, categories) ;
|
||||
GetStats(user, month, year, month, year, 0, categories, tags) ;
|
||||
}
|
||||
|
||||
std::map<int, int>* Database::GetNotChecked(User* user, int month, int year)
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
static const int NOT_CHECKED_OP = (1 << 3);
|
||||
static const int ALL_OP = (~0);
|
||||
|
||||
static const int VERSION = 3;
|
||||
static const int VERSION = 4;
|
||||
|
||||
Database(const char* filename, KissCount* kiss);
|
||||
|
||||
|
@ -128,6 +128,11 @@ public:
|
|||
void DeleteCategory(User* user, Category& category, int replacement);
|
||||
bool LoadCategory(int id, const QString& name, Category& category);
|
||||
|
||||
int AddTag(User* user, Tag& tag);
|
||||
void UpdateTag(Tag& tag);
|
||||
void DeleteTag(User* user, Tag& tag, int replacement);
|
||||
bool LoadTag(int id, const QString& name, Tag& tag);
|
||||
|
||||
std::map<int, std::vector<int> > GetAllOperations(User* user);
|
||||
void GenerateMonth(User* user, int monthFrom, int yearFrom, int monthTo, int yearTo);
|
||||
|
||||
|
@ -140,15 +145,15 @@ public:
|
|||
|
||||
std::vector<Operation>* Search(User* user, QString* description, QDate* dateFrom, QDate* dateTo,
|
||||
int* amountFrom, int* amountTo,
|
||||
std::vector<int> categories, int types, std::vector<int> accounts, bool wildcards);
|
||||
std::vector<int> categories, int types, std::vector<int> accounts, bool wildcards, std::vector<int> tags);
|
||||
|
||||
void GetStats(User* user, int monthFrom, int yearFrom, int monthTo,
|
||||
int yearTo, std::map<int, std::map<int, std::map<int, int> > >* accountAmounts,
|
||||
std::map<int, int>* categories);
|
||||
std::map<int, int>* categories, std::map<int, int>* tags);
|
||||
|
||||
void GetMonthStats(User* user, int month, int year, int nbDays,
|
||||
std::map<int, std::vector<int> >* operations,
|
||||
std::map<int, int>* categories);
|
||||
std::map<int, int>* categories, std::map<int, int>* tags);
|
||||
|
||||
void KillMe(User* user);
|
||||
bool GetOperation(int id, Operation* op);
|
||||
|
|
|
@ -94,9 +94,28 @@ static void Version_2_to_3(QSqlDatabase& _db)
|
|||
ON_ERROR(_("Cannot update database version 2 to version 3 because some columns needs to be deleted."));
|
||||
}
|
||||
|
||||
static void Version_3_to_4(QSqlDatabase& _db)
|
||||
{
|
||||
QString req ;
|
||||
|
||||
req = "CREATE TABLE tag(id INTEGER PRIMARY KEY, user REFERENCES user(id), name VARCHAR(255));";
|
||||
|
||||
UPDATE_TABLE("2", "3", "1");
|
||||
|
||||
/* Account */
|
||||
req = "ALTER TABLE operation ADD tag REFERENCES tag(id)";
|
||||
|
||||
UPDATE_TABLE("2", "3", "2");
|
||||
|
||||
req = "UPDATE operation SET tag='0'";
|
||||
|
||||
UPDATE_TABLE("2", "3", "3");
|
||||
}
|
||||
|
||||
static update_func updates[] = {
|
||||
Version_1_to_2,
|
||||
Version_2_to_3
|
||||
Version_2_to_3,
|
||||
Version_3_to_4
|
||||
};
|
||||
|
||||
void Database::CheckDatabaseVersion()
|
||||
|
|
|
@ -40,6 +40,7 @@ struct Operation {
|
|||
bool meta;
|
||||
bool _virtual;
|
||||
std::vector<int> childs;
|
||||
int tag;
|
||||
|
||||
bool operator == (int opId)
|
||||
{
|
||||
|
|
|
@ -149,6 +149,76 @@ void User::DeleteCategory(const Category& cat)
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -214,6 +284,11 @@ int User::GetCategoriesNumber()
|
|||
return _categories.size();
|
||||
}
|
||||
|
||||
int User::GetTagsNumber()
|
||||
{
|
||||
return _tags.size();
|
||||
}
|
||||
|
||||
int User::GetAccountsNumber()
|
||||
{
|
||||
return _accounts.size();
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <QFont>
|
||||
|
||||
#include "Category.hpp"
|
||||
#include "Tag.hpp"
|
||||
#include "Account.hpp"
|
||||
#include "Operation.hpp"
|
||||
#include "Database.hpp"
|
||||
|
@ -47,12 +48,14 @@ public:
|
|||
std::vector<Account> _accounts;
|
||||
std::map<unsigned int, std::map<unsigned int, std::vector<Operation> >* > _operations;
|
||||
std::vector<Category> _categories;
|
||||
std::vector<Tag> _tags;
|
||||
std::vector<QFont> _categoriesFonts;
|
||||
std::map<QString, QString> _preferences;
|
||||
std::map<QString, ImportPattern> _importPatterns;
|
||||
|
||||
class AccountNotFound {};
|
||||
class CategoryNotFound {};
|
||||
class TagNotFound {};
|
||||
|
||||
Category GetCategory(int catId);
|
||||
QString GetCategoryName(int catId);
|
||||
|
@ -61,6 +64,13 @@ public:
|
|||
void AddCategory(const Category& cat);
|
||||
void UpdateCategory(const Category& cat);
|
||||
void DeleteCategory(const Category& cat);
|
||||
|
||||
Tag GetTag(int tagId);
|
||||
QString GetTagName(int tagId);
|
||||
int GetTagId(const QString& tagName) throw (TagNotFound);
|
||||
void AddTag(const Tag& tag);
|
||||
void UpdateTag(const Tag& tag);
|
||||
void DeleteTag(const Tag& tag);
|
||||
|
||||
|
||||
Account GetAccount(int accountId) throw (AccountNotFound);
|
||||
|
@ -73,6 +83,7 @@ public:
|
|||
|
||||
|
||||
int GetCategoriesNumber();
|
||||
int GetTagsNumber();
|
||||
int GetAccountsNumber();
|
||||
int GetOperationsNumber(int month, int year);
|
||||
|
||||
|
|
|
@ -145,13 +145,38 @@ bool CSVExportEngine::SaveCategories()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CSVExportEngine::SaveTags()
|
||||
{
|
||||
Tag tag;
|
||||
std::map<int, int>::iterator it;
|
||||
QString v;
|
||||
|
||||
*_writer << "Tags" << endl << endl;
|
||||
*_writer << "id;name" << endl;
|
||||
|
||||
for(it=_tags.begin(); it!=_tags.end(); it++)
|
||||
{
|
||||
tag = _user->GetTag(it->first);
|
||||
|
||||
ESCAPE_CHARS(tag.name);
|
||||
|
||||
*_writer << QString::number(tag.id) << ";";
|
||||
*_writer << "\"" << tag.name << "\"" << ";";
|
||||
*_writer << endl;
|
||||
}
|
||||
|
||||
*_writer << endl << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVExportEngine::SaveOperations(std::vector<Operation>* operations)
|
||||
{
|
||||
std::vector<Operation>::iterator it;
|
||||
QString v;
|
||||
|
||||
*_writer << "Operations" << endl << endl;
|
||||
*_writer << "id;parent;day;month;year;amount;description;category;fix_cost;account;checked;transfert;formula;meta;virtual" << endl;
|
||||
*_writer << "id;parent;day;month;year;amount;description;category;fix_cost;account;checked;transfert;formula;meta;virtual;tag" << endl;
|
||||
|
||||
for(it=operations->begin(); it!=operations->end(); it++)
|
||||
{
|
||||
|
@ -172,6 +197,7 @@ bool CSVExportEngine::SaveOperations(std::vector<Operation>* operations)
|
|||
*_writer << it->formula << ";";
|
||||
*_writer << (it->meta ? "1" : "0") << ";";
|
||||
*_writer << (it->_virtual ? "1" : "0");
|
||||
*_writer << QString::number(it->tag) << ";";
|
||||
*_writer << endl;
|
||||
}
|
||||
|
||||
|
@ -202,6 +228,7 @@ bool CSVExportEngine::SaveFile(std::vector<Operation>* operations)
|
|||
SaveAccounts();
|
||||
SaveAccountAmounts();
|
||||
SaveCategories();
|
||||
SaveTags();
|
||||
SaveOperations(operations);
|
||||
|
||||
file.flush();
|
||||
|
|
|
@ -38,6 +38,7 @@ private:
|
|||
bool SaveAccounts();
|
||||
bool SaveAccountAmounts();
|
||||
bool SaveCategories();
|
||||
bool SaveTags();
|
||||
bool SaveOperations(std::vector<Operation>* operations);
|
||||
};
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ protected:
|
|||
|
||||
std::map<int, int> _accounts;
|
||||
std::map<int, int> _categories;
|
||||
std::map<int, int> _tags;
|
||||
std::map<AccountAmount, int, AccountAmount> _accountAmounts;
|
||||
};
|
||||
|
||||
|
|
|
@ -133,6 +133,27 @@ bool XMLExportEngine::SaveCategories()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool XMLExportEngine::SaveTags()
|
||||
{
|
||||
Tag tag;
|
||||
std::map<int, int>::iterator it;
|
||||
QString v;
|
||||
|
||||
for(it=_tags.begin(); it!=_tags.end(); it++)
|
||||
{
|
||||
tag = _user->GetTag(it->first);
|
||||
|
||||
ESCAPE_CHARS(tag.name);
|
||||
|
||||
_writer->writeStartElement("tag");
|
||||
_writer->writeAttribute("id", QString::number(tag.id));
|
||||
_writer->writeAttribute("name", tag.name);
|
||||
_writer->writeEndElement();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XMLExportEngine::SaveOperations(std::vector<Operation>* operations)
|
||||
{
|
||||
std::vector<Operation>::iterator it;
|
||||
|
@ -151,6 +172,7 @@ bool XMLExportEngine::SaveOperations(std::vector<Operation>* operations)
|
|||
_writer->writeAttribute("amount", v.sprintf("%d", it->amount));
|
||||
_writer->writeAttribute("description", it->description);
|
||||
_writer->writeAttribute("category", QString::number(it->category));
|
||||
_writer->writeAttribute("tag", QString::number(it->tag));
|
||||
_writer->writeAttribute("fix_cost", (it->fix_cost ? "1" : "0"));
|
||||
_writer->writeAttribute("account", QString::number(it->account));
|
||||
_writer->writeAttribute("checked", (it->checked ? "1" : "0"));
|
||||
|
@ -191,6 +213,7 @@ bool XMLExportEngine::SaveFile(std::vector<Operation>* operations)
|
|||
SaveAccounts();
|
||||
SaveAccountAmounts();
|
||||
SaveCategories();
|
||||
SaveTags();
|
||||
SaveOperations(operations);
|
||||
|
||||
_writer->writeEndElement();
|
||||
|
|
|
@ -38,6 +38,7 @@ private:
|
|||
bool SaveAccounts();
|
||||
bool SaveAccountAmounts();
|
||||
bool SaveCategories();
|
||||
bool SaveTags();
|
||||
bool SaveOperations(std::vector<Operation>* operations);
|
||||
};
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ void GrisbiImportEngine::LoadOperation(const QXmlAttributes& attrs)
|
|||
op.parent = 0;
|
||||
op.account = 0;
|
||||
op.category = 0;
|
||||
op.tag = 0;
|
||||
op.fix_cost = false;
|
||||
op.checked = false;
|
||||
op.transfert = 0;
|
||||
|
|
|
@ -196,6 +196,7 @@ void ImportEngine::ApplyPattern(ImportPattern& pattern, Operation& op)
|
|||
|
||||
op.account = pattern.account;
|
||||
op.category = pattern.category;
|
||||
op.tag = pattern.tag;
|
||||
|
||||
if (pattern.pattern == NULL_IMPORT_PATTERN) return;
|
||||
|
||||
|
@ -250,6 +251,7 @@ int ImportEngine::UpdatePattern(int pos)
|
|||
pattern.pattern = FindPattern(_descriptions[op.id], op.description);
|
||||
pattern.account = op.account;
|
||||
pattern.category = op.category;
|
||||
pattern.tag = op.tag;
|
||||
|
||||
_user->_importPatterns[key1] = pattern;
|
||||
|
||||
|
@ -281,6 +283,7 @@ void ImportEngine::MatchPattern(QString& originalKey, Operation& op)
|
|||
pattern.pattern = FindPattern(originalKey, op.description);
|
||||
pattern.account = op.account;
|
||||
pattern.category = op.category;
|
||||
pattern.tag = op.tag;
|
||||
|
||||
_user->_importPatterns[key1] = pattern;
|
||||
|
||||
|
@ -293,13 +296,14 @@ void ImportEngine::MatchPattern(QString& originalKey, Operation& op)
|
|||
}
|
||||
}
|
||||
|
||||
void ImportEngine::ParseFile(std::vector<Account>& accounts, std::vector<Category>& categories)
|
||||
void ImportEngine::ParseFile(std::vector<Account>& accounts, std::vector<Category>& categories, std::vector<Tag>& tags)
|
||||
{
|
||||
accounts = _unresolvedAccounts;
|
||||
categories = _unresolvedCategories;
|
||||
tags = _unresolvedTags;
|
||||
}
|
||||
|
||||
std::vector<Operation>* ImportEngine::GetOperations(std::map<int, int>& accounts, std::map<int, int>& categories)
|
||||
std::vector<Operation>* ImportEngine::GetOperations(std::map<int, int>& accounts, std::map<int, int>& categories, std::map<int, int>& tags)
|
||||
{
|
||||
int i;
|
||||
std::map<AccountAmount, int, AccountAmount>::iterator it;
|
||||
|
@ -320,6 +324,11 @@ std::vector<Operation>* ImportEngine::GetOperations(std::map<int, int>& accounts
|
|||
else
|
||||
_operations[i].category = _categories[_operations[i].category];
|
||||
|
||||
if (_tags[_operations[i].tag] < 0)
|
||||
_operations[i].tag = tags[_operations[i].tag];
|
||||
else
|
||||
_operations[i].tag = _tags[_operations[i].tag];
|
||||
|
||||
}
|
||||
|
||||
for(it=_accountAmounts.begin(); it!=_accountAmounts.end(); it++)
|
||||
|
|
|
@ -31,6 +31,7 @@ public:
|
|||
QString pattern;
|
||||
int account;
|
||||
int category;
|
||||
int tag;
|
||||
} ;
|
||||
|
||||
class ImportEngine {
|
||||
|
@ -50,10 +51,10 @@ public:
|
|||
virtual bool HandleFile(const QString& path, User* user, Database* db, KissCount* kiss)=0;
|
||||
|
||||
// Parse the file and return accounts that doesn't match
|
||||
virtual void ParseFile(std::vector<Account>& accounts, std::vector<Category>& categories);
|
||||
virtual void ParseFile(std::vector<Account>& accounts, std::vector<Category>& categories, std::vector<Tag>& tags);
|
||||
|
||||
// Final Step
|
||||
virtual std::vector<Operation>* GetOperations(std::map<int, int>& accounts, std::map<int, int>& categories);
|
||||
virtual std::vector<Operation>* GetOperations(std::map<int, int>& accounts, std::map<int, int>& categories, std::map<int, int>& tags);
|
||||
|
||||
const std::map<AccountAmount, int, AccountAmount>& GetAccountAmounts();
|
||||
|
||||
|
@ -73,8 +74,10 @@ protected:
|
|||
|
||||
std::map<int, int> _accounts;
|
||||
std::map<int, int> _categories;
|
||||
std::map<int, int> _tags;
|
||||
std::vector<Account> _unresolvedAccounts;
|
||||
std::vector<Category> _unresolvedCategories;
|
||||
std::vector<Tag> _unresolvedTags;
|
||||
std::vector<Operation> _operations;
|
||||
std::map<int, QString> _descriptions;
|
||||
std::map<AccountAmount, int, AccountAmount> _accountAmounts;
|
||||
|
|
|
@ -81,6 +81,7 @@ int OFXImportEngine::transaction_cb(const struct OfxTransactionData data, void *
|
|||
op.id = ++id;
|
||||
op.parent = 0;
|
||||
op.category = 0;
|
||||
op.tag = 0;
|
||||
op.fix_cost = false;
|
||||
op.account = _this->_curAccount;
|
||||
op.checked = false;
|
||||
|
|
|
@ -84,6 +84,9 @@ bool XMLImportEngine::startElement (const QString& namespaceURI, const QString&
|
|||
else if (qName == "category")
|
||||
LoadCategory(attrs);
|
||||
|
||||
else if (qName == "tag")
|
||||
LoadTag(attrs);
|
||||
|
||||
else if (qName == "operation")
|
||||
LoadOperation(attrs);
|
||||
else
|
||||
|
@ -201,6 +204,32 @@ void XMLImportEngine::LoadCategory(const QXmlAttributes& attrs)
|
|||
_unresolvedCategories.push_back(cat);
|
||||
}
|
||||
|
||||
void XMLImportEngine::LoadTag(const QXmlAttributes& attrs)
|
||||
{
|
||||
QString name;
|
||||
int id;
|
||||
Tag tag;
|
||||
static int unknownTag = 0;
|
||||
|
||||
tag.name = name = attrs.value("name");
|
||||
tag.id = id = attrs.value("id").toInt();
|
||||
|
||||
UNESCAPE_CHARS(tag.name);
|
||||
|
||||
try
|
||||
{
|
||||
int tagId = _user->GetTagId(name);
|
||||
|
||||
_tags[id] = tagId;
|
||||
return;
|
||||
}
|
||||
catch(User::TagNotFound e)
|
||||
{}
|
||||
|
||||
_tags[id] = --unknownTag;
|
||||
_unresolvedTags.push_back(tag);
|
||||
}
|
||||
|
||||
void XMLImportEngine::LoadOperation(const QXmlAttributes& attrs)
|
||||
{
|
||||
Operation op;
|
||||
|
@ -213,6 +242,7 @@ void XMLImportEngine::LoadOperation(const QXmlAttributes& attrs)
|
|||
op.amount = attrs.value("amount").toInt();
|
||||
op.description = attrs.value("description");
|
||||
op.category = attrs.value("category").toInt();
|
||||
op.tag = attrs.value("tag").toInt();
|
||||
op.fix_cost = (attrs.value("fix_cost") == "1");
|
||||
op.account = attrs.value("account").toInt();
|
||||
op.checked = (attrs.value("checked") == "1");
|
||||
|
|
|
@ -40,6 +40,7 @@ private:
|
|||
void LoadAccount(const QXmlAttributes& atts);
|
||||
void LoadAccountAmount(const QXmlAttributes& atts);
|
||||
void LoadCategory(const QXmlAttributes& atts);
|
||||
void LoadTag(const QXmlAttributes& atts);
|
||||
void LoadOperation(const QXmlAttributes& atts);
|
||||
};
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ void AccountPanel::Init(KissCount* kiss, wxUI *parent, int curMode)
|
|||
User* user = _kiss->GetUser();
|
||||
std::vector<Account>::iterator accountIt;
|
||||
std::vector<Category>::iterator categoryIt;
|
||||
std::vector<Tag>::iterator tagIt;
|
||||
|
||||
_icons[KissPanel::LOW_RES_ICON] = USER_LOW_ICON;
|
||||
_icons[KissPanel::HIGH_RES_ICON] = USER_ICON;
|
||||
|
@ -92,6 +93,17 @@ void AccountPanel::Init(KissCount* kiss, wxUI *parent, int curMode)
|
|||
|
||||
_categoriesValues = new int[user->GetCategoriesNumber()];
|
||||
|
||||
_tags = new QString[user->GetTagsNumber()] ;
|
||||
for(i=0, tagIt = user->_tags.begin();
|
||||
tagIt != user->_tags.end();
|
||||
tagIt++, i++)
|
||||
{
|
||||
_tags[i] = _(tagIt->name.toStdString().c_str()) ;
|
||||
_tagsIndexes[tagIt->name] = i;
|
||||
}
|
||||
|
||||
_tagsValues = new int[user->GetTagsNumber()];
|
||||
|
||||
_grid = new GridAccount(_kiss, this, true, true, true);
|
||||
_grid->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
|
@ -179,6 +191,8 @@ AccountPanel::~AccountPanel()
|
|||
{
|
||||
delete[] _categoriesValues;
|
||||
delete[] _categories;
|
||||
delete[] _tagsValues;
|
||||
delete[] _tags;
|
||||
delete[] _accounts;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,11 +77,12 @@ private:
|
|||
GridAccount* _grid;
|
||||
QTableWidget* _accountsGrid, *_statsGrid;
|
||||
CostRepartitionBanner* _costRepartitionBanner;
|
||||
int *_categoriesValues;
|
||||
int *_categoriesValues, *_tagsValues;
|
||||
// wxRadioBox *_radioMode;
|
||||
std::map<QString, int> _categoriesIndexes;
|
||||
std::map<QString, int> _tagsIndexes;
|
||||
std::vector<Operation>* _curOperations;
|
||||
QString* _categories, *_accounts;
|
||||
QString* _categories, *_tags, *_accounts;
|
||||
std::map<int, int> _accountsInitValues;
|
||||
int _fixCosts;
|
||||
QRadioButton *_virtual, *_real, *_check;
|
||||
|
|
|
@ -32,6 +32,7 @@ ImportPanel::ImportPanel(KissCount* kiss, wxUI *parent, bool lowResolution) :
|
|||
QPushButton* buttonOpen;
|
||||
QGroupBox* staticAccount = new QGroupBox(_("Unresolved accounts"));
|
||||
QGroupBox* staticCategory = new QGroupBox(_("Unresolved categories"));
|
||||
QGroupBox* staticTag = new QGroupBox(_("Unresolved tags"));
|
||||
|
||||
_icons[KissPanel::LOW_RES_ICON] = IMPORT_LOW_ICON;
|
||||
_icons[KissPanel::HIGH_RES_ICON] = IMPORT_ICON;
|
||||
|
@ -76,6 +77,13 @@ ImportPanel::ImportPanel(KissCount* kiss, wxUI *parent, bool lowResolution) :
|
|||
_categoriesGrid->setHorizontalHeaderLabels(labels);
|
||||
_categoriesGrid->resizeColumnsToContents();
|
||||
|
||||
_tagsGrid = new QTableWidget(0, 3);
|
||||
_tagsGrid->verticalHeader()->setHidden(true);
|
||||
labels.clear();
|
||||
labels << _("File tag") << _("Tag name") << _("Internal tag");
|
||||
_tagsGrid->setHorizontalHeaderLabels(labels);
|
||||
_tagsGrid->resizeColumnsToContents();
|
||||
|
||||
{
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(_accountsGrid);
|
||||
|
@ -90,7 +98,14 @@ ImportPanel::ImportPanel(KissCount* kiss, wxUI *parent, bool lowResolution) :
|
|||
staticCategory->setLayout(vbox);
|
||||
}
|
||||
|
||||
{
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(_tagsGrid);
|
||||
staticTag->setLayout(vbox);
|
||||
}
|
||||
|
||||
vbox2->addWidget(staticCategory);
|
||||
vbox2->addWidget(staticTag);
|
||||
|
||||
_operationsGrid = new GridAccount(kiss, this, false, false, false);
|
||||
connect(_operationsGrid, SIGNAL(cellChanged(int, int)), this, SLOT(OnOperationModified(int, int)));
|
||||
|
@ -145,6 +160,8 @@ void ImportPanel::ProcessFile()
|
|||
std::map<int, int> resolvedAccounts;
|
||||
QString* userCategories;
|
||||
std::map<int, int> resolvedCategories;
|
||||
QString* userTags;
|
||||
std::map<int, int> resolvedTags;
|
||||
QTableWidgetItem* item;
|
||||
|
||||
QString path = _fileTxt->text();
|
||||
|
@ -153,6 +170,7 @@ void ImportPanel::ProcessFile()
|
|||
_buttonIntegrate->setEnabled(false);
|
||||
_accountsGrid->setRowCount(0);
|
||||
_categoriesGrid->setRowCount(0);
|
||||
_tagsGrid->setRowCount(0);
|
||||
_operationsGrid->setRowCount(0);
|
||||
|
||||
_importEngine = _kiss->GetImportEngine(path);
|
||||
|
@ -163,7 +181,7 @@ void ImportPanel::ProcessFile()
|
|||
return ;
|
||||
}
|
||||
|
||||
_importEngine->ParseFile(_unresolvedAccounts, _unresolvedCategories);
|
||||
_importEngine->ParseFile(_unresolvedAccounts, _unresolvedCategories, _unresolvedTags);
|
||||
|
||||
if (_unresolvedAccounts.size())
|
||||
{
|
||||
|
@ -225,7 +243,37 @@ void ImportPanel::ProcessFile()
|
|||
_categoriesGrid->layout();
|
||||
}
|
||||
|
||||
if (!_unresolvedAccounts.size() && !_unresolvedCategories.size())
|
||||
if (_unresolvedTags.size())
|
||||
{
|
||||
int nb_tags = user->GetTagsNumber();
|
||||
userTags = new QString[nb_tags+1];
|
||||
|
||||
userTags[0] = _("Create one");
|
||||
|
||||
for(i=0; i<nb_tags; i++)
|
||||
userTags[i+1] = user->_tags[i].name;
|
||||
|
||||
ChoiceDelegate* tagEditor = new ChoiceDelegate(this, userTags, nb_tags+1);
|
||||
_tagsGrid->setItemDelegateForColumn(2, tagEditor);
|
||||
|
||||
_buttonLoadOperations->setEnabled(true);
|
||||
|
||||
_tagsGrid->setRowCount(_unresolvedTags.size());
|
||||
|
||||
for (i=0; i<(int)_unresolvedTags.size(); i++)
|
||||
{
|
||||
item = new QTableWidgetItem(_unresolvedTags[i].name);
|
||||
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
|
||||
_tagsGrid->setItem(i, 0, item);
|
||||
_tagsGrid->setItem(i, 1, new QTableWidgetItem(""));
|
||||
_tagsGrid->setItem(i, 2, new QTableWidgetItem(userTags[0]));
|
||||
}
|
||||
|
||||
_tagsGrid->resizeColumnsToContents();
|
||||
_tagsGrid->layout();
|
||||
}
|
||||
|
||||
if (!_unresolvedAccounts.size() && !_unresolvedCategories.size() && !_unresolvedTags.size())
|
||||
{
|
||||
OnLoadOperations();
|
||||
}
|
||||
|
@ -234,12 +282,14 @@ void ImportPanel::ProcessFile()
|
|||
|
||||
void ImportPanel::OnLoadOperations()
|
||||
{
|
||||
int i, nbAccounts=0, nbCategories=0;
|
||||
int i, nbAccounts=0, nbCategories=0, nbTags=0;
|
||||
User* user = _kiss->GetUser();
|
||||
Account account;
|
||||
Category category;
|
||||
Tag tag;
|
||||
std::map<int, int> accounts;
|
||||
std::map<int, int> categories;
|
||||
std::map<int, int> tags;
|
||||
int oldid;
|
||||
|
||||
for(i=0; i<_accountsGrid->rowCount(); i++)
|
||||
|
@ -264,7 +314,18 @@ void ImportPanel::OnLoadOperations()
|
|||
}
|
||||
}
|
||||
|
||||
if (nbAccounts || nbCategories)
|
||||
for(i=0; i<_tagsGrid->rowCount(); i++)
|
||||
{
|
||||
if (_tagsGrid->item(i, 2)->text() == _("Create one"))
|
||||
nbTags++;
|
||||
else
|
||||
{
|
||||
oldid = _unresolvedTags[i].id;
|
||||
tags[oldid] = user->GetTagId(_tagsGrid->item(i, 2)->text());;
|
||||
}
|
||||
}
|
||||
|
||||
if (nbAccounts || nbCategories || nbTags)
|
||||