2010-07-10 16:34:30 +02:00
/*
2016-10-08 20:05:01 +02:00
Copyright 2010 - 2016 Grégory Soutadé
2010-07-10 16:34:30 +02:00
2010-08-26 21:28:15 +02:00
This file is part of KissCount .
2010-07-10 16:34:30 +02:00
2010-08-26 21:28:15 +02:00
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 .
2010-07-10 16:34:30 +02:00
2010-08-26 21:28:15 +02:00
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 .
2010-07-10 16:34:30 +02:00
2010-08-26 21:28:15 +02:00
You should have received a copy of the GNU General Public License
along with KissCount . If not , see < http : //www.gnu.org/licenses/>.
2010-07-10 16:34:30 +02:00
*/
2011-08-20 11:43:12 +02:00
# include <fstream>
2011-08-25 17:45:41 +02:00
# include <iostream>
2011-08-20 11:43:12 +02:00
2011-08-27 18:35:36 +02:00
# include <QString>
2011-08-25 17:45:41 +02:00
# include <QMessageBox>
# include <QSqlQuery>
# include <QSqlError>
# include <QVariant>
# include <QSqlRecord>
2012-06-07 21:20:27 +02:00
# include <QCryptographicHash>
2011-08-25 17:45:41 +02:00
2011-08-20 14:02:47 +02:00
# include "Database.hpp"
2010-05-14 15:04:01 +02:00
2010-09-08 11:02:03 +02:00
Database : : Database ( const char * filename , KissCount * kiss ) : _kiss ( kiss )
2010-05-14 15:04:01 +02:00
{
2010-08-26 21:28:15 +02:00
std : : ifstream bdd_file ;
2011-02-20 14:22:31 +01:00
2012-03-20 20:57:45 +01:00
QString sPath = GetDatabaseHome ( ) + GetDatabaseFile ( ) ;
2011-08-25 17:45:41 +02:00
_db = QSqlDatabase : : addDatabase ( " QSQLITE " ) ;
2010-05-14 15:04:01 +02:00
2010-08-26 21:28:15 +02:00
if ( filename )
2010-05-14 15:04:01 +02:00
{
2010-08-26 21:28:15 +02:00
bdd_file . open ( filename , std : : ifstream : : in ) ;
2010-08-22 16:35:12 +02:00
2010-08-26 21:28:15 +02:00
if ( ! bdd_file . good ( ) )
2010-08-22 16:35:12 +02:00
{
2012-03-20 20:57:45 +01:00
QMessageBox : : critical ( 0 , _ ( " Error " ) , _ ( " Unable to open database " ) ) ;
2010-08-26 21:28:15 +02:00
throw std : : string ( " Unable to open " ) + filename ;
2010-08-22 16:35:12 +02:00
}
2011-08-25 17:45:41 +02:00
_db . setDatabaseName ( filename ) ;
if ( ! _db . open ( ) )
2010-08-22 16:35:12 +02:00
{
2012-03-20 20:57:45 +01:00
QMessageBox : : critical ( 0 , _ ( " Error " ) , _ ( " Unable to open database " ) ) ;
2010-08-26 21:28:15 +02:00
throw std : : string ( " Unable to open " ) + filename ;
2010-08-22 16:35:12 +02:00
}
2010-05-14 15:04:01 +02:00
}
2010-08-26 21:28:15 +02:00
else
2010-08-22 16:35:12 +02:00
{
2010-08-26 21:28:15 +02:00
// If default BDD file, assume this can be the first load
2011-08-25 17:45:41 +02:00
bdd_file . open ( sPath . toStdString ( ) . c_str ( ) , std : : ifstream : : in ) ;
2010-05-14 15:04:01 +02:00
2010-08-26 21:28:15 +02:00
if ( ! bdd_file . good ( ) )
2010-08-22 16:35:12 +02:00
{
2010-08-26 21:28:15 +02:00
CreateDatabase ( ) ;
2010-08-22 16:35:12 +02:00
}
2010-08-26 21:28:15 +02:00
else
2010-08-22 16:35:12 +02:00
{
2011-08-25 17:45:41 +02:00
_db . setDatabaseName ( sPath ) ;
if ( ! _db . open ( ) )
2010-08-22 16:35:12 +02:00
{
2012-03-20 20:57:45 +01:00
QMessageBox : : critical ( 0 , _ ( " Error " ) , _ ( " Unable to open database " ) ) ;
2011-08-25 17:45:41 +02:00
throw std : : string ( " Unable to open " ) + sPath . toStdString ( ) ;
2010-08-22 16:35:12 +02:00
}
}
}
2010-08-26 21:28:15 +02:00
bdd_file . close ( ) ;
2011-02-13 19:30:12 +01:00
CheckDatabaseVersion ( ) ;
2010-05-14 15:04:01 +02:00
}
void Database : : CreateDatabase ( )
{
2011-08-25 17:45:41 +02:00
QFile init_script ( INIT_SCRIPT ) ;
2012-03-20 20:57:45 +01:00
QString sPath = GetDatabaseHome ( ) + GetDatabaseFile ( ) ;
QDir dirname ( GetDatabaseHome ( ) ) ;
2011-08-25 17:45:41 +02:00
QFile file ( sPath ) ;
2012-05-06 11:40:13 +02:00
QString message ;
2010-09-08 11:02:03 +02:00
2018-03-11 15:57:22 +01:00
message = _ ( " A new database will be created, continue ? " ) ;
2012-05-06 11:40:13 +02:00
if ( QMessageBox : : question ( 0 , " KissCount " , message , QMessageBox : : Yes | QMessageBox : : No ) = = QMessageBox : : No )
throw std : : string ( " Abort " ) ;
2010-05-14 15:04:01 +02:00
2011-08-25 17:45:41 +02:00
if ( ! init_script . exists ( ) | | ! init_script . open ( QIODevice : : ReadOnly | QIODevice : : Text ) )
2010-05-14 15:04:01 +02:00
{
2018-03-11 15:57:22 +01:00
QMessageBox : : critical ( 0 , _ ( " Error " ) , INIT_SCRIPT + _ ( " not found, aborting " ) ) ;
2010-08-26 21:28:15 +02:00
throw " init.sql not found, aborting " ;
2010-05-14 15:04:01 +02:00
}
2011-08-25 17:45:41 +02:00
if ( ! dirname . exists ( ) & & ! dirname . mkdir ( dirname . absolutePath ( ) ) )
2011-02-20 14:22:31 +01:00
{
2011-08-25 17:45:41 +02:00
QMessageBox : : critical ( 0 , _ ( " Error " ) , _ ( " Unable to Create " ) + dirname . absolutePath ( ) ) ;
throw std : : string ( " Unable to create " ) + dirname . absolutePath ( ) . toStdString ( ) ;
2011-02-20 14:22:31 +01:00
}
2011-08-25 17:45:41 +02:00
if ( ! file . exists ( ) & & ! file . open ( QIODevice : : WriteOnly | QIODevice : : Truncate ) )
2011-02-20 14:22:31 +01:00
{
2011-08-25 17:45:41 +02:00
QMessageBox : : critical ( 0 , _ ( " Error " ) , _ ( " Unable to Create " ) + QString ( sPath ) ) ;
throw std : : string ( " Unable to create " ) + sPath . toStdString ( ) ;
2011-02-20 14:22:31 +01:00
}
2011-08-25 17:45:41 +02:00
file . close ( ) ;
2010-05-14 15:04:01 +02:00
2011-08-25 17:45:41 +02:00
_db . setDatabaseName ( sPath ) ;
if ( ! _db . open ( ) )
2010-08-22 16:35:12 +02:00
{
2011-08-25 17:45:41 +02:00
QMessageBox : : critical ( 0 , _ ( " Error " ) , _ ( " Unable to open Database " ) ) ;
throw std : : string ( " Unable to open " ) + sPath . toStdString ( ) ;
2010-08-22 16:35:12 +02:00
}
2011-08-25 17:45:41 +02:00
while ( ! init_script . atEnd ( ) )
2010-05-14 15:04:01 +02:00
{
2012-04-26 20:45:01 +02:00
QByteArray line = init_script . readLine ( ) . trimmed ( ) ;
QSqlQuery query ;
2011-08-25 17:45:41 +02:00
if ( line . isEmpty ( ) | | line . startsWith ( " -- " ) ) continue ;
2012-04-26 20:45:01 +02:00
// if (!query.isValid())
// {
// std::cout << QString(line).toStdString() << " is invalid !\n" ;
// continue;
// }
2011-08-25 17:45:41 +02:00
2012-04-26 20:45:01 +02:00
if ( ! query . exec ( QString ( line ) ) )
2010-05-14 15:04:01 +02:00
{
2011-08-25 17:45:41 +02:00
QMessageBox : : critical ( 0 , _ ( " Error " ) , _ ( " Error creating original database " ) ) ;
init_script . close ( ) ;
file . remove ( ) ;
2012-04-26 20:45:01 +02:00
std : : cout < < QString ( line ) . toStdString ( ) < < " is invalid ! \n " ;
throw QString ( line ) ;
2010-05-14 15:04:01 +02:00
}
2011-08-25 17:45:41 +02:00
}
2010-05-14 15:04:01 +02:00
2010-08-26 21:28:15 +02:00
init_script . close ( ) ;
2010-05-14 15:04:01 +02:00
}
2010-06-27 21:39:49 +02:00
2011-08-25 17:45:41 +02:00
QString Database : : HashPassword ( const QString & password )
2010-06-27 21:39:49 +02:00
{
2012-06-07 21:20:27 +02:00
return QCryptographicHash : : hash ( password . toUtf8 ( ) , QCryptographicHash : : Sha1 ) . toHex ( ) ;
2010-06-27 21:39:49 +02:00
}
2011-08-27 18:35:36 +02:00
std : : list < QString > Database : : GetUsers ( )
2010-05-14 15:04:01 +02:00
{
2011-08-27 18:35:36 +02:00
std : : list < QString > res ;
QSqlQuery query ( _db ) ;
2010-05-15 11:21:42 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( QString ( " SELECT name FROM user ORDER BY name " ) , res ) ;
2010-05-14 15:04:01 +02:00
2011-08-25 17:45:41 +02:00
while ( query . next ( ) )
2011-08-27 18:35:36 +02:00
res . push_back ( query . value ( 0 ) . toString ( ) ) ;
2010-05-14 15:04:01 +02:00
2010-08-26 21:28:15 +02:00
return res ;
2010-05-14 15:04:01 +02:00
}
2011-08-25 17:45:41 +02:00
bool Database : : IsValidUser ( const QString & user , const QString & password )
2010-07-04 16:33:25 +02:00
{
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-05-14 15:04:01 +02:00
2016-10-08 20:05:01 +02:00
query . prepare ( " SELECT name FROM user WHERE name=:id AND password=:password " ) ;
query . bindValue ( " :id " , user ) ;
query . bindValue ( " :password " , HashPassword ( password ) ) ;
EXECUTE_PREPARED_SQL_QUERY ( false ) ;
2010-05-14 15:04:01 +02:00
2011-08-25 17:45:41 +02:00
return query . next ( ) ;
}
2010-05-14 15:04:01 +02:00
2011-08-25 17:45:41 +02:00
static inline void fillOperation ( Operation * op , const QSqlRecord & set )
{
op - > id = set . value ( " id " ) . toInt ( ) ;
op - > parent = set . value ( " parent " ) . toInt ( ) ;
op - > account = set . value ( " account " ) . toInt ( ) ;
op - > day = set . value ( " day " ) . toInt ( ) ;
op - > month = set . value ( " month " ) . toInt ( ) ;
op - > year = set . value ( " year " ) . toInt ( ) ;
2012-04-30 21:15:51 +02:00
op - > amount = set . value ( " amount " ) . toInt ( ) ;
2011-08-27 18:35:36 +02:00
op - > description = set . value ( " description " ) . toString ( ) ;
2011-08-25 17:45:41 +02:00
op - > category = set . value ( " category " ) . toInt ( ) ;
2014-11-10 11:54:28 +01:00
op - > tag = set . value ( " tag " ) . toInt ( ) ;
2011-08-25 17:45:41 +02:00
op - > fix_cost = set . value ( " fix_cost " ) . toBool ( ) ;
op - > checked = set . value ( " checked " ) . toBool ( ) ;
op - > transfert = set . value ( " transfert " ) . toInt ( ) ;
2011-08-27 18:35:36 +02:00
op - > formula = set . value ( " formula " ) . toString ( ) ;
2011-08-25 17:45:41 +02:00
op - > meta = set . value ( " meta " ) . toBool ( ) ;
op - > _virtual = set . value ( " virtual " ) . toBool ( ) ;
2010-05-14 15:04:01 +02:00
}
2010-05-15 11:21:42 +02:00
2011-08-25 17:45:41 +02:00
static inline void fillAccount ( Account * account , const QSqlRecord & set )
{
account - > id = set . value ( " id " ) . toInt ( ) ;
2011-08-27 18:35:36 +02:00
account - > name = set . value ( " name " ) . toString ( ) ;
account - > number = set . value ( " number " ) . toString ( ) ;
2011-08-25 17:45:41 +02:00
account - > shared = set . value ( " shared " ) . toBool ( ) ;
account - > blocked = set . value ( " blocked " ) . toBool ( ) ;
account - > _default = set . value ( " default_account " ) . toBool ( ) ;
account - > _virtual = set . value ( " virtual " ) . toBool ( ) ;
account - > is_owner = true ;
2012-02-01 12:43:43 +01:00
account - > hidden = set . value ( " hidden " ) . toBool ( ) ;
2017-10-13 15:30:18 +02:00
account - > start_date = set . value ( " start " ) . toDate ( ) ;
account - > end_date = set . value ( " end " ) . toDate ( ) ;
2011-08-25 17:45:41 +02:00
}
static inline void fillCategory ( Category * category , const QSqlRecord & set )
{
category - > id = set . value ( " id " ) . toInt ( ) ;
category - > parent = set . value ( " parent " ) . toInt ( ) ;
2011-08-27 18:35:36 +02:00
category - > name = set . value ( " name " ) . toString ( ) ;
2011-08-25 17:45:41 +02:00
category - > backcolor = QColor ( set . value ( " backcolor " ) . toString ( ) ) ;
category - > forecolor = QColor ( set . value ( " forecolor " ) . toString ( ) ) ;
2011-08-27 18:35:36 +02:00
category - > font = set . value ( " font " ) . toString ( ) ;
2011-08-25 17:45:41 +02:00
category - > fix_cost = set . value ( " fix_cost " ) . toBool ( ) ;
}
2014-11-10 11:54:28 +01:00
static inline void fillTag ( Tag * tag , const QSqlRecord & set )
{
tag - > id = set . value ( " id " ) . toInt ( ) ;
tag - > name = set . value ( " name " ) . toString ( ) ;
}
2011-08-27 18:35:36 +02:00
User * Database : : LoadUser ( const QString & name )
2010-05-15 11:21:42 +02:00
{
2010-08-26 21:28:15 +02:00
User * user ;
Account account ;
Category category ;
2014-11-10 11:54:28 +01:00
Tag tag ;
2011-03-23 20:35:29 +01:00
ImportPattern importPattern ;
2011-08-25 17:45:41 +02:00
QString req ;
QSqlRecord set ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-06-22 12:29:36 +02:00
2010-08-26 21:28:15 +02:00
std : : vector < Account > : : iterator it ;
2010-05-15 11:21:42 +02:00
2016-10-08 20:05:01 +02:00
query . prepare ( " SELECT * FROM user WHERE name=:name " ) ;
query . bindValue ( " :name " , name ) ;
EXECUTE_PREPARED_SQL_QUERY ( 0 ) ;
2010-05-15 11:21:42 +02:00
2011-08-25 17:45:41 +02:00
if ( ! query . next ( ) )
2011-08-14 17:47:16 +02:00
return 0 ;
2010-05-15 11:21:42 +02:00
2010-10-24 16:04:56 +02:00
user = new User ( this ) ;
2010-07-27 22:31:56 +02:00
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
user - > _id = set . value ( " id " ) . toInt ( ) ;
2011-08-27 18:35:36 +02:00
user - > _name = set . value ( " name " ) . toString ( ) ;
user - > _password = " " ; // Security reasons set.value("password").toString();
2010-05-15 11:21:42 +02:00
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-05-15 11:21:42 +02:00
2012-05-05 16:49:24 +02:00
req = QString ( " SELECT * FROM account WHERE user='%1' ORDER BY default_account DESC, hidden, blocked, virtual, name ASC " ) . arg ( user - > _id ) ;
2010-05-15 11:21:42 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY_WITH_CODE ( req , 0 , { delete user ; } , { delete user ; } ) ;
2010-05-15 11:21:42 +02:00
2011-08-25 17:45:41 +02:00
while ( query . next ( ) )
2010-05-15 11:21:42 +02:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
fillAccount ( & account , set ) ;
2010-10-20 20:54:23 +02:00
user - > _accounts . push_back ( account ) ;
}
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-10-20 20:54:23 +02:00
2012-05-05 16:49:24 +02:00
req = QString ( " SELECT * FROM account WHERE id IN (SELECT account FROM shared_account WHERE user='%1') ORDER BY default_account DESC, hidden, blocked, virtual, name ASC " ) . arg ( user - > _id ) ;
2010-10-20 20:54:23 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY_WITH_CODE ( req , 0 , { delete user ; } , { delete user ; } ) ;
while ( query . next ( ) )
2010-10-20 20:54:23 +02:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
fillAccount ( & account , set ) ;
2010-10-20 20:54:23 +02:00
account . is_owner = false ;
2010-08-26 21:28:15 +02:00
user - > _accounts . push_back ( account ) ;
2010-05-15 11:21:42 +02:00
}
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-05-15 11:21:42 +02:00
2010-08-26 21:28:15 +02:00
if ( ! user - > _accounts . empty ( ) )
2010-05-15 11:21:42 +02:00
{
2010-08-26 21:28:15 +02:00
it = user - > _accounts . begin ( ) ;
2011-08-25 17:45:41 +02:00
req = " SELECT DISTINCT year FROM operation WHERE account IN(' " + QString : : number ( it - > id ) ;
2010-08-26 21:28:15 +02:00
it + + ;
for ( ; it ! = user - > _accounts . end ( ) ; it + + )
2010-05-15 11:21:42 +02:00
{
2011-08-27 18:35:36 +02:00
req + = " ', ' " + QString : : number ( it - > id ) ;
2010-05-15 11:21:42 +02:00
}
2011-08-25 17:45:41 +02:00
req + = " ') " ;
req + = " OR user=' " + QString : : number ( user - > _id ) + " ' " ;
req + = " ORDER BY year ASC " ;
2010-05-15 11:21:42 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY_WITH_CODE ( req , 0 , { delete user ; } , { delete user ; } ) ;
2010-05-15 11:21:42 +02:00
2011-08-25 17:45:41 +02:00
while ( query . next ( ) )
2010-05-15 11:21:42 +02:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
user - > _operations [ set . value ( " year " ) . toInt ( ) ] = 0 ;
2010-05-15 11:21:42 +02:00
}
}
2011-08-25 17:45:41 +02:00
req = QString ( " SELECT * FROM category WHERE user='%1' ORDER BY fix_cost DESC, name ASC " ) . arg ( user - > _id ) ;
EXECUTE_SQL_QUERY_WITH_CODE ( req , 0 , { delete user ; } , { delete user ; } ) ;
2010-05-24 20:14:15 +02:00
2011-08-25 17:45:41 +02:00
while ( query . next ( ) )
2010-06-22 12:29:36 +02:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
fillCategory ( & category , set ) ;
2011-02-13 19:30:12 +01:00
user - > _categories . push_back ( category ) ;
user - > _categoriesFonts . push_back ( _kiss - > ExtractFont ( category . font ) ) ;
2010-06-22 12:29:36 +02:00
}
2010-05-24 20:14:15 +02:00
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-05-24 20:14:15 +02:00
2014-11-10 11:54:28 +01:00
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 ( ) ;
2011-08-25 17:45:41 +02:00
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 ; } ) ;
2010-06-16 17:29:07 +02:00
2011-08-25 17:45:41 +02:00
while ( query . next ( ) )
{
set = query . record ( ) ;
2011-08-27 18:35:36 +02:00
user - > _preferences [ set . value ( " name " ) . toString ( ) ] = set . value ( " value " ) . toString ( ) ;
2011-08-25 17:45:41 +02:00
}
2010-06-16 17:29:07 +02:00
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-06-16 17:29:07 +02:00
2011-08-25 17:45:41 +02:00
req = QString ( " SELECT * FROM import_pattern WHERE user='%1' " ) . arg ( user - > _id ) ;
EXECUTE_SQL_QUERY_WITH_CODE ( req , 0 , { delete user ; } , { delete user ; } ) ;
2011-03-23 20:35:29 +01:00
2011-08-25 17:45:41 +02:00
while ( query . next ( ) )
2011-03-23 20:35:29 +01:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
2011-08-27 18:35:36 +02:00
importPattern . pattern = set . value ( " pattern " ) . toString ( ) ;
2011-08-25 17:45:41 +02:00
importPattern . account = set . value ( " account " ) . toInt ( ) ;
importPattern . category = set . value ( " category " ) . toInt ( ) ;
2011-03-23 20:35:29 +01:00
2011-08-27 18:35:36 +02:00
user - > _importPatterns [ set . value ( " description " ) . toString ( ) ] = importPattern ;
2011-03-23 20:35:29 +01:00
}
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2011-03-23 20:35:29 +01:00
2010-08-26 21:28:15 +02:00
return user ;
2010-05-15 11:21:42 +02:00
}
2010-05-16 10:35:34 +02:00
void Database : : LoadYear ( User * user , int year )
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
QString req ;
2010-08-26 21:28:15 +02:00
std : : vector < Account > : : iterator it ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-05-16 10:35:34 +02:00
2011-08-14 17:47:16 +02:00
if ( user - > _operations [ year ] = = 0 )
2010-08-26 21:28:15 +02:00
user - > _operations [ year ] = new std : : map < unsigned int , std : : vector < Operation > > ( ) ;
2010-05-16 10:35:34 +02:00
2010-08-26 21:28:15 +02:00
if ( ! user - > _accounts . size ( ) ) return ;
2010-07-03 09:52:44 +02:00
2010-08-26 21:28:15 +02:00
it = user - > _accounts . begin ( ) ;
2011-08-25 17:45:41 +02:00
req = " SELECT * FROM operation WHERE (account IN(' " + QString : : number ( it - > id ) ;
2010-08-26 21:28:15 +02:00
it + + ;
for ( ; it ! = user - > _accounts . end ( ) ; it + + )
2010-05-16 10:35:34 +02:00
{
2011-08-25 17:45:41 +02:00
req + = " ', ' " + QString : : number ( it - > id ) ;
2010-05-16 10:35:34 +02:00
}
2011-08-25 17:45:41 +02:00
req + = " ') " ;
req + = " OR user=' " + QString : : number ( user - > _id ) + " ') " ;
req + = " AND year=' " + QString : : number ( year ) + " ' " ;
req + = " ORDER BY fix_cost DESC, year, month ASC, day " ;
req + = user - > _preferences [ " operation_order " ] ;
2010-05-16 10:35:34 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , ) ;
2010-05-16 10:35:34 +02:00
2011-08-25 17:45:41 +02:00
while ( query . next ( ) )
2010-05-16 10:35:34 +02:00
{
2010-08-26 21:28:15 +02:00
Operation op ;
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
fillOperation ( & op , set ) ;
2010-08-26 21:28:15 +02:00
( * user - > _operations [ op . year ] ) [ op . month ] . push_back ( op ) ;
2010-05-16 10:35:34 +02:00
}
2010-09-22 21:02:29 +02:00
user - > ResolveGroups ( year ) ;
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-05-16 10:35:34 +02:00
}
2010-06-02 22:14:11 +02:00
2013-02-17 18:58:32 +01:00
int Database : : GetAccountAmount ( int id , int month , int year , bool * had_value , bool create_if_not_exsits )
2010-06-02 22:14:11 +02:00
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
QString req ;
2012-04-30 21:15:51 +02:00
int res = 0 ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-06-02 22:14:11 +02:00
2011-09-13 21:39:22 +02:00
req = QString ( " SELECT amount FROM account_amount WHERE account='%1' AND month='%2' AND year='%3' " )
. arg ( QString : : number ( id ) , QString : : number ( month ) , QString : : number ( year ) ) ;
2010-06-02 22:14:11 +02:00
2012-04-30 21:15:51 +02:00
EXECUTE_SQL_QUERY ( req , 0 ) ;
2010-06-02 22:14:11 +02:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
2010-06-21 10:53:43 +02:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
2012-04-30 21:15:51 +02:00
res = set . value ( " amount " ) . toInt ( ) ;
2012-04-28 12:25:17 +02:00
if ( had_value )
* had_value = true ;
2010-06-21 10:53:43 +02:00
}
2011-08-25 17:45:41 +02:00
else
2012-04-28 12:25:17 +02:00
{
2013-02-17 18:58:32 +01:00
if ( create_if_not_exsits )
SetAccountAmount ( id , month , year , 0 ) ;
2012-04-28 12:25:17 +02:00
if ( had_value )
* had_value = false ;
}
2010-06-02 22:14:11 +02:00
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-06-02 22:14:11 +02:00
2010-08-26 21:28:15 +02:00
return res ;
2010-06-02 22:14:11 +02:00
}
2010-06-03 18:28:38 +02:00
2012-04-30 21:15:51 +02:00
int Database : : CalcAccountAmount ( int id , int month , int year , bool * had_values )
2011-01-29 20:53:44 +01:00
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
QString req ;
2012-04-30 21:15:51 +02:00
int res = 0 ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-01-29 20:53:44 +01:00
2011-09-13 21:39:22 +02:00
req = QString ( " SELECT SUM(id) AS id, SUM(amount) AS amount FROM operation WHERE account='%1' AND month='%2' AND year='%3' AND meta='0' " ) .
arg ( QString : : number ( id ) , QString : : number ( month ) , QString : : number ( year ) ) ;
2011-01-29 20:53:44 +01:00
2012-04-30 21:15:51 +02:00
EXECUTE_SQL_QUERY ( req , 0 ) ;
2011-01-29 20:53:44 +01:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
2011-01-29 20:53:44 +01:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
2012-04-30 21:15:51 +02:00
res = set . value ( " amount " ) . toInt ( ) ;
2011-01-29 20:53:44 +01:00
if ( had_values )
2011-08-25 17:45:41 +02:00
* had_values = set . value ( " id " ) . toInt ( ) > 0 ;
2011-01-29 20:53:44 +01:00
}
else
{
if ( had_values )
* had_values = false ;
}
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2011-01-29 20:53:44 +01:00
return res ;
}
2011-08-25 17:45:41 +02:00
bool Database : : GetOperation ( int id , Operation * op )
2010-08-21 09:25:35 +02:00
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
QString req ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-08-25 17:45:41 +02:00
2011-10-22 11:37:35 +02:00
req = QString ( " SELECT * FROM operation WHERE id='%1' " ) . arg ( QString : : number ( id ) ) ;
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , false ) ;
if ( ! query . next ( ) ) return false ;
set = query . record ( ) ;
fillOperation ( op , set ) ;
2010-08-26 21:28:15 +02:00
return true ;
2010-08-21 09:25:35 +02:00
}
2011-02-14 20:56:59 +01:00
void Database : : LinkOrUnlinkOperation ( User * user , Operation & op )
2010-08-21 09:25:35 +02:00
{
2010-08-26 21:28:15 +02:00
Operation linked ;
2012-05-12 09:56:33 +02:00
QString req , v ;
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
2011-02-14 20:56:59 +01:00
Account account , account2 ;
bool _virtual ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-08-21 09:25:35 +02:00
2017-10-05 19:05:55 +02:00
if ( op . meta ) return ;
2017-09-12 20:58:57 +02:00
account = user - > GetAccount ( op . account ) ;
2011-08-25 17:45:41 +02:00
if ( op . transfert )
2010-08-21 09:25:35 +02:00
{
2010-08-26 21:28:15 +02:00
// No one or not linked
2010-11-05 19:25:11 +01:00
if ( ! GetOperation ( op . transfert , & linked ) | | op . description ! = linked . description | | op . amount ! = - linked . amount | | op . account = = linked . account )
2010-08-21 09:25:35 +02:00
{
2017-09-12 20:58:57 +02:00
op . _virtual = account . _virtual ;
req = QString ( " UPDATE operation SET transfert='', virtual='%1' WHERE id='%2' " ) . arg ( op . _virtual ? " 1 " : " 0 " , op . id ) ;
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2011-08-25 17:45:41 +02:00
op . transfert = 0 ;
2010-08-26 21:28:15 +02:00
return ;
2010-08-21 09:25:35 +02:00
}
}
2010-08-26 21:28:15 +02:00
// Not Linked
else
2010-08-21 09:25:35 +02:00
{
2011-08-25 17:45:41 +02:00
req = QString ( " SELECT id FROM operation WHERE transfert='%1' " ) . arg ( op . id ) ;
2010-08-21 09:25:35 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , ) ;
2010-08-21 09:25:35 +02:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
2010-08-21 09:25:35 +02:00
{
2017-09-12 20:58:57 +02:00
op . _virtual = account . _virtual ;
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
2017-09-12 20:58:57 +02:00
req = QString ( " UPDATE operation SET transfert='', virtual='%1' WHERE id='%2' " ) . arg ( op . _virtual ? " 1 " : " 0 " , set . value ( " id " ) . toString ( ) ) ;
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-08-21 09:25:35 +02:00
}
2011-08-25 17:45:41 +02:00
else
query . clear ( ) ;
2010-08-21 09:25:35 +02:00
2011-08-27 18:35:36 +02:00
req = QString ( " SELECT id, account FROM operation WHERE description= \" %1 \" AND month='%2' AND year='%3' AND amount='%4' AND meta='0' AND account !='%5' AND transfert='' " )
2012-05-12 09:56:33 +02:00
. arg ( op . description , QString : : number ( op . month ) , QString : : number ( op . year ) , v . sprintf ( " %d " , - op . amount ) , QString : : number ( op . account ) ) ;
2010-08-21 09:25:35 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , ) ;
2010-08-21 09:25:35 +02:00
2010-08-26 21:28:15 +02:00
// Don't need to link
2017-10-05 19:05:55 +02:00
if ( ! query . next ( ) ) return ;
2011-08-25 17:45:41 +02:00
2017-10-05 19:05:55 +02:00
set = query . record ( ) ;
2010-08-21 09:25:35 +02:00
2010-08-26 21:28:15 +02:00
// Link
2017-10-05 19:05:55 +02:00
linked . id = set . value ( " id " ) . toInt ( ) ;
2010-08-21 09:25:35 +02:00
2010-08-26 21:28:15 +02:00
op . transfert = linked . id ;
2010-08-21 09:25:35 +02:00
2011-08-25 17:45:41 +02:00
account2 = user - > GetAccount ( set . value ( " account " ) . toInt ( ) ) ;
2011-02-14 20:56:59 +01:00
_virtual = account . _virtual | | account2 . _virtual ;
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2011-08-27 18:35:36 +02:00
req = QString ( " UPDATE operation SET transfert='%1', virtual='%2' WHERE id='%3' " )
. arg ( ( linked . id ) ? QString : : number ( linked . id ) : " " , QString : : number ( _virtual ) , QString : : number ( op . id ) ) ;
2011-02-14 20:56:59 +01:00
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-08-21 09:25:35 +02:00
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2011-08-27 18:35:36 +02:00
req = QString ( " UPDATE operation SET transfert='%1', virtual='%2' WHERE id='%3' " )
. arg ( ( op . id ) ? QString : : number ( op . id ) : " " , QString : : number ( _virtual ) , QString : : number ( linked . id ) ) ;
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2011-02-14 20:56:59 +01:00
op . _virtual = _virtual ;
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-08-21 09:25:35 +02:00
}
}
2011-07-04 20:23:00 +02:00
void Database : : UpdateOperation ( User * user , Operation & op , bool checkTransfert )
2010-06-03 18:28:38 +02:00
{
2012-05-12 09:56:33 +02:00
QString req , v ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-08-26 21:28:15 +02:00
2011-07-04 20:23:00 +02:00
if ( checkTransfert )
LinkOrUnlinkOperation ( user , op ) ;
2010-08-26 21:28:15 +02:00
2010-09-05 12:08:48 +02:00
ESCAPE_CHARS ( op . description ) ;
2016-10-08 20:05:01 +02:00
req = " UPDATE operation SET parent='%1', account='%2', year='%3', month='%4', day='%5', amount='%6', description=:description, category='%8', tag='%9' " ;
2011-08-27 18:35:36 +02:00
req = req . arg ( ( op . parent ) ? QString : : number ( op . parent ) : " " , QString : : number ( op . account ) , QString : : number ( op . year ) , QString : : number ( op . month ) ,
2016-10-08 20:05:01 +02:00
QString : : number ( op . day ) , v . sprintf ( " %d " , op . amount ) , QString : : number ( op . category ) , QString : : number ( op . tag ) ) ;
req + = " , fix_cost='%1', checked='%2', transfert='%3', meta='%4', virtual='%5', formula=:formula WHERE id='%7' " ;
2011-08-27 18:35:36 +02:00
req = req . arg ( QString : : number ( op . fix_cost ) , QString : : number ( op . checked ) , ( op . transfert ) ? QString : : number ( op . transfert ) : " " ,
2016-10-08 20:05:01 +02:00
QString : : number ( op . meta ) , QString : : number ( op . _virtual ) , QString : : number ( op . id ) ) ;
2010-08-26 21:28:15 +02:00
2016-10-08 20:05:01 +02:00
query . prepare ( req ) ;
query . bindValue ( " :description " , op . description ) ;
query . bindValue ( " :formula " , op . formula ) ;
EXECUTE_PREPARED_SQL_UPDATE ( ) ;
2010-08-26 21:28:15 +02:00
2011-07-04 20:23:00 +02:00
if ( checkTransfert )
LinkOrUnlinkOperation ( user , op ) ;
2010-06-03 18:28:38 +02:00
}
2011-08-27 18:35:36 +02:00
int Database : : AddOperation ( User * user , Operation & op , bool checkTransfert )
2010-06-03 18:28:38 +02:00
{
2012-05-12 09:56:33 +02:00
QString req , v ;
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-08-26 21:28:15 +02:00
2011-10-22 11:37:35 +02:00
2010-09-05 12:08:48 +02:00
ESCAPE_CHARS ( op . description ) ;
2016-10-08 20:05:01 +02:00
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', :description " ;
2011-08-27 18:35:36 +02:00
req = req . arg ( QString : : number ( user - > _id ) , ( op . parent ) ? QString : : number ( op . parent ) : " " , QString : : number ( op . account ) , QString : : number ( op . year ) ,
2016-10-08 20:05:01 +02:00
QString : : number ( op . month ) , QString : : number ( op . day ) , v . sprintf ( " %d " , op . amount ) ) ;
req + = " , '%1', '%2', '%3', :formula, '%4', '%5', '%6', '%7') " ;
req = req . arg ( QString : : number ( op . category ) , QString : : number ( op . tag ) , QString : : number ( op . fix_cost ) , ( op . transfert ) ? QString : : number ( op . transfert ) : " " ,
2012-01-07 09:21:22 +01:00
QString : : number ( op . meta ) , QString : : number ( op . _virtual ) , QString : : number ( op . checked ) ) ;
2016-10-08 20:05:01 +02:00
query . prepare ( req ) ;
query . bindValue ( " :description " , op . description ) ;
query . bindValue ( " :formula " , op . formula ) ;
2010-06-03 18:28:38 +02:00
2016-10-08 20:05:01 +02:00
if ( ! query . exec ( ) )
2011-10-22 11:37:35 +02:00
{
QMessageBox : : critical ( 0 , _ ( " Error " ) , _ ( " Update failed ! \n " ) + req ) ;
return 0 ;
}
2010-08-26 21:28:15 +02:00
2011-08-25 17:45:41 +02:00
op . id = query . lastInsertId ( ) . toInt ( ) ;
2010-08-26 21:28:15 +02:00
2011-07-04 20:23:00 +02:00
if ( checkTransfert )
LinkOrUnlinkOperation ( user , op ) ;
2010-08-26 21:28:15 +02:00
2011-08-25 17:45:41 +02:00
return op . id ;
2010-06-03 18:28:38 +02:00
}
2011-02-14 20:56:59 +01:00
void Database : : DeleteOperation ( User * user , Operation & op )
2010-06-03 18:28:38 +02:00
{
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-08-25 17:45:41 +02:00
QString req = QString ( " DELETE FROM operation WHERE id='%1' " ) . arg ( op . id ) ;
2010-06-03 18:28:38 +02:00
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-08-21 09:25:35 +02:00
2011-02-14 20:56:59 +01:00
LinkOrUnlinkOperation ( user , op ) ;
2010-06-03 18:28:38 +02:00
}
2010-06-12 15:59:27 +02:00
2010-06-24 21:02:42 +02:00
void Database : : DeleteOperations ( User * user , int month , int year )
{
2011-08-25 17:45:41 +02:00
QString req ;
2010-08-26 21:28:15 +02:00
std : : vector < Account > : : iterator it ;
2010-07-04 16:33:25 +02:00
2010-08-26 21:28:15 +02:00
it = user - > _accounts . begin ( ) ;
2011-08-27 18:35:36 +02:00
req = " DELETE FROM account_amount WHERE account IN(' " + QString : : number ( it - > id ) ;
2010-08-26 21:28:15 +02:00
it + + ;
for ( ; it ! = user - > _accounts . end ( ) ; it + + )
2010-07-04 16:33:25 +02:00
{
2011-08-27 18:35:36 +02:00
req + = " ', ' " + QString : : number ( it - > id ) ;
2010-07-04 16:33:25 +02:00
}
2011-08-25 17:45:41 +02:00
req + = " ') " ;
2011-08-27 18:35:36 +02:00
req + = " AND year=' " + QString : : number ( year ) + " ' " ;
2010-08-26 21:28:15 +02:00
if ( month ! = - 1 )
2011-08-27 18:35:36 +02:00
req + = " AND month=' " + QString : : number ( month ) + " ' " ;
2010-07-04 16:33:25 +02:00
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-07-04 16:33:25 +02:00
2010-08-26 21:28:15 +02:00
it = user - > _accounts . begin ( ) ;
2011-10-31 10:24:05 +01:00
req = " DELETE FROM operation WHERE (account IN(' " + QString : : number ( it - > id ) ;
2010-08-26 21:28:15 +02:00
it + + ;
for ( ; it ! = user - > _accounts . end ( ) ; it + + )
2010-07-04 16:33:25 +02:00
{
2011-08-27 18:35:36 +02:00
req + = " ', ' " + QString : : number ( it - > id ) ;
2010-07-04 16:33:25 +02:00
}
2011-08-25 17:45:41 +02:00
req + = " ') " ;
2011-08-27 18:35:36 +02:00
req + = " OR user=' " + QString : : number ( user - > _id ) + " ') " ;
req + = " AND year=' " + QString : : number ( year ) + " ' " ;
2010-08-26 21:28:15 +02:00
if ( month ! = - 1 )
2011-08-27 18:35:36 +02:00
req + = " AND month=' " + QString : : number ( month ) + " ' " ;
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-10-24 16:04:56 +02:00
}
2011-08-25 17:45:41 +02:00
bool Database : : LoadOperation ( User * user , int id )
2010-10-24 16:04:56 +02:00
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
QString req ;
2010-10-24 16:04:56 +02:00
bool ret = false ;
std : : vector < Operation > : : iterator it ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
req = QString ( " SELECT * FROM operation WHERE id='%1' " ) . arg ( id ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , false ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
2010-10-24 16:04:56 +02:00
{
Operation op ;
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
fillOperation ( & op , set ) ;
2011-01-06 18:18:31 +01:00
2011-01-06 18:59:23 +01:00
if ( user - > _operations [ op . year ] )
2010-10-24 16:04:56 +02:00
{
2011-01-06 18:59:23 +01:00
for ( it = ( * user - > _operations [ op . year ] ) [ op . month ] . begin ( ) ;
it ! = ( * user - > _operations [ op . year ] ) [ op . month ] . end ( ) ;
it + + )
2010-10-24 16:04:56 +02:00
{
2011-01-06 18:59:23 +01:00
if ( ! op . fix_cost & & it - > fix_cost ) continue ;
if ( op . fix_cost & & ! it - > fix_cost )
{
it - - ;
break ;
}
if ( it - > day > op . day )
{
it - - ;
break ;
}
2010-10-24 16:04:56 +02:00
}
2011-01-06 18:59:23 +01:00
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 ;
2010-10-24 16:04:56 +02:00
}
}
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-10-24 16:04:56 +02:00
return ret ;
}
// We may not have access to all operations if we have a shared account
2012-04-30 21:15:51 +02:00
int Database : : MetaAmount ( int id )
2010-10-24 16:04:56 +02:00
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
QString req ;
2012-04-30 21:15:51 +02:00
int res = 0 ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
req = QString ( " SELECT SUM(amount) as amount FROM operation WHERE parent='%1' " ) . arg ( id ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , false ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
{
set = query . record ( ) ;
2012-04-30 21:15:51 +02:00
res = set . value ( " amount " ) . toInt ( ) ;
2011-08-25 17:45:41 +02:00
}
query . clear ( ) ;
2010-06-24 21:02:42 +02:00
2010-10-24 16:04:56 +02:00
return res ;
}
// Idem
2012-04-30 21:15:51 +02:00
int Database : : MetaPositiveAmount ( int id )
2010-10-24 16:04:56 +02:00
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
QString req ;
2012-04-30 21:15:51 +02:00
int res = 0 ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
req = QString ( " SELECT SUM(amount) as amount FROM operation WHERE amount > 0 AND parent='%1' " ) . arg ( id ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , false ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
{
set = query . record ( ) ;
2012-04-30 21:15:51 +02:00
res = set . value ( " amount " ) . toInt ( ) ;
2011-08-25 17:45:41 +02:00
}
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-10-24 16:04:56 +02:00
return res ;
2010-06-24 21:02:42 +02:00
}
2012-04-30 21:15:51 +02:00
void Database : : SetAccountAmount ( int accountId , int month , int year , int amount )
2010-06-12 15:59:27 +02:00
{
2012-05-12 09:56:33 +02:00
QString req , v ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-08-25 17:45:41 +02:00
2012-04-28 12:25:17 +02:00
req = " INSERT or REPLACE INTO account_amount ('account', 'year', 'month', 'amount') VALUES ('%1', '%2', '%3', '%4') " ;
2012-05-12 09:56:33 +02:00
req = req . arg ( QString : : number ( accountId ) , QString : : number ( year ) , QString : : number ( month ) , v . sprintf ( " %d " , amount ) ) ;
2012-04-28 12:25:17 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-06-12 15:59:27 +02:00
}
2010-06-21 10:53:43 +02:00
2011-08-27 18:35:36 +02:00
int Database : : AddAccount ( User * user , Account & ac )
2010-06-21 10:53:43 +02:00
{
2011-08-25 17:45:41 +02:00
QString req ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2018-03-11 15:57:22 +01:00
int id ;
2011-08-25 17:45:41 +02:00
2018-03-11 15:57:22 +01:00
req = " INSERT INTO account ('user', 'name', 'number', 'shared', 'blocked', 'default_account', 'virtual', 'hidden') VALUES " ;
2012-02-01 12:43:43 +01:00
req + = " ('%1', '%2', '%3', '%4', '%5', '%6', '%7', '%8') " ;
2011-08-27 18:35:36 +02:00
req = req . arg ( QString : : number ( user - > _id ) , ac . name , ac . number , QString : : number ( ac . shared ) , QString : : number ( ac . blocked ) ,
2012-02-01 12:43:43 +01:00
QString : : number ( ac . _default ) , QString : : number ( ac . _virtual ) , QString : : number ( ac . hidden ) ) ;
2011-08-27 18:35:36 +02:00
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 ;
}
2010-06-21 13:02:02 +02:00
2018-03-11 15:57:22 +01:00
id = query . lastInsertId ( ) . toInt ( ) ;
req = " UPDATE account SET start='%1', end='%2' WHERE id='%3' " ;
req = req . arg ( ac . start_date . toString ( " yyyy-MM-dd " ) , ac . end_date . toString ( " yyyy-MM-dd " ) , QString : : number ( id ) ) ;
EXECUTE_SQL_UPDATE ( req , 0 ) ;
return id ;
2010-06-21 10:53:43 +02:00
}
2010-07-05 18:35:12 +02:00
void Database : : UpdateAccount ( Account & ac )
2010-06-21 10:53:43 +02:00
{
2011-08-25 17:45:41 +02:00
QString req ;
2012-02-01 12:43:43 +01:00
req = " UPDATE account SET name='%1', number='%2', shared='%3', blocked='%4', default_account='%5', virtual='%6', hidden='%7' WHERE id='%8' " ;
2011-08-27 18:35:36 +02:00
req = req . arg ( ac . name , ac . number , QString : : number ( ac . shared ) , QString : : number ( ac . blocked ) , QString : : number ( ac . _default ) ,
2012-02-01 12:43:43 +01:00
QString : : number ( ac . _virtual ) , QString : : number ( ac . hidden ) , QString : : number ( ac . id ) ) ;
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-10-20 20:54:23 +02:00
2017-10-13 15:30:18 +02:00
req = " UPDATE account SET start='%1', end='%2' WHERE id='%3' " ;
req = req . arg ( ac . start_date . toString ( " yyyy-MM-dd " ) , ac . end_date . toString ( " yyyy-MM-dd " ) ,
QString : : number ( ac . id ) ) ;
EXECUTE_SQL_UPDATE ( req , ) ;
2010-10-20 20:54:23 +02:00
if ( ! ac . shared & & ac . is_owner )
{
2011-08-25 17:45:41 +02:00
req = QString ( " DELETE FROM shared_account WHERE account='%1' " ) . arg ( ac . id ) ;
2010-10-20 20:54:23 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
}
2010-06-21 10:53:43 +02:00
}
2011-08-25 17:45:41 +02:00
void Database : : DeleteAccount ( User * user , Account & ac , int replacement )
2010-06-21 10:53:43 +02:00
{
2011-08-25 17:45:41 +02:00
QString req ;
2010-10-20 20:54:23 +02:00
if ( ac . is_owner )
{
if ( ac . shared )
{
2011-08-25 17:45:41 +02:00
req = QString ( " DELETE FROM shared_account WHERE account='%1' " ) . arg ( ac . id ) ;
2010-10-20 20:54:23 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
}
2011-08-25 17:45:41 +02:00
req = QString ( " DELETE FROM account WHERE id='%1' " ) . arg ( ac . id ) ;
2010-10-20 20:54:23 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
req = QString ( " DELETE FROM account_amount WHERE account='%1' " ) . arg ( ac . id ) ;
2010-10-24 16:04:56 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2011-02-08 21:17:35 +01:00
2011-08-27 18:35:36 +02:00
req = QString ( " UPDATE operation SET account='%1' WHERE account='%2' " ) . arg ( QString : : number ( replacement ) , QString : : number ( ac . id ) ) ;
2011-02-08 21:17:35 +01:00
// req += wxT(", transfert='0'");
EXECUTE_SQL_UPDATE ( req , ) ;
2010-10-20 20:54:23 +02:00
}
else
2010-10-24 16:04:56 +02:00
RemoveSharedAccount ( ac , user - > _id ) ;
}
2010-10-20 20:54:23 +02:00
2011-08-27 18:35:36 +02:00
void Database : : AddSharedAccount ( Account & ac , const QString & granted )
2010-10-24 16:04:56 +02:00
{
2011-08-25 17:45:41 +02:00
QString req ;
QSqlRecord set ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-08-25 17:45:41 +02:00
2016-10-08 20:05:01 +02:00
req = QString ( " SELECT id FROM user WHERE name=:name " ) ;
2011-08-25 17:45:41 +02:00
2016-10-08 20:05:01 +02:00
query . prepare ( req ) ;
query . bindValue ( " :name " , granted ) ;
EXECUTE_PREPARED_SQL_QUERY ( ) ;
2010-10-20 20:54:23 +02:00
2011-08-25 17:45:41 +02:00
query . next ( ) ;
2010-10-20 20:54:23 +02:00
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
2010-10-20 20:54:23 +02:00
2011-08-27 18:35:36 +02:00
req = QString ( " INSERT INTO shared_account ('account', 'user') VALUES ('%1', '%2') " ) . arg ( QString : : number ( ac . id ) , set . value ( " id " ) . toString ( ) ) ;
2010-10-24 16:04:56 +02:00
2011-12-18 13:51:04 +01:00
query . clear ( ) ;
2010-10-24 16:04:56 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
if ( ! ac . shared )
{
ac . shared = true ;
UpdateAccount ( ac ) ;
2010-10-20 20:54:23 +02:00
}
}
2011-08-27 18:35:36 +02:00
void Database : : RemoveSharedAccount ( Account & ac , int granted )
2010-10-20 20:54:23 +02:00
{
2011-08-25 17:45:41 +02:00
QString req ;
QSqlRecord set ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-10-20 20:54:23 +02:00
2011-08-27 18:35:36 +02:00
req = QString ( " DELETE FROM shared_account WHERE user='%1' AND account='%2' " ) . arg ( QString : : number ( granted ) , QString : : number ( ac . id ) ) ;
2010-06-21 10:53:43 +02:00
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
req = QString ( " SELECT COUNT(user) AS cnt FROM shared_account WHERE account='%1' " ) . arg ( ac . id ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
query . next ( ) ;
2011-08-27 18:35:36 +02:00
set = query . record ( ) ;
2011-08-25 17:45:41 +02:00
if ( ! set . value ( " cnt " ) . toInt ( ) )
2010-10-24 16:04:56 +02:00
{
ac . shared = false ;
UpdateAccount ( ac ) ;
}
2010-06-21 10:53:43 +02:00
}
2010-06-22 11:35:21 +02:00
2011-08-27 18:35:36 +02:00
int Database : : AddCategory ( User * user , Category & category )
2010-06-22 11:35:21 +02:00
{
2011-08-25 17:45:41 +02:00
QString req ;
2011-08-27 18:35:36 +02:00
QString backcolor , forecolor ;
QSqlQuery query ( _db ) ;
backcolor = " # " ;
backcolor + = QString : : number ( category . backcolor . red ( ) , 16 ) ;
backcolor + = QString : : number ( category . backcolor . green ( ) , 16 ) ;
backcolor + = QString : : number ( category . backcolor . blue ( ) , 16 ) ;
forecolor = " # " ;
forecolor + = QString : : number ( category . forecolor . red ( ) , 16 ) ;
forecolor + = QString : : number ( category . forecolor . green ( ) , 16 ) ;
forecolor + = QString : : number ( category . forecolor . blue ( ) , 16 ) ;
req = " INSERT INTO category ('user', 'parent', 'name', 'backcolor', 'forecolor', 'font', 'fix_cost') VALUES (' " ;
req + = QString : : number ( user - > _id ) + " ' " ;
req + = " , ' " + QString : : number ( category . parent ) + " ' " ;
2016-10-08 20:05:01 +02:00
req + = " , :name " ;
2011-08-25 17:45:41 +02:00
req + = " , ' " + backcolor + " ' " ;
req + = " , ' " + forecolor + " ' " ;
req + = " , ' " + category . font + " ' " ;
2011-02-13 19:30:12 +01:00
if ( category . fix_cost )
2011-08-25 17:45:41 +02:00
req + = " , '1' " ;
2011-02-13 19:30:12 +01:00
else
2011-08-25 17:45:41 +02:00
req + = " , '0' " ;
req + = " ) " ;
2016-10-08 20:05:01 +02:00
query . prepare ( req ) ;
query . bindValue ( " :name " , category . name ) ;
if ( ! query . exec ( ) )
2011-08-27 18:35:36 +02:00
{
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 ;
}
2010-06-22 12:29:36 +02:00
2011-08-27 18:35:36 +02:00
return query . lastInsertId ( ) . toInt ( ) ;
2010-06-22 11:35:21 +02:00
}
2010-07-05 18:35:12 +02:00
void Database : : UpdateCategory ( Category & category )
2010-06-22 11:35:21 +02:00
{
2012-04-28 12:25:17 +02:00
QString req , tmp ;
2011-08-27 18:35:36 +02:00
QString backcolor , forecolor ;
2016-10-08 20:05:01 +02:00
QSqlQuery query ( _db ) ;
2011-08-27 18:35:36 +02:00
backcolor = " # " ;
2012-04-28 12:25:17 +02:00
tmp = QString : : number ( category . backcolor . red ( ) , 16 ) ;
if ( tmp . length ( ) = = 1 ) tmp = " 0 " + tmp ;
backcolor + = tmp ;
tmp = QString : : number ( category . backcolor . green ( ) , 16 ) ;
if ( tmp . length ( ) = = 1 ) tmp = " 0 " + tmp ;
backcolor + = tmp ;
tmp = QString : : number ( category . backcolor . blue ( ) , 16 ) ;
if ( tmp . length ( ) = = 1 ) tmp = " 0 " + tmp ;
backcolor + = tmp ;
2011-08-27 18:35:36 +02:00
forecolor = " # " ;
2012-04-28 12:25:17 +02:00
tmp = QString : : number ( category . forecolor . red ( ) , 16 ) ;
if ( tmp . length ( ) = = 1 ) tmp = " 0 " + tmp ;
forecolor + = tmp ;
tmp = QString : : number ( category . forecolor . green ( ) , 16 ) ;
if ( tmp . length ( ) = = 1 ) tmp = " 0 " + tmp ;
forecolor + = tmp ;
tmp = QString : : number ( category . forecolor . blue ( ) , 16 ) ;
if ( tmp . length ( ) = = 1 ) tmp = " 0 " + tmp ;
forecolor + = tmp ;
2011-08-27 18:35:36 +02:00
req = " UPDATE category SET " ;
req + = " parent=' " + QString : : number ( category . parent ) + " ' " ;
2016-10-08 20:05:01 +02:00
req + = " , name=:name " ;
2011-08-27 18:35:36 +02:00
req + = " , backcolor=' " + backcolor + " ' " ;
req + = " , forecolor=' " + forecolor + " ' " ;
req + = " , font=' " + category . font + " ' " ;
2011-02-13 19:30:12 +01:00
if ( category . fix_cost )
2011-08-27 18:35:36 +02:00
req + = " , fix_cost='1' " ;
2011-02-13 19:30:12 +01:00
else
2011-08-27 18:35:36 +02:00
req + = " , fix_cost='0' " ;
req + = " WHERE id=' " + QString : : number ( category . id ) + " ' " ;
2010-08-26 21:28:15 +02:00
2016-10-08 20:05:01 +02:00
query . prepare ( req ) ;
query . bindValue ( " :name " , category . name ) ;
EXECUTE_PREPARED_SQL_UPDATE ( ) ;
2010-06-22 11:35:21 +02:00
}
2011-08-25 17:45:41 +02:00
void Database : : DeleteCategory ( User * user , Category & category , int replacement )
2010-06-22 11:35:21 +02:00
{
2011-08-25 17:45:41 +02:00
QString req ;
2010-06-24 21:02:42 +02:00
2011-08-25 17:45:41 +02:00
req = QString ( " DELETE FROM category WHERE id='%1' " ) . arg ( category . id ) ;
2010-06-22 11:35:21 +02:00
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-06-22 11:35:21 +02:00
2011-08-25 17:45:41 +02:00
req = QString ( " UPDATE category SET parent='' WHERE parent='%1' " ) . arg ( category . id ) ;
2010-06-22 11:35:21 +02:00
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2011-02-08 21:17:35 +01:00
2011-08-27 18:35:36 +02:00
req = QString ( " UPDATE operation SET category='%1' WHERE category='%2' AND user='%3' " )
. arg ( QString : : number ( replacement ) , QString : : number ( category . id ) , QString : : number ( user - > _id ) ) ;
2011-02-08 21:17:35 +01:00
EXECUTE_SQL_UPDATE ( req , ) ;
2011-02-09 20:50:21 +01:00
if ( replacement = = user - > _categories [ 0 ] . id )
{
2011-08-25 17:45:41 +02:00
req = QString ( " UPDATE operation SET fix_cost='1' WHERE category='%1' " ) . arg ( replacement ) ;
2011-02-09 20:50:21 +01:00
EXECUTE_SQL_UPDATE ( req , ) ;
}
2010-06-22 11:35:21 +02:00
}
2010-06-23 14:25:00 +02:00
2011-08-27 18:35:36 +02:00
bool Database : : LoadCategory ( int id , const QString & name , Category & category )
2010-10-24 16:04:56 +02:00
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
QString req ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-10-24 16:04:56 +02:00
bool ret = false ;
2011-08-25 17:45:41 +02:00
if ( id )
2016-10-08 20:05:01 +02:00
{
2011-08-25 17:45:41 +02:00
req = QString ( " SELECT * FROM category WHERE id='%1' " ) . arg ( id ) ;
2016-10-08 20:05:01 +02:00
EXECUTE_SQL_QUERY ( req , false ) ;
}
2010-10-24 16:04:56 +02:00
else
2016-10-08 20:05:01 +02:00
{
req = QString ( " SELECT * FROM category WHERE name=:name " ) ;
query . prepare ( req ) ;
query . bindValue ( " :name " , name ) ;
EXECUTE_PREPARED_SQL_QUERY ( false ) ;
}
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
2010-10-24 16:04:56 +02:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
fillCategory ( & category , set ) ;
2010-10-24 16:04:56 +02:00
ret = true ;
}
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-10-24 16:04:56 +02:00
return ret ;
}
2014-11-10 11:54:28 +01:00
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 ) + " ' " ;
2016-10-08 20:05:01 +02:00
req + = " , :name " ;
2014-11-10 11:54:28 +01:00
req + = " ) " ;
2016-10-08 20:05:01 +02:00
query . prepare ( req ) ;
query . bindValue ( " :name " , tag . name ) ;
if ( ! query . exec ( ) )
2014-11-10 11:54:28 +01:00
{
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 ;
2016-10-08 20:05:01 +02:00
QSqlQuery query ( _db ) ;
2014-11-10 11:54:28 +01:00
req = " UPDATE tag SET " ;
2016-10-08 20:05:01 +02:00
req + = " name=:name " ;
2014-11-10 11:54:28 +01:00
req + = " WHERE id=' " + QString : : number ( tag . id ) + " ' " ;
2016-10-08 20:05:01 +02:00
query . prepare ( req ) ;
query . bindValue ( " :name " , tag . name ) ;
EXECUTE_PREPARED_SQL_UPDATE ( ) ;
2014-11-10 11:54:28 +01:00
}
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 )
2016-10-08 20:05:01 +02:00
{
2014-11-10 11:54:28 +01:00
req = QString ( " SELECT * FROM tag WHERE id='%1' " ) . arg ( id ) ;
2016-10-08 20:05:01 +02:00
EXECUTE_SQL_QUERY ( req , false ) ;
}
2014-11-10 11:54:28 +01:00
else
2016-10-08 20:05:01 +02:00
{
req = QString ( " SELECT * FROM tag WHERE name=:name " ) ;
query . prepare ( req ) ;
query . bindValue ( " :name " , name ) ;
EXECUTE_PREPARED_SQL_QUERY ( false ) ;
}
2014-11-10 11:54:28 +01:00
if ( query . next ( ) )
{
set = query . record ( ) ;
fillTag ( & tag , set ) ;
ret = true ;
}
query . clear ( ) ;
return ret ;
}
2010-06-23 14:25:00 +02:00
std : : map < int , std : : vector < int > > Database : : GetAllOperations ( User * user )
{
2011-08-25 17:45:41 +02:00
QString req , req2 , reqUnion ;
QSqlRecord set ;
2011-09-04 21:01:32 +02:00
QSqlQuery query ( _db ) , query2 ( _db ) ;
2010-08-26 21:28:15 +02:00
std : : vector < Account > : : iterator it ;
std : : map < int , std : : vector < int > > res ;
int year ;
2010-06-23 14:25:00 +02:00
2010-08-26 21:28:15 +02:00
if ( ! user - > _accounts . empty ( ) )
2010-06-23 14:25:00 +02:00
{
2010-08-26 21:28:15 +02:00
it = user - > _accounts . begin ( ) ;
2011-08-27 18:35:36 +02:00
req = " SELECT DISTINCT year FROM account_amount WHERE account IN(' " + QString : : number ( it - > id ) ;
2010-08-26 21:28:15 +02:00
it + + ;
for ( ; it ! = user - > _accounts . end ( ) ; it + + )
2010-06-23 14:25:00 +02:00
{
2011-08-27 18:35:36 +02:00
req + = " ', ' " + QString : : number ( it - > id ) ;
2010-06-23 14:25:00 +02:00
}
2011-08-25 17:45:41 +02:00
req + = " ') " ;
2010-06-23 14:25:00 +02:00
2010-08-26 21:28:15 +02:00
it = user - > _accounts . begin ( ) ;
2011-08-27 18:35:36 +02:00
req2 = " SELECT DISTINCT year FROM operation WHERE account IN(' " + QString : : number ( it - > id ) ;
2010-08-26 21:28:15 +02:00
it + + ;
for ( ; it ! = user - > _accounts . end ( ) ; it + + )
2010-07-03 12:22:46 +02:00
{
2011-08-27 18:35:36 +02:00
req2 + = " ', ' " + QString : : number ( it - > id ) ;
2010-07-03 12:22:46 +02:00
}
2011-08-25 17:45:41 +02:00
req2 + = " ') " ;
2011-08-27 18:35:36 +02:00
req2 + = " OR user=' " + QString : : number ( user - > _id ) + " ' " ;
2011-08-25 17:45:41 +02:00
req2 + = " ORDER BY year ASC " ;
2010-07-03 12:22:46 +02:00
2011-08-25 17:45:41 +02:00
reqUnion = req + " UNION " + req2 ;
EXECUTE_SQL_QUERY ( reqUnion , res ) ;
2010-06-23 14:25:00 +02:00
2011-09-04 21:01:32 +02:00
query2 = query ;
while ( query2 . next ( ) )
2010-06-23 14:25:00 +02:00
{
2011-09-04 21:01:32 +02:00
set = query2 . record ( ) ;
2011-08-25 17:45:41 +02:00
year = set . value ( " year " ) . toInt ( ) ;
2010-06-23 14:25:00 +02:00
2010-08-26 21:28:15 +02:00
it = user - > _accounts . begin ( ) ;
2011-08-27 18:35:36 +02:00
req = " SELECT DISTINCT month FROM account_amount WHERE account IN(' " + QString : : number ( it - > id ) ;
2010-08-26 21:28:15 +02:00
it + + ;
for ( ; it ! = user - > _accounts . end ( ) ; it + + )
2010-06-23 14:25:00 +02:00
{
2011-08-27 18:35:36 +02:00
req + = " ', ' " + QString : : number ( it - > id ) ;
2010-06-23 14:25:00 +02:00
}
2011-08-25 17:45:41 +02:00
req + = " ') " ;
2011-08-27 18:35:36 +02:00
req + = " AND year=' " + QString : : number ( year ) + " ' " ;
2010-06-23 14:25:00 +02:00
2010-08-26 21:28:15 +02:00
it = user - > _accounts . begin ( ) ;
2011-08-27 18:35:36 +02:00
req2 = " SELECT DISTINCT month FROM operation WHERE (account IN(' " + QString : : number ( it - > id ) ;
2010-08-26 21:28:15 +02:00
it + + ;
for ( ; it ! = user - > _accounts . end ( ) ; it + + )
2010-07-03 12:22:46 +02:00
{
2011-08-27 18:35:36 +02:00
req2 + = " ', ' " + QString : : number ( it - > id ) ;
2010-07-03 12:22:46 +02:00
}
2011-08-25 17:45:41 +02:00
req2 + = " ') " ;
2011-08-27 18:35:36 +02:00
req2 + = " OR user=' " + QString : : number ( user - > _id ) + " ') " ;
req2 + = " AND year=' " + QString : : number ( year ) + " ' " ;
2011-08-25 17:45:41 +02:00
req2 + = " ORDER BY month ASC " ;
2010-07-03 12:22:46 +02:00
2011-08-25 17:45:41 +02:00
reqUnion = req + " UNION " + req2 ;
query . clear ( ) ;
2010-06-23 14:25:00 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( reqUnion , res ) ;
while ( query . next ( ) )
2010-06-23 14:25:00 +02:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
res [ year ] . push_back ( set . value ( " month " ) . toInt ( ) ) ;
2010-06-23 14:25:00 +02:00
}
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-06-23 14:25:00 +02:00
}
2011-09-04 21:01:32 +02:00
query2 . clear ( ) ;
2010-06-23 14:25:00 +02:00
}
2010-08-26 21:28:15 +02:00
return res ;
2010-06-23 14:25:00 +02:00
}
2010-06-23 19:32:42 +02:00
void Database : : GenerateMonth ( User * user , int monthFrom , int yearFrom , int monthTo , int yearTo )
{
2010-08-26 21:28:15 +02:00
std : : vector < Account > : : iterator it ;
2012-05-12 09:56:33 +02:00
QString req , v ;
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
2012-04-30 21:15:51 +02:00
int amount ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2010-06-23 19:32:42 +02:00
2010-08-26 21:28:15 +02:00
for ( it = user - > _accounts . begin ( ) ; it ! = user - > _accounts . end ( ) ; it + + )
2010-06-23 19:32:42 +02:00
{
2012-04-30 21:15:51 +02:00
amount = 0 ;
2011-08-25 17:45:41 +02:00
req = " SELECT SUM(amount) AS total FROM operation WHERE account='%1' AND year='%2' AND month='%3' AND meta='0' " ;
2011-08-27 18:35:36 +02:00
req = req . arg ( QString : : number ( it - > id ) , QString : : number ( yearFrom ) , QString : : number ( monthFrom ) ) ;
2010-06-23 19:32:42 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , ) ;
2010-06-23 19:32:42 +02:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
{
set = query . record ( ) ;
2012-04-30 21:15:51 +02:00
amount + = set . value ( " total " ) . toInt ( ) ;
2011-08-25 17:45:41 +02:00
}
2010-06-23 19:32:42 +02:00
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-06-23 19:32:42 +02:00
2011-08-25 17:45:41 +02:00
req = " SELECT amount FROM account_amount WHERE account='%1' AND year='%2' AND month='%3' " ;
2011-08-27 18:35:36 +02:00
req = req . arg ( QString : : number ( it - > id ) , QString : : number ( yearFrom ) , QString : : number ( monthFrom ) ) ;
2010-06-23 19:32:42 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , ) ;
2010-06-23 19:32:42 +02:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
{
set = query . record ( ) ;
2012-04-30 21:15:51 +02:00
amount + = set . value ( " amount " ) . toInt ( ) ;
2011-08-25 17:45:41 +02:00
}
query . clear ( ) ;
req = " INSERT INTO account_amount ('account', 'year', 'month', 'amount') VALUES " ;
req + = " ('%1', '%2', '%3', '%4') " ;
2012-05-12 09:56:33 +02:00
req = req . arg ( QString : : number ( it - > id ) , QString : : number ( yearTo ) , QString : : number ( monthTo ) , v . sprintf ( " %d " , amount ) ) ;
2010-06-23 19:32:42 +02:00
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-06-23 19:32:42 +02:00
}
}
2010-06-27 21:39:49 +02:00
2011-08-27 18:35:36 +02:00
void Database : : ChangePassword ( User * user , const QString & password )
2010-06-27 21:39:49 +02:00
{
2011-08-25 17:45:41 +02:00
QString req ;
2016-10-08 20:05:01 +02:00
QSqlQuery query ( _db ) ;
2010-06-27 21:39:49 +02:00
2016-10-08 20:05:01 +02:00
req = QString ( " UPDATE user SET password=:password WHERE name=:name " ) ;
2010-06-27 21:39:49 +02:00
2016-10-08 20:05:01 +02:00
query . prepare ( req ) ;
query . bindValue ( " :name " , user - > _name ) ;
query . bindValue ( " :password " , HashPassword ( password ) ) ;
EXECUTE_PREPARED_SQL_UPDATE ( ) ;
2010-06-27 21:39:49 +02:00
}
2011-08-27 18:35:36 +02:00
bool Database : : UserExists ( const QString & name )
2010-06-27 21:39:49 +02:00
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-08-25 17:45:41 +02:00
QString req ;
2010-08-26 21:28:15 +02:00
bool res = false ;
2010-06-27 21:39:49 +02:00
2016-10-08 20:05:01 +02:00
req = QString ( " SELECT name FROM user WHERE name=:name " ) ;
2010-06-27 21:39:49 +02:00
2016-10-08 20:05:01 +02:00
query . prepare ( req ) ;
query . bindValue ( " :name " , name ) ;
EXECUTE_PREPARED_SQL_QUERY ( false ) ;
2010-06-27 21:39:49 +02:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
2010-08-26 21:28:15 +02:00
res = true ;
else
res = false ;
2010-06-27 21:39:49 +02:00
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-06-27 21:39:49 +02:00
2010-08-26 21:28:15 +02:00
return res ;
2010-06-27 21:39:49 +02:00
}
2011-08-27 18:35:36 +02:00
void Database : : ChangeName ( User * user , const QString & name )
2010-06-27 21:39:49 +02:00
{
2011-08-25 17:45:41 +02:00
QString req ;
2016-10-08 20:05:01 +02:00
QSqlQuery query ( _db ) ;
2010-06-27 21:39:49 +02:00
2016-10-08 20:05:01 +02:00
req = QString ( " UPDATE user SET name=:name WHERE name=:name2 " ) ;
2010-06-27 21:39:49 +02:00
2016-10-08 20:05:01 +02:00
query . prepare ( req ) ;
query . bindValue ( " :name " , name ) ;
query . bindValue ( " :name2 " , user - > _name ) ;
EXECUTE_PREPARED_SQL_UPDATE ( ) ;
2010-06-27 21:39:49 +02:00
}
2011-08-27 18:35:36 +02:00
void Database : : NewUser ( const QString & name )
2010-06-27 21:39:49 +02:00
{
2011-08-25 17:45:41 +02:00
QString req ;
2016-10-08 20:05:01 +02:00
QSqlQuery query ( _db ) ;
2010-06-27 21:39:49 +02:00
2016-10-08 20:05:01 +02:00
req = QString ( " INSERT INTO user ('name', 'password') VALUES (:name, :password) " ) ;
2010-06-27 21:39:49 +02:00
2016-10-08 20:05:01 +02:00
query . prepare ( req ) ;
query . bindValue ( " :name " , name ) ;
query . bindValue ( " :password " , HashPassword ( " " ) ) ;
EXECUTE_PREPARED_SQL_UPDATE ( ) ;
2010-06-27 21:39:49 +02:00
}
2010-07-03 11:03:36 +02:00
/*
Shared accounts not currently supported
2010-07-04 16:33:25 +02:00
*/
2010-06-27 21:39:49 +02:00
void Database : : KillMe ( User * user )
{
2011-08-25 17:45:41 +02:00
QString req ;
2010-08-26 21:28:15 +02:00
std : : vector < Account > : : iterator it ;
2010-06-27 21:39:49 +02:00
2011-08-25 17:45:41 +02:00
req = QString ( " DELETE FROM preference WHERE user='%1' " ) . arg ( user - > _id ) ;
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-06-27 21:39:49 +02:00
2010-08-26 21:28:15 +02:00
if ( ! user - > _accounts . empty ( ) )
2010-06-27 21:39:49 +02:00
{
2010-10-24 16:04:56 +02:00
for ( it = user - > _accounts . begin ( ) ; it ! = user - > _accounts . end ( ) ; it + + )
2011-08-25 17:45:41 +02:00
DeleteAccount ( user , * it , 0 ) ;
2010-06-27 21:39:49 +02:00
2010-08-26 21:28:15 +02:00
it = user - > _accounts . begin ( ) ;
2010-10-24 16:04:56 +02:00
if ( it - > is_owner )
2011-08-27 18:35:36 +02:00
req = " DELETE FROM operation WHERE account IN(' " + QString : : number ( it - > id ) ;
2010-10-24 16:04:56 +02:00
else
2011-08-27 18:35:36 +02:00
req = " DELETE FROM operation WHERE account IN('-1 " ;
2010-08-26 21:28:15 +02:00
it + + ;
for ( ; it ! = user - > _accounts . end ( ) ; it + + )
2010-06-27 21:39:49 +02:00
{
2010-10-24 16:04:56 +02:00
if ( it - > is_owner )
2011-08-27 18:35:36 +02:00
req + = " ', ' " + QString : : number ( it - > id ) ;
2010-06-27 21:39:49 +02:00
}
2011-08-25 17:45:41 +02:00
req + = " ') " ;
2011-08-27 18:35:36 +02:00
req + = " OR (user=' " + QString : : number ( user - > _id ) + " ' AND account='') " ;
2010-06-27 21:39:49 +02:00
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-06-27 21:39:49 +02:00
}
2011-08-25 17:45:41 +02:00
req = QString ( " DELETE FROM category WHERE user='%1' " ) . arg ( user - > _id ) ;
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-07-02 21:40:32 +02:00
2014-11-10 11:54:28 +01:00
req = QString ( " DELETE FROM tag WHERE user='%1' " ) . arg ( user - > _id ) ;
EXECUTE_SQL_UPDATE ( req , ) ;
2011-08-25 17:45:41 +02:00
req = QString ( " DELETE FROM user WHERE id='%1' " ) . arg ( user - > _id ) ;
2010-08-26 21:28:15 +02:00
EXECUTE_SQL_UPDATE ( req , ) ;
2010-06-27 21:39:49 +02:00
}
2010-07-07 21:04:38 +02:00
2011-08-27 18:35:36 +02:00
void Database : : UpdatePreference ( User * user , const QString & preference )
2010-07-07 21:04:38 +02:00
{
2011-08-25 17:45:41 +02:00
QString req ;
2011-08-27 18:35:36 +02:00
QString value = user - > _preferences [ preference ] ;
QSqlQuery query ( _db ) ;
2010-07-27 22:31:56 +02:00
2012-04-28 12:25:17 +02:00
req = " INSERT or REPLACE INTO preference ('user', 'name', 'value') VALUES ('%1', '%2', '%3') " ;
req = req . arg ( QString : : number ( user - > _id ) , preference , value ) ;
EXECUTE_SQL_UPDATE ( req , ) ;
2010-07-07 21:04:38 +02:00
}
2010-07-14 16:22:02 +02:00
2011-08-27 18:35:36 +02:00
std : : vector < Operation > * Database : : Search ( User * user , QString * description , QDate * dateFrom , QDate * dateTo ,
2012-04-30 21:15:51 +02:00
int * amountFrom , int * amountTo ,
2014-11-10 11:54:28 +01:00
std : : vector < int > categories , int types , std : : vector < int > accounts , bool wildcards , std : : vector < int > tags )
2010-07-14 16:22:02 +02:00
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2012-05-12 09:56:33 +02:00
QString req , v ;
2010-08-26 21:28:15 +02:00
bool firstCond = false ;
2011-08-27 18:35:36 +02:00
std : : vector < int > : : iterator it ;
2010-08-26 21:28:15 +02:00
std : : vector < Account > : : iterator accountIt ;
std : : vector < Operation > * res = new std : : vector < Operation > ;
2010-10-25 21:33:09 +02:00
int i ;
2011-08-25 17:45:41 +02:00
QString dayFrom , monthFrom , yearFrom ;
QString dayTo , monthTo , yearTo ;
QString desc ;
2010-08-21 09:54:04 +02:00
2010-08-26 21:28:15 +02:00
if ( dateFrom )
2010-08-21 09:54:04 +02:00
{
2011-08-27 18:35:36 +02:00
dayFrom = QString : : number ( dateFrom - > day ( ) - 1 ) ;
2013-01-17 20:22:42 +01:00
monthFrom = QString : : number ( dateFrom - > month ( ) - 1 ) ;
2011-08-27 18:35:36 +02:00
yearFrom = QString : : number ( dateFrom - > year ( ) ) ;
2010-08-21 09:54:04 +02:00
}
2010-08-26 21:28:15 +02:00
if ( dateTo )
2010-08-21 09:54:04 +02:00
{
2011-08-27 18:35:36 +02:00
dayTo = QString : : number ( dateTo - > day ( ) - 1 ) ;
2013-01-17 20:22:42 +01:00
monthTo = QString : : number ( dateTo - > month ( ) - 1 ) ;
2011-08-27 18:35:36 +02:00
yearTo = QString : : number ( dateTo - > year ( ) ) ;
2010-08-21 09:54:04 +02:00
}
2010-07-14 16:22:02 +02:00
2011-08-25 17:45:41 +02:00
req = " SELECT * from operation WHERE " ;
2010-07-14 16:22:02 +02:00
2010-08-26 21:28:15 +02:00
if ( description )
2010-07-14 16:22:02 +02:00
{
2010-09-05 12:08:48 +02:00
desc = * description ;
ESCAPE_CHARS ( desc ) ;
2010-08-29 09:29:34 +02:00
if ( wildcards )
2012-05-12 10:28:16 +02:00
req + = " UPPER(description) LIKE UPPER( \" % " + desc + " % \" ) " ;
2010-08-29 09:29:34 +02:00
else
2011-08-25 17:45:41 +02:00
req + = " description= \" " + desc + " \" " ;
2010-08-26 21:28:15 +02:00
firstCond = true ;
2010-07-14 16:22:02 +02:00
}
2010-08-26 21:28:15 +02:00
if ( dateFrom )
2010-07-14 16:22:02 +02:00
{
2011-08-25 17:45:41 +02:00
if ( firstCond ) req + = " AND " ; else firstCond = true ;
req + = " ( " ;
req + = " year >= " + yearFrom ;
req + = " AND (month > ' " + monthFrom + " ' OR (month == ' " + monthFrom + " ' AND day >= ' " + dayFrom + " ') " ;
req + = " OR (month < ' " + monthFrom + " ' AND year > ' " + yearFrom + " ')) " ;
req + = " ) " ;
2010-07-14 16:22:02 +02:00
}
2010-08-26 21:28:15 +02:00
if ( dateTo )
2010-07-14 16:22:02 +02:00
{
2011-08-25 17:45:41 +02:00
if ( firstCond ) req + = " AND " ; else firstCond = true ;
req + = " ( " ;
req + = " year <= " + yearTo ;
req + = " AND (month < ' " + monthTo + " ' OR (month == ' " + monthTo + " ' AND day <= ' " + dayTo + " ') " ;
req + = " OR (month > ' " + monthTo + " ' AND year < ' " + yearTo + " ')) " ;
req + = " ) " ;
2010-07-14 16:22:02 +02:00
}
2010-08-26 21:28:15 +02:00
if ( amountFrom )
2010-07-14 16:22:02 +02:00
{
2011-08-25 17:45:41 +02:00
if ( firstCond ) req + = " AND " ; else firstCond = true ;
2012-05-12 09:56:33 +02:00
req + = " ABS(amount) >= " + v . sprintf ( " %d " , * amountFrom ) ;
2010-07-14 16:22:02 +02:00
}
2010-08-26 21:28:15 +02:00
if ( amountTo )
2010-07-14 16:22:02 +02:00
{
2011-08-25 17:45:41 +02:00
if ( firstCond ) req + = " AND " ; else firstCond = true ;
2012-05-12 09:56:33 +02:00
req + = " ABS(amount) <= " + v . sprintf ( " %d " , * amountTo ) ;
2010-07-14 16:22:02 +02:00
}
2010-08-26 21:28:15 +02:00
if ( categories . size ( ) )
2010-07-14 16:22:02 +02:00
{
2011-08-25 17:45:41 +02:00
if ( firstCond ) req + = " AND " ; else firstCond = true ;
req + = " category IN (' " ;
2010-08-26 21:28:15 +02:00
it = categories . begin ( ) ;
2011-08-27 18:35:36 +02:00
req + = QString : : number ( * it ) ;
2010-08-26 21:28:15 +02:00
it + + ;
2010-07-14 16:22:02 +02:00
2010-08-26 21:28:15 +02:00
for ( ; it ! = categories . end ( ) ; it + + )
2011-08-27 18:35:36 +02:00
req + = " ', ' " + QString : : number ( * it ) ;
2010-07-14 16:22:02 +02:00
2011-08-25 17:45:41 +02:00
req + = " ') " ;
2010-07-14 16:22:02 +02:00
}
2014-11-10 11:54:28 +01:00
if ( tags . size ( ) )
{
if ( firstCond ) req + = " AND " ; else firstCond = true ;
2014-11-10 13:50:00 +01:00
req + = " tag IN (' " ;
2014-11-10 11:54:28 +01:00
it = tags . begin ( ) ;
req + = QString : : number ( * it ) ;
it + + ;
for ( ; it ! = tags . end ( ) ; it + + )
req + = " ', ' " + QString : : number ( * it ) ;
req + = " ') " ;
}
2010-12-01 20:30:34 +01:00
if ( types )
2010-10-30 21:00:18 +02:00
{
2011-08-27 18:35:36 +02:00
if ( ( ( types & Database : : FIX_OP ) & & ! ( types & Database : : NON_FIX_OP ) ) | |
( ! ( types & Database : : FIX_OP ) & & ( types & Database : : NON_FIX_OP ) ) )
2010-12-01 20:30:34 +01:00
{
2011-08-25 17:45:41 +02:00
if ( firstCond ) req + = " AND " ; else firstCond = true ;
2010-12-01 20:30:34 +01:00
2011-08-27 18:35:36 +02:00
if ( types & Database : : FIX_OP )
2011-08-25 17:45:41 +02:00
req + = " fix_cost='1' " ;
2010-12-01 20:30:34 +01:00
else
2011-08-25 17:45:41 +02:00
req + = " fix_cost='0' " ;
2010-12-01 20:30:34 +01:00
}
2011-08-27 18:35:36 +02:00
if ( ( ( types & Database : : CHECKED_OP ) & & ! ( types & Database : : NOT_CHECKED_OP ) ) | |
( ! ( types & Database : : CHECKED_OP ) & & ( types & Database : : NOT_CHECKED_OP ) ) )
2010-12-01 20:30:34 +01:00
{
2011-08-25 17:45:41 +02:00
if ( firstCond ) req + = " AND " ; else firstCond = true ;
2010-12-01 20:30:34 +01:00
2011-08-27 18:35:36 +02:00
if ( types & Database : : CHECKED_OP )
2011-08-25 17:45:41 +02:00
req + = " checked='1' " ;
2010-12-01 20:30:34 +01:00
else
2011-08-25 17:45:41 +02:00
req + = " checked='0' " ;
2010-12-01 20:30:34 +01:00
}
2010-10-30 21:00:18 +02:00
}
2010-10-30 20:52:53 +02:00
2011-08-25 17:45:41 +02:00
if ( firstCond ) req + = " AND " ; else firstCond = true ;
2010-10-30 20:52:53 +02:00
2010-08-26 21:28:15 +02:00
if ( accounts . size ( ) )
2010-07-14 16:22:02 +02:00
{
2011-08-25 17:45:41 +02:00
req + = " (account IN (' " ;
2010-08-26 21:28:15 +02:00
it = accounts . begin ( ) ;
2011-08-27 18:35:36 +02:00
req + = QString : : number ( * it ) ;
2010-08-26 21:28:15 +02:00
it + + ;
2010-07-14 16:22:02 +02:00
2010-10-25 21:33:09 +02:00
for ( ; it ! = accounts . end ( ) ; it + + )
2011-08-27 18:35:36 +02:00
req + = " ', ' " + QString : : number ( * it ) ;
2010-07-14 16:22:02 +02:00
2011-08-25 17:45:41 +02:00
req + = " ')) " ;
// req += wxT(" OR user ='") + user->_id + "')";
2010-07-14 16:22:02 +02:00
}
2010-08-26 21:28:15 +02:00
else
2010-07-14 16:22:02 +02:00
{
2011-08-25 17:45:41 +02:00
req + = " (account IN (' " ;
2010-08-26 21:28:15 +02:00
accountIt = user - > _accounts . begin ( ) ;
2011-08-27 18:35:36 +02:00
req + = QString : : number ( accountIt - > id ) ;
2010-08-26 21:28:15 +02:00
accountIt + + ;
for ( ; accountIt ! = user - > _accounts . end ( ) ; accountIt + + )
2010-07-14 16:22:02 +02:00
{
2011-08-27 18:35:36 +02:00
req + = " ', ' " + QString : : number ( accountIt - > id ) ;
2010-07-14 16:22:02 +02:00
}
2011-08-25 17:45:41 +02:00
req + = " ') " ;
2011-08-27 18:35:36 +02:00
req + = " OR user =' " + QString : : number ( user - > _id ) + " ') " ;
2010-07-14 16:22:02 +02:00
}
2011-08-25 17:45:41 +02:00
req + = " ORDER BY year " ;
2011-08-27 18:35:36 +02:00
req + = user - > _preferences [ " operation_order " ] ;
req + = " , month " + user - > _preferences [ " operation_order " ] ;
req + = " , day " + user - > _preferences [ " operation_order " ] ;
2010-07-14 16:22:02 +02:00
2011-12-03 11:23:55 +01:00
// std::cout << req.toStdString() << "\n";
2010-07-14 16:22:02 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , res ) ;
2010-07-14 16:22:02 +02:00
2011-08-25 17:45:41 +02:00
while ( query . next ( ) )
2010-07-14 16:22:02 +02:00
{
2010-08-26 21:28:15 +02:00
Operation op ;
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
fillOperation ( & op , set ) ;
2010-08-26 21:28:15 +02:00
res - > push_back ( op ) ;
2010-07-14 16:22:02 +02:00
}
2010-10-25 21:33:09 +02:00
for ( i = 0 ; i < ( int ) res - > size ( ) ; i + + )
2011-08-25 17:45:41 +02:00
if ( ( * res ) [ i ] . parent )
2010-10-25 21:33:09 +02:00
user - > Group ( res , ( * res ) [ i ] ) ;
2010-08-26 21:28:15 +02:00
return res ;
2010-07-14 16:22:02 +02:00
}
2010-08-17 18:59:19 +02:00
2011-08-27 18:35:36 +02:00
void Database : : GetStats ( User * user , int monthFrom , int yearFrom , int monthTo ,
2012-04-30 21:15:51 +02:00
int yearTo , std : : map < int , std : : map < int , std : : map < int , int > > > * accountAmounts ,
2014-11-10 11:54:28 +01:00
std : : map < int , int > * categories , std : : map < int , int > * tags )
2010-08-17 18:59:19 +02:00
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-08-25 17:45:41 +02:00
QString req , req2 ;
2010-08-26 21:28:15 +02:00
std : : vector < Account > : : iterator accountIt ;
std : : vector < Category > : : iterator categoryIt ;
2014-11-10 11:54:28 +01:00
std : : vector < Tag > : : iterator tagIt ;
2010-08-17 18:59:19 +02:00
2010-08-26 21:28:15 +02:00
if ( ! user - > _accounts . empty ( ) )
2010-08-17 18:59:19 +02:00
{
2010-11-19 19:58:02 +01:00
if ( accountAmounts )
2010-08-17 18:59:19 +02:00
{
2010-11-19 19:58:02 +01:00
for ( accountIt = user - > _accounts . begin ( ) ; accountIt ! = user - > _accounts . end ( ) ; accountIt + + )
{
2011-08-27 18:35:36 +02:00
req = " SELECT month, year, amount FROM account_amount WHERE account =' " + QString : : number ( accountIt - > 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 ) + " ')) " ;
2010-08-17 18:59:19 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , ) ;
2010-08-17 18:59:19 +02:00
2011-08-25 17:45:41 +02:00
while ( query . next ( ) )
2010-11-19 19:58:02 +01:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
2012-04-30 21:15:51 +02:00
( * accountAmounts ) [ accountIt - > id ] [ set . value ( " year " ) . toInt ( ) ] [ set . value ( " month " ) . toInt ( ) ] = set . value ( " amount " ) . toInt ( ) ;
2010-11-19 19:58:02 +01:00
}
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-08-17 18:59:19 +02:00
}
}
2010-11-19 19:58:02 +01:00
if ( categories )
2010-08-17 18:59:19 +02:00
{
2010-11-19 19:58:02 +01:00
for ( categoryIt = user - > _categories . begin ( ) ; categoryIt ! = user - > _categories . end ( ) ; categoryIt + + )
2010-08-17 18:59:19 +02:00
{
2019-01-29 19:31:35 +01:00
if ( categoryIt - > id = = 1 )
req = " SELECT SUM(amount) as amount FROM operation AS o1 WHERE (category=' " + QString : : number ( categoryIt - > id ) + " ' OR fix_cost='1') " ;
else
req = " SELECT SUM(amount) as amount FROM operation AS o1 WHERE category=' " + QString : : number ( categoryIt - > id ) + " ' " ;
2010-11-19 19:58:02 +01:00
accountIt = user - > _accounts . begin ( ) ;
2011-08-27 18:35:36 +02:00
req + = " AND (account IN(' " + QString : : number ( accountIt - > id ) ;
2010-11-19 19:58:02 +01:00
accountIt + + ;
for ( ; accountIt ! = user - > _accounts . end ( ) ; accountIt + + )
{
2011-08-27 18:35:36 +02:00
req + = " ', ' " + QString : : number ( accountIt - > id ) ;
2010-11-19 19:58:02 +01:00
}
2011-08-25 17:45:41 +02:00
req + = " ') " ;
2011-08-27 18:35:36 +02:00
req + = " OR user=' " + QString : : number ( user - > _id ) + " ') " ;
2010-08-17 18:59:19 +02:00
2011-08-27 18:35:36 +02:00
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 ) + " ')) " ;
2011-08-25 17:45:41 +02:00
req + = " AND meta='0' " ;
2010-08-17 18:59:19 +02:00
2011-08-25 17:45:41 +02:00
req2 = req + " AND (transfert='' OR transfert IS 0) " ;
req2 + = " AND amount < 0 " ;
2010-11-01 11:34:39 +01:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req2 , ) ;
2010-11-19 19:58:02 +01:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
2010-11-19 19:58:02 +01:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
2012-04-30 21:15:51 +02:00
( * categories ) [ categoryIt - > id ] = - set . value ( " amount " ) . toInt ( ) ;
2010-11-19 19:58:02 +01:00
}
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-11-19 19:58:02 +01:00
// Transfert on blocked accounts must be computed
2011-08-25 17:45:41 +02:00
req2 = req + " AND transfert != '' " ;
req2 + = " AND (SELECT blocked FROM account WHERE id=o1.account) " ;
req2 + = " AND amount > 0 " ;
2010-11-19 19:58:02 +01:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req2 , ) ;
2010-08-17 18:59:19 +02:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
2010-11-19 19:58:02 +01:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
2012-04-30 21:15:51 +02:00
( * categories ) [ categoryIt - > id ] + = set . value ( " amount " ) . toInt ( ) ;
2010-11-19 19:58:02 +01:00
}
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-11-19 19:58:02 +01:00
}
}
2014-11-10 11:54:28 +01:00
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 ( ) ;
}
}
2010-11-19 19:58:02 +01:00
}
}
2011-08-27 18:35:36 +02:00
void Database : : GetMonthStats ( User * user , int month , int year , int nbDays ,
2017-10-29 18:21:54 +01:00
std : : map < int , std : : vector < int > > * operations ,
2014-11-10 11:54:28 +01:00
std : : map < int , int > * categories , std : : map < int , int > * tags )
2010-11-19 19:58:02 +01:00
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-08-25 17:45:41 +02:00
QString req ;
2010-11-19 19:58:02 +01:00
std : : vector < Account > : : iterator accountIt ;
int previous_amount , previous_day , cur_day ;
if ( ! user - > _accounts . empty ( ) )
{
for ( accountIt = user - > _accounts . begin ( ) ; accountIt ! = user - > _accounts . end ( ) ; accountIt + + )
{
2011-08-25 17:45:41 +02:00
req = " SELECT amount FROM account_amount WHERE account ='%1' AND year='%2' AND month='%3' " ;
2011-08-27 18:35:36 +02:00
req = req . arg ( QString : : number ( accountIt - > id ) , QString : : number ( year ) , QString : : number ( month ) ) ;
2010-11-19 19:58:02 +01:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , ) ;
2010-11-19 19:58:02 +01:00
2011-08-25 17:45:41 +02:00
while ( query . next ( ) )
2010-08-17 18:59:19 +02:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
2010-11-19 19:58:02 +01:00
( * operations ) [ accountIt - > id ] . clear ( ) ;
2012-04-30 21:15:51 +02:00
previous_amount = set . value ( " amount " ) . toInt ( ) ;
2010-08-17 18:59:19 +02:00
}
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-11-01 11:34:39 +01:00
2011-08-25 17:45:41 +02:00
req = " SELECT day, amount FROM operation WHERE account='%1' AND year='%2' AND month='%3' AND meta='0' ORDER BY day ASC " ;
2011-08-27 18:35:36 +02:00
req = req . arg ( QString : : number ( accountIt - > id ) , QString : : number ( year ) , QString : : number ( month ) ) ;
2010-11-01 11:34:39 +01:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , ) ;
2010-11-01 11:34:39 +01:00
2010-11-19 19:58:02 +01:00
cur_day = previous_day = - 1 ;
2011-08-25 17:45:41 +02:00
while ( query . next ( ) )
2010-11-01 11:34:39 +01:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
cur_day = set . value ( " day " ) . toInt ( ) ;
2010-11-19 19:58:02 +01:00
while ( cur_day ! = previous_day )
{
( * operations ) [ accountIt - > id ] . push_back ( previous_amount ) ;
previous_day + + ;
}
2012-04-30 21:15:51 +02:00
previous_amount + = set . value ( " amount " ) . toInt ( ) ;
2010-11-19 19:58:02 +01:00
( * operations ) [ accountIt - > id ] [ cur_day ] = previous_amount ;
}
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
2010-11-19 19:58:02 +01:00
while ( cur_day < nbDays )
{
( * operations ) [ accountIt - > id ] . push_back ( previous_amount ) ;
cur_day + + ;
2010-11-01 11:34:39 +01:00
}
2010-08-17 18:59:19 +02:00
}
}
2010-11-19 19:58:02 +01:00
// Fill categories
2014-11-10 11:54:28 +01:00
GetStats ( user , month , year , month , year , 0 , categories , tags ) ;
2010-08-17 18:59:19 +02:00
}
2010-08-21 11:49:03 +02:00
2012-04-30 21:15:51 +02:00
std : : map < int , int > * Database : : GetNotChecked ( User * user , int month , int year )
2010-08-21 11:49:03 +02:00
{
2010-10-24 16:04:56 +02:00
std : : vector < Account > : : iterator accountIt ;
2012-04-30 21:15:51 +02:00
std : : map < int , int > * res = new std : : map < int , int > ;
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-08-25 17:45:41 +02:00
QString req ;
2010-08-21 11:49:03 +02:00
2010-08-26 21:28:15 +02:00
for ( accountIt = user - > _accounts . begin ( ) ; accountIt ! = user - > _accounts . end ( ) ; accountIt + + )
2010-08-21 11:49:03 +02:00
{
2011-08-27 18:35:36 +02:00
req = " SELECT SUM(amount) AS amount FROM operation WHERE account=' " + QString : : number ( accountIt - > id ) + " ' " ;
2011-08-25 17:45:41 +02:00
req + = " AND checked='0' " ;
req + = " AND meta='0' " ;
2018-02-18 10:30:00 +01:00
req + = " AND virtual='0' " ;
2011-08-27 18:35:36 +02:00
req + = " AND (year < ' " + QString : : number ( year ) + " ' " ;
req + = " OR (year == ' " + QString : : number ( year ) + " ' " ;
req + = " AND month < ' " + QString : : number ( month ) + " ' " ;
2011-08-25 17:45:41 +02:00
req + = " )) " ;
EXECUTE_SQL_QUERY_WITH_CODE ( req , 0 , delete res , delete res ) ;
if ( query . next ( ) )
{
set = query . record ( ) ;
2012-04-30 21:15:51 +02:00
( * res ) [ accountIt - > id ] = set . value ( " amount " ) . toInt ( ) ;
2011-08-25 17:45:41 +02:00
}
query . clear ( ) ;
2010-08-21 11:49:03 +02:00
}
2011-02-14 20:56:59 +01:00
return res ;
}
2012-04-30 21:15:51 +02:00
std : : map < int , int > * Database : : GetVirtualAmount ( User * user , int month , int year )
2011-02-14 20:56:59 +01:00
{
std : : vector < Account > : : iterator accountIt ;
2012-04-30 21:15:51 +02:00
std : : map < int , int > * res = new std : : map < int , int > ;
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-08-25 17:45:41 +02:00
QString req ;
2011-02-14 20:56:59 +01:00
for ( accountIt = user - > _accounts . begin ( ) ; accountIt ! = user - > _accounts . end ( ) ; accountIt + + )
{
2011-08-27 18:35:36 +02:00
req = " SELECT SUM(amount) AS amount FROM operation WHERE account=' " + QString : : number ( accountIt - > id ) + " ' " ;
2011-08-25 17:45:41 +02:00
req + = " AND virtual='1' " ;
req + = " AND meta='0' " ;
2011-08-27 18:35:36 +02:00
req + = " AND (year < ' " + QString : : number ( year ) + " ' " ;
req + = " OR (year == ' " + QString : : number ( year ) + " ' " ;
req + = " AND month < ' " + QString : : number ( month ) + " ' " ;
2011-08-25 17:45:41 +02:00
req + = " )) " ;
EXECUTE_SQL_QUERY_WITH_CODE ( req , 0 , delete res , delete res ) ;
if ( query . next ( ) )
{
set = query . record ( ) ;
2012-04-30 21:15:51 +02:00
( * res ) [ accountIt - > id ] = set . value ( " amount " ) . toInt ( ) ;
2011-08-25 17:45:41 +02:00
}
query . clear ( ) ;
2011-02-14 20:56:59 +01:00
}
2010-08-26 21:28:15 +02:00
return res ;
2010-08-21 11:49:03 +02:00
}
2010-10-24 16:04:56 +02:00
2011-08-27 18:35:36 +02:00
std : : map < QString , QString > Database : : getSharedAccountOwners ( int account )
2010-10-24 16:04:56 +02:00
{
2011-08-27 18:35:36 +02:00
std : : map < QString , QString > res ;
2011-08-25 17:45:41 +02:00
QSqlRecord set , set2 ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-12-18 13:51:04 +01:00
QString req , user ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
req = QString ( " SELECT user FROM shared_account WHERE account='%1' " ) . arg ( account ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , res ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
while ( query . next ( ) )
2010-10-24 16:04:56 +02:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
2010-10-24 16:04:56 +02:00
2011-12-18 13:51:04 +01:00
user = set . value ( " user " ) . toString ( ) ;
2011-08-27 18:35:36 +02:00
req = QString ( " SELECT name FROM user WHERE id='%1' " ) . arg ( set . value ( " user " ) . toString ( ) ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
EXECUTE_SQL_QUERY ( req , res ) ;
2011-12-18 13:51:04 +01:00
if ( query . next ( ) )
{
set2 = query . record ( ) ;
2011-08-25 17:45:41 +02:00
2011-12-18 13:51:04 +01:00
res [ set2 . value ( " name " ) . toString ( ) ] = user ;
}
2010-10-24 16:04:56 +02:00
}
return res ;
}
2011-08-27 18:35:36 +02:00
QString Database : : getSharedAccountOwner ( int account )
2010-10-24 16:04:56 +02:00
{
2011-08-25 17:45:41 +02:00
QSqlRecord set ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-08-25 17:45:41 +02:00
QString req ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
req = QString ( " SELECT user FROM account WHERE id='%1' " ) . arg ( account ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
EXECUTE_SQL_QUERY ( req , " " ) ;
2010-10-24 16:04:56 +02:00
2011-08-25 17:45:41 +02:00
if ( query . next ( ) )
2010-10-24 16:04:56 +02:00
{
2011-08-25 17:45:41 +02:00
set = query . record ( ) ;
2011-08-27 18:35:36 +02:00
req = QString ( " SELECT name FROM user WHERE id='%1' " ) . arg ( set . value ( " user " ) . toString ( ) ) ;
2011-08-25 17:45:41 +02:00
query . clear ( ) ;
EXECUTE_SQL_QUERY ( req , " " ) ;
2010-10-24 16:04:56 +02:00
2011-12-18 13:51:04 +01:00
if ( query . next ( ) )
{
set = query . record ( ) ;
return set . value ( " name " ) . toString ( ) ;
}
2010-10-24 16:04:56 +02:00
}
2011-08-25 17:45:41 +02:00
return " " ;
2010-10-24 16:04:56 +02:00
}
2011-03-23 20:35:29 +01:00
void Database : : UpdateImportPattern ( User * user )
{
2011-08-27 18:35:36 +02:00
std : : map < QString , ImportPattern > : : iterator it ;
2011-08-25 17:45:41 +02:00
QString req , key ;
2011-08-27 18:35:36 +02:00
QSqlQuery query ( _db ) ;
2011-03-23 20:35:29 +01:00
for ( it = user - > _importPatterns . begin ( ) ;
it ! = user - > _importPatterns . end ( ) ;
it + + )
{
2011-08-16 18:22:35 +02:00
if ( it - > second . pattern = = ImportEngine : : NULL_IMPORT_PATTERN ) continue ;
2011-03-23 20:35:29 +01:00
key = ImportEngine : : RemoveUnused ( it - > first ) ;
2012-04-28 12:25:17 +02:00
req = " INSERT or REPLACE INTO import_pattern ('user', 'description', 'pattern', 'account', 'category') VALUES " ;
req + = " ('%1', '%2', '%3', '%4', '%5') " ;
req = req . arg ( QString : : number ( user - > _id ) , key , it - > second . pattern , QString : : number ( it - > second . account ) , QString : : number ( it - > second . category ) ) ;
EXECUTE_SQL_UPDATE ( req , ) ;
2011-03-23 20:35:29 +01:00
}
}
2012-02-26 21:16:45 +01:00
void Database : : GetHistory ( int month , int year , QStringList & list )
{
QSqlRecord set ;
QSqlQuery query ( _db ) ;
QString req ;
req = QString ( " SELECT DISTINCT description AS d FROM operation " ) ;
req + = " WHERE (year > ' " + QString : : number ( year ) + " ' OR (year == ' " + QString : : number ( year ) + " ' AND month >= ' " + QString : : number ( month ) + " ')) " ;
req + = " ORDER by description " ;
EXECUTE_SQL_QUERY ( req , ) ;
while ( query . next ( ) )
{
set = query . record ( ) ;
list < < set . value ( " d " ) . toString ( ) ;
}
}
2012-03-20 20:57:45 +01:00
bool Database : : ChangeDatabase ( QString filename )
{
QString oldFilename = _db . databaseName ( ) ;
_db . close ( ) ;
_db . setDatabaseName ( filename ) ;
if ( ! _db . open ( ) )
{
QMessageBox : : critical ( 0 , _ ( " Error " ) , _ ( " Unable to open database " ) ) ;
_db . setDatabaseName ( oldFilename ) ;
_db . open ( ) ;
return false ;
}
try {
CheckDatabaseVersion ( ) ;
}
catch ( . . . )
{
_db . setDatabaseName ( oldFilename ) ;
_db . open ( ) ;
return false ;
}
return true ;
}