1 /*
2  * Copyright 2000-2003  Michael Edwardes <mte@users.sourceforge.net>
3  * Copyright 2001-2002  Felix Rodriguez <frodriguez@users.sourceforge.net>
4  * Copyright 2002-2004  Kevin Tambascio <ktambascio@users.sourceforge.net>
5  * Copyright 2004-2005  Ace Jones <acejones@users.sourceforge.net>
6  * Copyright 2006-2018  Thomas Baumgart <tbaumgart@kde.org>
7  * Copyright 2006       Darren Gould <darren_gould@gmx.de>
8  * Copyright 2017-2018  Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #ifndef MYMONEYFILE_H
25 #define MYMONEYFILE_H
26 
27 // ----------------------------------------------------------------------------
28 // QT Includes
29 
30 #include <QObject>
31 
32 // ----------------------------------------------------------------------------
33 // Project Includes
34 #include "kmm_mymoney_export.h"
35 #include "mymoneyunittestable.h"
36 
37 /**
38   * @author Thomas Baumgart, Michael Edwardes, Kevin Tambascio, Christian Dávid
39   */
40 
41 /**
42   * This class represents the interface to the MyMoney engine.
43   * For historical reasons it is still called MyMoneyFile.
44   * It is implemented using the singleton pattern and thus only
45   * exists once for each running instance of an application.
46   *
47   * The instance of the MyMoneyFile object is accessed as follows:
48   *
49   * @code
50   * MyMoneyFile *file = MyMoneyFile::instance();
51   * file->anyMemberFunction();
52   * @endcode
53   *
54   * The first line of the above code creates a unique MyMoneyFile
55   * object if it is called for the first time ever. All subsequent
56   * calls to this functions return a pointer to the object created
57   * during the first call.
58   *
59   * As the MyMoneyFile object represents the business logic, a storage
60   * manager must be attached to it. This mechanism allows to use different
61   * access methods to store the objects. The interface to access such an
62   * storage manager is defined in the class MyMoneyStorageMgr. The methods
63   * attachStorage() and detachStorage() are used to attach/detach a
64   * storage manager object. The following code can be used to create a
65   * functional MyMoneyFile instance:
66   *
67   * @code
68   * MyMoneyStorageMgr *storage = ....
69   * MyMoneyFile *file = MyMoneyFile::instance();
70   * file->attachStorage(storage);
71   * @endcode
72   *
73   * The methods addAccount(), modifyAccount() and removeAccount() implement the
74   * general account maintenance functions. The method reparentAccount() is
75   * available to move an account from one superordinate account to another.
76   * account() and accountList() are used to retrieve a single instance or a
77   * QList of MyMoneyAccount objects.
78   *
79   * The methods addInstitution(), modifyInstitution() and removeInstitution()
80   * implement the general institution maintenance functions. institution() and
81   * institutionList() are used to retrieve a single instance or a
82   * QList of MyMoneyInstitution objects.
83   *
84   * The methods addPayee(), modifyPayee() and removePayee()
85   * implement the general payee maintenance functions.
86   * payee() and payeeList() are used to retrieve a single instance or a
87   * QList of MyMoneyPayee objects.
88   *
89   * The methods addTag(), modifyTag() and removeTag()
90   * implement the general tag maintenance functions.
91   * tag() and tagList() are used to retrieve a single instance or a
92   * QList of MyMoneyTag objects.
93   *
94   * The methods addTransaction(), modifyTransaction() and removeTransaction()
95   * implement the general transaction maintenance functions.
96   * transaction() and transactionList() are used to retrieve
97   * a single instance or a QList of MyMoneyTransaction objects.
98   *
99   * The methods addSecurity(), modifySecurity() and removeSecurity()
100   * implement the general access to equities held in the engine.
101   *
102   * The methods addCurrency(), modifyCurrency() and removeCurrency()
103   * implement the general access to multiple currencies held in the engine.
104   * The methods baseCurrency() and setBaseCurrency() allow to retrieve/set
105   * the currency selected by the user as base currency. If a currency
106   * reference is empty, it will usually be interpreted as baseCurrency().
107   *
108   * The methods liability(), asset(), expense(), income() and equity() are
109   * used to retrieve the five standard accounts. isStandardAccount()
110   * checks if a given accountId references one of the or not.
111   * setAccountName() is used to specify a name for the standard accounts
112   * from the GUI.
113   *
114   * The MyMoneyFile object emits the dataChanged() signal when data
115   * has been changed.
116   *
117   * For arbitrary values that have to be stored with the storage object
118   * but are of importance to the application only, the object is derived
119   * for MyMoneyKeyValueContainer which provides a container to store
120   * these values indexed by an alphanumeric key.
121   *
122   * @exception MyMoneyException is thrown whenever an error occurs
123   * while the engine code is running. The MyMoneyException:: object
124   * describes the problem.
125   */
126 template <class Key, class T> class QMap;
127 class QString;
128 class QStringList;
129 class QBitArray;
130 class MyMoneyStorageMgr;
131 class MyMoneyCostCenter;
132 class MyMoneyAccount;
133 class MyMoneyInstitution;
134 class MyMoneySecurity;
135 class MyMoneyPrice;
136 typedef QPair<QString, QString> MyMoneySecurityPair;
137 typedef QMap<QDate, MyMoneyPrice> MyMoneyPriceEntries;
138 typedef QMap<MyMoneySecurityPair, MyMoneyPriceEntries> MyMoneyPriceList;
139 class MyMoneySchedule;
140 class MyMoneyTag;
141 class MyMoneyPayee;
142 class MyMoneyBudget;
143 class MyMoneyReport;
144 class MyMoneyMoney;
145 class MyMoneySplit;
146 class MyMoneyObject;
147 class MyMoneyTransaction;
148 class MyMoneyTransactionFilter;
149 class onlineJob;
150 
151 namespace eMyMoney { namespace Account { enum class Type; }
152                      namespace File { enum class Object; }
153                      namespace Schedule { enum class Type;
154                                           enum class Occurrence;
155                                           enum class PaymentType; }
156                      namespace TransactionFilter { enum class State; }
157                    }
158 
159 class KMM_MYMONEY_EXPORT MyMoneyFile : public QObject
160 {
161   Q_OBJECT
162   KMM_MYMONEY_UNIT_TESTABLE
163 
164 public:
165   friend class MyMoneyNotifier;
166 
167   /**
168     * This is the function to access the MyMoneyFile object.
169     * It returns a pointer to the single instance of the object.
170     */
171   static MyMoneyFile* instance();
172 
173   /**
174     * This is the destructor for any MyMoneyFile object
175     */
176   ~MyMoneyFile();
177 
178   /**
179     * @deprecated This is a convenience constructor. Do not use it anymore.
180     * It will be deprecated in a future version of the engine.
181     *
182     * @param storage pointer to object that implements the MyMoneyStorageMgr
183     *                interface.
184     */
185   explicit MyMoneyFile(MyMoneyStorageMgr *storage);
186 
187   // general get functions
188   MyMoneyPayee user() const;
189 
190   // general set functions
191   void setUser(const MyMoneyPayee& user);
192 
193   /**
194     * This method is used to attach a storage object to the MyMoneyFile object
195     * Without an attached storage object, the MyMoneyFile object is
196     * of no use.
197     *
198     * After successful completion, the dataChanged() signal is emitted.
199     *
200     * In case of an error condition, an exception is thrown.
201     * The following error conditions are checked:
202     *
203     * - @a storage is not equal to 0
204     * - there is no other @a storage object attached (use detachStorage()
205     *   to revert the attachStorage() operation.
206     *
207     * @param storage pointer to object that implements the MyMoneyStorageMgr
208     *                interface.
209     *
210     * @sa detachStorage()
211     */
212   void attachStorage(MyMoneyStorageMgr* const storage);
213 
214   /**
215     * This method is used to detach a previously attached storage
216     * object from the MyMoneyFile object. If no storage object
217     * is attached to the engine, this is a NOP.
218     *
219     * @param storage pointer to object that implements the MyMoneyStorageMgr
220     *                interface.
221     *
222     * @sa attachStorage()
223     */
224   void detachStorage(MyMoneyStorageMgr* const storage = 0);
225 
226   /**
227     * This method returns whether a storage is currently attached to
228     * the engine or not.
229     *
230     * @return true if storage object is attached, false otherwise
231     */
232   bool storageAttached() const;
233 
234   /**
235     * This method returns a pointer to the storage object
236     *
237     * @return const pointer to the current attached storage object.
238     *         If no object is attached, returns 0.
239     */
240   MyMoneyStorageMgr* storage() const;
241 
242   /**
243     * This method must be called before any single change or a series of changes
244     * in the underlying storage area is performed.
245     * Once all changes are complete (i.e. the transaction is completed),
246     * commitTransaction() must be called to finalize all changes. If an error occurs
247     * during the processing of the changes call rollbackTransaction() to undo the
248     * changes done so far.
249     */
250   void startTransaction();
251 
252   /**
253     * This method returns whether a transaction has been started (@a true)
254     * or not (@a false).
255     */
256   bool hasTransaction() const;
257 
258   /**
259     * @sa startTransaction()
260     */
261   void commitTransaction();
262 
263   /**
264     * @sa startTransaction()
265     */
266   void rollbackTransaction();
267 
268   /**
269     * This method is used to return the standard liability account
270     * @return MyMoneyAccount liability account(group)
271     */
272   MyMoneyAccount liability() const;
273 
274   /**
275     * This method is used to return the standard asset account
276     * @return MyMoneyAccount asset account(group)
277     */
278   MyMoneyAccount asset() const;
279 
280   /**
281     * This method is used to return the standard expense account
282     * @return MyMoneyAccount expense account(group)
283     */
284   MyMoneyAccount expense() const;
285 
286   /**
287     * This method is used to return the standard income account
288     * @return MyMoneyAccount income account(group)
289     */
290   MyMoneyAccount income() const;
291 
292   /**
293     * This method is used to return the standard equity account
294     * @return MyMoneyAccount equity account(group)
295     */
296   MyMoneyAccount equity() const;
297 
298   /**
299     * This method returns the account information for the opening
300     * balances account for the given @p security. If the respective
301     * account does not exist, it will be created. The name is constructed
302     * using MyMoneyFile::openingBalancesPrefix() and appending " (xxx)" in
303     * case the @p security is not the baseCurrency(). The account created
304     * will be a sub-account of the standard equity account provided by equity().
305     *
306     * @param security Security for which the account is searched
307     *
308     * @return The opening balance account
309     *
310     * @note No notifications will be sent!
311     */
312   MyMoneyAccount openingBalanceAccount(const MyMoneySecurity& security);
313 
314   /**
315     * This method is essentially the same as the above, except it works on
316     * const objects.  If there is no opening balance account, this method
317     * WILL NOT create one.  Instead it will thrown an exception.
318     *
319     * @param security Security for which the account is searched
320     *
321     * @return The opening balance account
322     *
323     * @note No notifications will be sent!
324     */
325   MyMoneyAccount openingBalanceAccount(const MyMoneySecurity& security) const;
326 
327   /**
328     * Create an opening balance transaction for the account @p acc
329     * with a value of @p balance. If the corresponding opening balance account
330     * for the account's currency does not exist it will be created. If it exists
331     * and it's opening date is later than the opening date of @p acc,
332     * the opening date of the opening balances account will be adjusted to the
333     * one of @p acc.
334     *
335     * @param acc reference to account for which the opening balance transaction
336     *            should be created
337     * @param balance reference to the value of the opening balance transaction
338     *
339     * @returns The created MyMoneyTransaction object. In case no transaction has been
340     *          created, the id of the object is empty.
341     */
342   MyMoneyTransaction createOpeningBalanceTransaction(const MyMoneyAccount& acc, const MyMoneyMoney& balance);
343 
344   /**
345     * Retrieve the opening balance transaction for the account @p acc.
346     * If there is no opening balance transaction, QString() will be returned.
347     *
348     * @param acc reference to account for which the opening balance transaction
349     *            should be retrieved
350     * @return QString id for the transaction, or QString() if no transaction exists
351     */
352   QString openingBalanceTransaction(const MyMoneyAccount& acc) const;
353 
354   /**
355     * This method returns an indicator if the MyMoneyFile object has been
356     * changed after it has last been saved to permanent storage.
357     *
358     * @return true if changed, false if not
359     */
360   bool dirty() const;
361 
362   /**
363     * This method is used to force the attached storage object to
364     * be dirty. This is used by the application to re-set the dirty
365     * flag after a failed upload to a server when the save operation
366     * to a local temp file was OK.
367     */
368   void setDirty() const;
369 
370   /**
371     * Adds an institution to the file-global institution pool. A
372     * respective institution-ID will be generated for this object.
373     * The ID is stored as QString in the object passed as argument.
374     *
375     * An exception will be thrown upon error conditions.
376 
377     * @param institution The complete institution information in a
378     *        MyMoneyInstitution object
379     */
380   void addInstitution(MyMoneyInstitution& institution);
381 
382   /**
383     * Modifies an already existing institution in the file global
384     * institution pool.
385     *
386     * An exception will be thrown upon error conditions.
387     *
388     * @param institution The complete new institution information
389     */
390   void modifyInstitution(const MyMoneyInstitution& institution);
391 
392   /**
393     * Deletes an existing institution from the file global institution pool
394     * Also modifies the accounts that reference this institution as
395     * their institution.
396     *
397     * An exception will be thrown upon error conditions.
398     *
399     * @param institution institution to be deleted.
400     */
401   void removeInstitution(const MyMoneyInstitution& institution);
402 
403   void createAccount(MyMoneyAccount& newAccount, MyMoneyAccount& parentAccount, MyMoneyAccount& brokerageAccount, MyMoneyMoney openingBal);
404   /**
405     * Adds an account to the file-global account pool. A respective
406     * account-ID will be generated within this record. The modified
407     * members of @a account will be updated.
408     *
409     * A few parameters of the account to be added are checked against
410     * the following conditions. If they do not match, an exception is
411     * thrown.
412     *
413     * An account must match the following conditions:
414     *
415     *   a) the account must have a name with length > 0
416     *   b) the account must not have an id assigned
417     *   c) the transaction list must be empty
418     *   d) the account must not have any sub-ordinate accounts
419     *   e) the account must have no parent account
420     *   f) the account must not have any reference to a MyMoneyFile object
421     *
422     * An exception will be thrown upon error conditions.
423     *
424     * @param account The complete account information in a MyMoneyAccount object
425     * @param parent  The complete account information of the parent account
426     */
427   void addAccount(MyMoneyAccount& account, MyMoneyAccount& parent);
428 
429   /**
430     * Modifies an already existing account in the file global account pool.
431     *
432     * An exception will be thrown upon error conditions.
433     *
434     * @param account reference to the new account information
435     */
436   void modifyAccount(const MyMoneyAccount& account);
437 
438   /**
439     * This method re-parents an existing account
440     *
441     * An exception will be thrown upon error conditions.
442     *
443     * @param account MyMoneyAccount reference to account to be re-parented
444     * @param parent  MyMoneyAccount reference to new parent account
445     */
446   void reparentAccount(MyMoneyAccount &account, MyMoneyAccount& parent);
447 
448   /**
449     * moves splits from one account to another
450     *
451     * @param oldAccount id of the current account
452     * @param newAccount if of the new account
453     *
454     * @return the number of modified splits
455     */
456   unsigned int moveSplits(const QString& oldAccount, const QString& newAccount);
457 
458   /**
459     * This method is used to determine, if the account with the
460     * given ID is referenced by any split in m_transactionList.
461     *
462     * @param id id of the account to be checked for
463     * @return true if account is referenced, false otherwise
464     */
465   bool hasActiveSplits(const QString& id) const;
466 
467   /**
468     * This method is used to check whether a given
469     * account id references one of the standard accounts or not.
470     *
471     * An exception will be thrown upon error conditions.
472     *
473     * @param id account id
474     * @return true if account-id is one of the standards, false otherwise
475     */
476   bool isStandardAccount(const QString& id) const;
477 
478   /**
479     * Returns @a true, if transaction @p t is a transfer transaction.
480     * A transfer transaction has two splits, both referencing either
481     * an asset, a liability or an equity account.
482     */
483   bool isTransfer(const MyMoneyTransaction& t) const;
484 
485   /**
486     * This method is used to set the name for the specified standard account
487     * within the storage area. An exception will be thrown, if an error
488     * occurs
489     *
490     * @param id QString reference to one of the standard accounts.
491     * @param name QString reference to the name to be set
492     *
493     */
494   void setAccountName(const QString& id, const QString& name) const;
495 
496   /**
497     * Deletes an existing account from the file global account pool
498     * This method only allows to remove accounts that are not
499     * referenced by any split. Use moveSplits() to move splits
500     * to another account. An exception is thrown in case of a
501     * problem.
502     *
503     * @param account reference to the account to be deleted.
504     */
505   void removeAccount(const MyMoneyAccount& account);
506 
507   /**
508     * Deletes existing accounts and their subaccounts recursively
509     * from the global account pool.
510     * This method expects that all accounts and their subaccounts
511     * are no longer assigned to any transactions or splits.
512     * An exception is thrown in case of a problem deleting an account.
513     *
514     * The optional parameter level is used to keep track of the recursion level.
515     * If the recursion level exceeds 100 (some arbitrary number which seems a good
516     * maximum), an exception is thrown.
517     *
518     * @param account_list Reference to a list of account IDs to be deleted.
519     * @param level Parameter to keep track of recursion level (do not pass a value here).
520     */
521   void removeAccountList(const QStringList& account_list, unsigned int level = 0);
522 
523   /**
524     * This member function checks all accounts identified by account_list
525     * and their subaccounts whether they are assigned to transactions/splits or not.
526     * The function calls itself recursively with the list of sub-accounts of
527     * the currently processed account.
528     *
529     * The optional parameter level is used to keep track of the recursion level.
530     * If the recursion level exceeds 100 (some arbitrary number which seems a good
531     * maximum), an exception is thrown.
532     *
533     * @param account_list  A QStringList with account IDs that need to be checked.
534     * @param level         (optional) Optional parameter to indicate recursion level.
535     * @return              Returns 'false' if at least one account has been found that
536     *                      is still referenced by a transaction.
537     */
538   bool hasOnlyUnusedAccounts(const QStringList& account_list, unsigned int level = 0);
539 
540   /**
541     * Adds a transaction to the file-global transaction pool. A respective
542     * transaction-ID will be generated for this object. The ID is stored
543     * as QString in the object passed as argument.
544     * Splits must reference valid accounts and valid payees. The payee
545     * id can be empty.
546     *
547     * An exception will be thrown upon error conditions.
548     *
549     * @param transaction reference to the transaction
550     */
551   void addTransaction(MyMoneyTransaction& transaction);
552 
553   /**
554     * This method is used to update a specific transaction in the
555     * transaction pool of the MyMoneyFile object.
556     * Splits must reference valid accounts and valid payees. The payee
557     * id can be empty.
558     *
559     * An exception will be thrown upon error conditions.
560     *
561     * @param transaction reference to transaction to be changed
562     */
563   void modifyTransaction(const MyMoneyTransaction& transaction);
564 
565   /**
566     * This method is used to extract a transaction from the file global
567     * transaction pool through an id. In case of an invalid id, an
568     * exception will be thrown.
569     *
570     * @param id id of transaction as QString.
571     * @return reference to the requested transaction
572     */
573   MyMoneyTransaction transaction(const QString& id) const;
574 
575   /**
576     * This method is used to extract a transaction from the file global
577     * transaction pool through an index into an account.
578     *
579     * @param account id of the account as QString
580     * @param idx number of transaction in this account
581     * @return reference to MyMoneyTransaction object
582     */
583   MyMoneyTransaction transaction(const QString& account, const int idx) const;
584 
585   /**
586     * This method is used to pull a list of transactions from the file
587     * global transaction pool. It returns all those transactions
588     * that match the filter passed as argument. If the filter is empty,
589     * the whole journal will be returned.
590     * The list returned is sorted according to the transactions posting date.
591     * If more than one transaction exists for the same date, the order among
592     * them is undefined.
593     *
594     * @param filter MyMoneyTransactionFilter object with the match criteria
595     *
596     * @return set of transactions in form of a QList<MyMoneyTransaction>
597     */
598   QList<MyMoneyTransaction> transactionList(MyMoneyTransactionFilter& filter) const;
599 
600   void transactionList(QList<MyMoneyTransaction>& list, MyMoneyTransactionFilter& filter) const;
601 
602   void transactionList(QList<QPair<MyMoneyTransaction, MyMoneySplit> >& list, MyMoneyTransactionFilter& filter) const;
603 
604   /**
605     * This method is used to remove a transaction from the transaction
606     * pool (journal).
607     *
608     * @param transaction const reference to transaction to be deleted
609     */
610   void removeTransaction(const MyMoneyTransaction& transaction);
611 
612   /**
613     * This method is used to return the actual balance of an account
614     * without it's sub-ordinate accounts. If a @p date is presented,
615     * the balance at the beginning of this date (not including any
616     * transaction on this date) is returned. Otherwise all recorded
617     * transactions are included in the balance.
618     *
619     * @param id id of the account in question
620     * @param date return balance for specific date (default = QDate())
621     * @return balance of the account as MyMoneyMoney object
622     */
623   MyMoneyMoney balance(const QString& id, const QDate& date) const;
624   MyMoneyMoney balance(const QString& id) const;
625 
626   /**
627     * This method is used to return the cleared balance of an account
628     * without it's sub-ordinate accounts for a specific date. All
629     * recorded  transactions are included in the balance.
630     * This method is used by the reconciliation functionality
631     *
632     * @param id id of the account in question
633     * @param date return cleared balance for specific date
634     * @return balance of the account as MyMoneyMoney object
635     */
636   MyMoneyMoney clearedBalance(const QString& id, const QDate& date) const;
637 
638 
639   /**
640     * This method is used to return the actual balance of an account
641     * including it's sub-ordinate accounts. If a @p date is presented,
642     * the balance at the beginning of this date (not including any
643     * transaction on this date) is returned. Otherwise all recorded
644     * transactions are included in the balance.
645     *
646     * @param id id of the account in question
647     * @param date return balance for specific date (default = QDate())
648     * @return balance of the account as MyMoneyMoney object
649     */
650   MyMoneyMoney totalBalance(const QString& id, const QDate& date) const;
651   MyMoneyMoney totalBalance(const QString& id) const;
652 
653   /**
654     * This method returns the number of transactions currently known to file
655     * in the range 0..MAXUINT
656     *
657     * @param account QString reference to account id. If account is empty
658     +                all transactions (the journal) will be counted. If account
659     *                is not empty it returns the number of transactions
660     *                that have splits in this account.
661     *
662     * @return number of transactions in journal/account
663     */
664   unsigned int transactionCount(const QString& account) const;
665   unsigned int transactionCount() const;
666 
667   /**
668     * This method returns a QMap filled with the number of transactions
669     * per account. The account id serves as index into the map. If one
670     * needs to have all transactionCounts() for many accounts, this method
671     * is faster than calling transactionCount(const QString& account) many
672     * times.
673     *
674     * @return QMap with numbers of transactions per account
675     */
676   QMap<QString, unsigned long> transactionCountMap() const;
677 
678   /**
679     * This method returns the number of institutions currently known to file
680     * in the range 0..MAXUINT
681     *
682     * @return number of institutions known to file
683     */
684   unsigned int institutionCount() const;
685 
686   /**
687     * This method returns the number of accounts currently known to file
688     * in the range 0..MAXUINT
689     *
690     * @return number of accounts currently known inside a MyMoneyFile object
691     */
692   unsigned int accountCount() const;
693 
694   /**
695     * Returns the institution of a given ID
696     *
697     * @param id id of the institution to locate
698     * @return MyMoneyInstitution object filled with data. If the institution
699     *         could not be found, an exception will be thrown
700     */
701   MyMoneyInstitution institution(const QString& id) const;
702 
703   /**
704     * This method returns a list of the institutions
705     * inside a MyMoneyFile object. This is a convenience method
706     * to the one above
707     *
708     * @return QList containing the institution objects
709     */
710   QList<MyMoneyInstitution> institutionList() const;
711 
712   /**
713     * Returns the account addressed by its id.
714     *
715     * @param id id of the account to locate.
716     * @return MyMoneyAccount object carrying the @p id. An exception is thrown
717     *         if the id is unknown
718     */
719   MyMoneyAccount account(const QString& id) const;
720 
721   /**
722    * Returns the account addressed by its name.
723    *
724    * @param name  name of the account to locate.
725    * @return First MyMoneyAccount object found carrying the @p name.
726    * An empty MyMoneyAccount object will be returned if the name is not found.
727    */
728   MyMoneyAccount accountByName(const QString& name) const;
729 
730   /**
731    * Returns the sub-account addressed by its name.
732    *
733    * @param acc account to search in
734    * @param name  name of the account to locate.
735    * @return First MyMoneyAccount object found carrying the @p name.
736    * An empty MyMoneyAccount object will be returned if the name is not found.
737    */
738   MyMoneyAccount subAccountByName(const MyMoneyAccount& account, const QString& name) const;
739 
740   /**
741     * This method returns a list of accounts inside a MyMoneyFile object.
742     * An optional parameter is a list of id's. If this list is empty (the default)
743     * the returned list contains all accounts, otherwise only those referenced
744     * in the id-list.
745     *
746     * @param list reference to QList receiving the account objects
747     * @param idlist QStringList of account ids of those accounts that
748     *        should be returned. If this list is empty, all accounts
749     *        currently known will be returned.
750     *
751     * @param recursive if @p true, then recurse in all found accounts. The default is @p false
752     */
753   void accountList(QList<MyMoneyAccount>& list, const QStringList& idlist = QStringList(), const bool recursive = false) const;
754 
755   /**
756     * This method is used to convert an account id to a string representation
757     * of the names which can be used as a category description. If the account
758     * is part of a hierarchy, the category name will be the concatenation of
759     * the single account names separated by MyMoneyFile::AccountSeparator.
760     *
761     * @param accountId QString reference of the account's id
762     * @param includeStandardAccounts if true, the standard top account will be part
763     *                   of the name, otherwise it will not be included (default is @c false)
764     *
765     * @return QString of the constructed name.
766     */
767   QString accountToCategory(const QString& accountId, bool includeStandardAccounts = false) const;
768 
769   /**
770     * This method is used to convert a string representing a category to
771     * an account id. A category can be the concatenation of multiple accounts
772     * representing a hierarchy of accounts. They have to be separated by
773     * MyMoneyFile::AccountSeparator.
774     *
775     * @param category const reference to QString containing the category
776     * @param type account type if a specific type is required (defaults to Unknown)
777     *
778     * @return QString of the corresponding account. If account was not found
779     *         the return value will be an empty string.
780     */
781   QString categoryToAccount(const QString& category, eMyMoney::Account::Type type) const;
782   QString categoryToAccount(const QString& category) const;
783 
784   /**
785     * This method is used to convert a string representing an asset or
786     * liability account to an account id. An account name can be the
787     * concatenation of multiple accounts representing a hierarchy of
788     * accounts. They have to be separated by MyMoneyFile::AccountSeparator.
789     *
790     * @param name const reference to QString containing the account name
791     *
792     * @return QString of the corresponding account. If account was not found
793     *         the return value will be an empty string.
794     */
795   QString nameToAccount(const QString& name) const;
796 
797   /**
798     * This method is used to extract the parent part of an account hierarchy
799     * name who's parts are separated by MyMoneyFile::AccountSeparator.
800     *
801     * @param name full account name
802     * @return parent name (full account name excluding the last part)
803     */
804   QString parentName(const QString& name) const;
805 
806   /**
807     * This method is used to create a new payee
808     *
809     * An exception will be thrown upon error conditions
810     *
811     * @param payee MyMoneyPayee reference to payee information
812     */
813   void addPayee(MyMoneyPayee& payee);
814 
815   /**
816     * This method is used to retrieve information about a payee
817     * An exception will be thrown upon error conditions.
818     *
819     * @param id QString reference to id of payee
820     *
821     * @return MyMoneyPayee object of payee
822     */
823   MyMoneyPayee payee(const QString& id) const;
824 
825   /**
826     * This method is used to retrieve the id to a corresponding
827     * name of a payee/receiver.
828     * An exception will be thrown upon error conditions.
829     *
830     * @param payee QString reference to name of payee
831     *
832     * @return MyMoneyPayee object of payee
833     */
834   MyMoneyPayee payeeByName(const QString& payee) const;
835 
836   /**
837     * This method is used to modify an existing payee
838     *
839     * An exception will be thrown upon error conditions
840     *
841     * @param payee MyMoneyPayee reference to payee information
842     */
843   void modifyPayee(const MyMoneyPayee& payee);
844 
845   /**
846     * This method is used to remove an existing payee.
847     * An error condition occurs, if the payee is still referenced
848     * by a split.
849     *
850     * An exception will be thrown upon error conditions
851     *
852     * @param payee MyMoneyPayee reference to payee information
853     */
854   void removePayee(const MyMoneyPayee& payee);
855 
856   /**
857     * This method returns a list of the payees
858     * inside a MyMoneyStorage object
859     *
860     * @return QList<MyMoneyPayee> containing the payee information
861     */
862   QList<MyMoneyPayee> payeeList() const;
863 
864   /**
865     * This method is used to create a new tag
866     *
867     * An exception will be thrown upon error conditions
868     *
869     * @param tag MyMoneyTag reference to tag information
870     */
871   void addTag(MyMoneyTag& tag);
872 
873   /**
874     * This method is used to retrieve information about a tag
875     * An exception will be thrown upon error conditions.
876     *
877     * @param id QString reference to id of tag
878     *
879     * @return MyMoneyTag object of tag
880     */
881   MyMoneyTag tag(const QString& id) const;
882 
883   /**
884     * This method is used to retrieve the id to a corresponding
885     * name of a tag.
886     * An exception will be thrown upon error conditions.
887     *
888     * @param tag QString reference to name of tag
889     *
890     * @return MyMoneyTag object of tag
891     */
892   MyMoneyTag tagByName(const QString& tag) const;
893 
894   /**
895     * This method is used to modify an existing tag
896     *
897     * An exception will be thrown upon error conditions
898     *
899     * @param tag MyMoneyTag reference to tag information
900     */
901   void modifyTag(const MyMoneyTag& tag);
902 
903   /**
904     * This method is used to remove an existing tag.
905     * An error condition occurs, if the tag is still referenced
906     * by a split.
907     *
908     * An exception will be thrown upon error conditions
909     *
910     * @param tag MyMoneyTag reference to tag information
911     */
912   void removeTag(const MyMoneyTag& tag);
913 
914   /**
915     * This method returns a list of the tags
916     * inside a MyMoneyStorage object
917     *
918     * @return QList<MyMoneyTag> containing the tag information
919     */
920   QList<MyMoneyTag> tagList() const;
921 
922   /**
923     * This method returns a list of the cost centers
924     * inside a MyMoneyStorage object
925     *
926     * @return QList<MyMoneyCostCenter> containing the cost center information
927     */
928     void costCenterList(QList< MyMoneyCostCenter >& list) const;
929 
930   /**
931     * This method is used to extract a value from the storage's
932     * KeyValueContainer. For details see MyMoneyKeyValueContainer::value().
933     * @note Do not use this method to return the value of the key @p kmm-id. Use
934     * storageId() instead.
935     *
936     * @param key const reference to QString containing the key
937     * @return QString containing the value
938     */
939   QString value(const QString& key) const;
940 
941   /**
942     * This method is used to set a value in the storage's
943     * KeyValueContainer. For details see MyMoneyKeyValueContainer::setValue().
944     *
945     * @param key const reference to QString containing the key
946     * @param val const reference to QString containing the value
947     *
948     * @note Keys starting with the leading @p kmm- are reserved for internal use
949     *       by the MyMoneyFile object.
950     */
951   void setValue(const QString& key, const QString& val);
952 
953   /**
954    * This method returns the unique id of the attached storage object.
955    * In case the storage object does not have an id yet, a new one will be
956    * assigned.
957    *
958    * @return QString containing the value
959    *
960    * An exception is thrown if no storage object is attached.
961    */
962   QString storageId();
963 
964   /**
965     * This method is used to delete a key-value-pair from the
966     * storage's KeyValueContainer identified by the parameter
967     * @p key. For details see MyMoneyKeyValueContainer::deletePair().
968     *
969     * @param key const reference to QString containing the key
970     */
971   void deletePair(const QString& key);
972 
973   /**
974     * This method is used to add a scheduled transaction to the engine.
975     * It must be sure, that the id of the object is not filled. When the
976     * method returns to the caller, the id will be filled with the
977     * newly created object id value.
978     *
979     * An exception will be thrown upon erroneous situations.
980     *
981     * @param sched reference to the MyMoneySchedule object
982     */
983   void addSchedule(MyMoneySchedule& sched);
984 
985   /**
986     * This method is used to modify an existing MyMoneySchedule
987     * object. Therefor, the id attribute of the object must be set.
988     *
989     * An exception will be thrown upon erroneous situations.
990     *
991     * @param sched const reference to the MyMoneySchedule object to be updated
992     */
993   void modifySchedule(const MyMoneySchedule& sched);
994 
995   /**
996     * This method is used to remove an existing MyMoneySchedule object
997     * from the engine. The id attribute of the object must be set.
998     *
999     * An exception will be thrown upon erroneous situations.
1000     *
1001     * @param sched const reference to the MyMoneySchedule object to be updated
1002     */
1003   void removeSchedule(const MyMoneySchedule& sched);
1004 
1005   /**
1006     * This method is used to retrieve a single MyMoneySchedule object.
1007     * The id of the object must be supplied in the parameter @p id.
1008     *
1009     * An exception will be thrown upon erroneous situations.
1010     *
1011     * @param id QString containing the id of the MyMoneySchedule object
1012     * @return MyMoneySchedule object
1013     */
1014   MyMoneySchedule schedule(const QString& id) const;
1015 
1016   /**
1017     * This method is used to extract a list of scheduled transactions
1018     * according to the filter criteria passed as arguments.
1019     *
1020     * @param accountId only search for scheduled transactions that reference
1021     *                  account @p accountId. If accountId is the empty string,
1022     *                  this filter is off. Default is @p QString().
1023     * @param type      only schedules of type @p type are searched for.
1024     *                  See eMyMoney::Schedule::Type for details.
1025     *                  Default is eMyMoney::Schedule::Type::Any
1026     * @param occurrence only schedules of occurrence type @p occurrence are searched for.
1027     *                  See eMyMoney::Schedule::Occurrence for details.
1028     *                  Default is eMyMoney::Schedule::Occurrence::Any
1029     * @param paymentType only schedules of payment method @p paymentType
1030     *                  are searched for.
1031     *                  See eMyMoney::Schedule::PaymentType for details.
1032     *                  Default is eMyMoney::Schedule::PaymentType::Any
1033     * @param startDate only schedules with payment dates after @p startDate
1034     *                  are searched for. Default is all dates (QDate()).
1035     * @param endDate   only schedules with payment dates ending prior to @p endDate
1036     *                  are searched for. Default is all dates (QDate()).
1037     * @param overdue   if true, only those schedules that are overdue are
1038     *                  searched for. Default is false (all schedules will be returned).
1039     *
1040     * @return const QList<MyMoneySchedule> list of schedule objects.
1041     */
1042   QList<MyMoneySchedule> scheduleList(const QString& accountId,
1043       const eMyMoney::Schedule::Type type,
1044       const eMyMoney::Schedule::Occurrence occurrence,
1045       const eMyMoney::Schedule::PaymentType paymentType,
1046       const QDate& startDate,
1047       const QDate& endDate,
1048       const bool overdue) const;
1049   QList<MyMoneySchedule> scheduleList(const QString& accountId) const;
1050   QList<MyMoneySchedule> scheduleList() const;
1051 
1052   QStringList consistencyCheck();
1053 
1054   /**
1055     * MyMoneyFile::openingBalancesPrefix() is a special string used
1056     * to generate the name for opening balances accounts. See openingBalanceAccount()
1057     * for details.
1058     */
1059   static QString openingBalancesPrefix();
1060 
1061   /**
1062     * MyMoneyFile::AccountSeparator is used as the separator
1063     * between account names to form a hierarchy.
1064     */
1065   static const QString AccountSeparator;
1066 
1067   /**
1068     * createCategory creates a category from a text name.
1069     *
1070     * The whole account hierarchy is created if it does not
1071     * already exist.  e.g if name = Bills:Credit Card and
1072     * base = expense(), Bills will first be checked to see if
1073     * it exists and created if not.  Credit Card will then
1074     * be created with Bills as it's parent.  The Credit Card account
1075     * will have it's id returned.
1076     *
1077     * @param base The base account (expense or income)
1078     * @param name The category to create
1079     *
1080     * @return The category account id or empty on error.
1081     *
1082     * @exception An exception will be thrown, if @p base is not equal
1083     *            expense() or income().
1084     **/
1085   QString createCategory(const MyMoneyAccount& base, const QString& name);
1086 
1087   /**
1088     * This method is used to get the account id of the split for
1089     * a transaction from the text found in the QIF $ or L record.
1090     * If an account with the name is not found, the user is asked
1091     * if it should be created.
1092     *
1093     * @param name name of account as found in the QIF file
1094     * @param value value found in the T record
1095     * @param value2 value found in the $ record for split transactions
1096     *
1097     * @return id of the account for the split. If no name is specified
1098     *            or the account was not found and not created the
1099     *            return value will be "".
1100     */
1101   QString checkCategory(const QString& name, const MyMoneyMoney& value, const MyMoneyMoney& value2);
1102 
1103   /**
1104     * This method is used to add a new security object to the engine.
1105     * The ID of the object is the trading symbol, so there is no need for an additional
1106     * ID since the symbol is guaranteed to be unique.
1107     *
1108     * An exception will be thrown upon erroneous situations.
1109     *
1110     * @param security reference to the MyMoneySecurity object
1111     */
1112   void addSecurity(MyMoneySecurity& security);
1113 
1114   /**
1115     * This method is used to modify an existing MyMoneySchedule
1116     * object.
1117     *
1118     * An exception will be thrown upon erroneous situations.
1119     *
1120     * @param security reference to the MyMoneySecurity object to be updated
1121     */
1122   void modifySecurity(const MyMoneySecurity& security);
1123 
1124   /**
1125     * This method is used to remove an existing MyMoneySecurity object
1126     * from the engine.
1127     *
1128     * An exception will be thrown upon erroneous situations.
1129     *
1130     * @param security reference to the MyMoneySecurity object to be removed
1131     */
1132   void removeSecurity(const MyMoneySecurity& security);
1133 
1134   /**
1135     * This method is used to retrieve a single MyMoneySecurity object.
1136     * The id of the object must be supplied in the parameter @p id.
1137     * If no security with the given id is found, then a corresponding
1138     * currency is searched. If @p id is empty, the baseCurrency() is returned.
1139     *
1140     * An exception will be thrown upon erroneous situations.
1141     *
1142     * @param id QString containing the id of the MyMoneySecurity object
1143     * @return MyMoneySecurity object
1144     */
1145   MyMoneySecurity security(const QString& id) const;
1146 
1147   /**
1148     * This method is used to retrieve a list of all MyMoneySecurity objects.
1149     */
1150   QList<MyMoneySecurity> securityList() const;
1151 
1152   /**
1153     * This method is used to add a new currency object to the engine.
1154     * The ID of the object is the trading symbol, so there is no need for an additional
1155     * ID since the symbol is guaranteed to be unique.
1156     *
1157     * An exception will be thrown upon erroneous situations.
1158     *
1159     * @param currency reference to the MyMoneySecurity object
1160     */
1161   void addCurrency(const MyMoneySecurity& currency);
1162 
1163   /**
1164     * This method is used to modify an existing MyMoneySecurity
1165     * object.
1166     *
1167     * An exception will be thrown upon erroneous situations.
1168     *
1169     * @param currency reference to the MyMoneySecurity object
1170     */
1171   void modifyCurrency(const MyMoneySecurity& currency);
1172 
1173   /**
1174     * This method is used to remove an existing MyMoneySecurity object
1175     * from the engine.
1176     *
1177     * An exception will be thrown upon erroneous situations.
1178     *
1179     * @param currency reference to the MyMoneySecurity object
1180     */
1181   void removeCurrency(const MyMoneySecurity& currency);
1182 
1183   /**
1184     * This method is used to retrieve a single MyMoneySecurity object.
1185     * The id of the object must be supplied in the parameter @p id.
1186     * If @p id is empty, this method returns baseCurrency(). In case
1187     * no currency is found, @p id is searched in the loaded set of securities.
1188     *
1189     * An exception will be thrown upon erroneous situations.
1190     *
1191     * @param id QString containing the id of the MyMoneySchedule object
1192     * @return MyMoneySchedule object
1193     */
1194   MyMoneySecurity currency(const QString& id) const;
1195 
1196   /**
1197     * This method is used to retrieve the map of ancient currencies (together with their last prices)
1198     * known to the engine.
1199     *
1200     * An exception will be thrown upon erroneous situations.
1201     *
1202     * @return QMap of all MyMoneySecurity and MyMoneyPrice objects.
1203     */
1204   QMap<MyMoneySecurity, MyMoneyPrice> ancientCurrencies() const;
1205 
1206   /**
1207     * This method is used to retrieve the list of available currencies
1208     * known to the engine.
1209     *
1210     * An exception will be thrown upon erroneous situations.
1211     *
1212     * @return QList of all MyMoneySecurity objects.
1213     */
1214   QList<MyMoneySecurity> availableCurrencyList() const;
1215 
1216   /**
1217     * This method is used to retrieve the list of stored currencies
1218     * known to the engine.
1219     *
1220     * An exception will be thrown upon erroneous situations.
1221     *
1222     * @return QList of all MyMoneySecurity objects.
1223     */
1224   QList<MyMoneySecurity> currencyList() const;
1225 
1226   /**
1227     * This method retrieves a MyMoneySecurity object representing
1228     * the selected base currency. If the base currency is not
1229     * selected (e.g. due to a previous call to setBaseCurrency())
1230     * a standard MyMoneySecurity object will be returned. See
1231     * MyMoneySecurity() for details.
1232     *
1233     * An exception will be thrown upon erroneous situations.
1234     *
1235     * @return MyMoneySecurity describing base currency
1236     */
1237   MyMoneySecurity baseCurrency() const;
1238 
1239   /**
1240     * This method returns the foreign currency of the given two
1241     * currency ids. If second is the base currency id then @a first
1242     * is returned otherwise @a second is returned.
1243     */
1244   QString foreignCurrency(const QString& first, const QString& second) const;
1245 
1246   /**
1247     * This method allows to select the base currency. It does
1248     * not perform any changes to the data in the engine. It merely
1249     * stores a reference to the base currency. The currency
1250     * passed as argument must exist in the engine.
1251     *
1252     * An exception will be thrown upon erroneous situations.
1253     *
1254     * @param currency
1255     */
1256   void setBaseCurrency(const MyMoneySecurity& currency);
1257 
1258   /**
1259     * This method adds/replaces a price to/from the price list
1260     */
1261   void addPrice(const MyMoneyPrice& price);
1262 
1263   /**
1264     * This method removes a price from the price list
1265     */
1266   void removePrice(const MyMoneyPrice& price);
1267 
1268   /**
1269     * This method is used to retrieve a price for a specific security
1270     * on a specific date. If there is no price for this date, the last
1271     * known price for this currency is used. If no price information
1272     * is available, 1.0 will be returned as price.
1273     *
1274     * @param fromId the id of the currency in question
1275     * @param toId the id of the currency to convert to (if empty, baseCurrency)
1276     * @param date the date for which the price should be returned (default = today)
1277     * @param exactDate if true, entry for date must exist, if false any price information
1278     *                  with a date less or equal to @p date will be returned
1279     *
1280     * @return price found as MyMoneyPrice object
1281     * @note This throws an exception when the base currency is not set and toId is empty
1282     */
1283   MyMoneyPrice price(const QString& fromId, const QString& toId, const QDate& date, const bool exactDate = false) const;
1284   MyMoneyPrice price(const QString& fromId, const QString& toId) const;
1285   MyMoneyPrice price(const QString& fromId) const;
1286 
1287   /**
1288     * This method returns a list of all prices.
1289     *
1290     * @return MyMoneyPriceList of all MyMoneyPrice objects.
1291     */
1292   MyMoneyPriceList priceList() const;
1293 
1294   /**
1295     * This method allows to interrogate the engine, if a known account
1296     * with id @p id has a subaccount with the name @p name.
1297     *
1298     * @param id id of the account to look at
1299     * @param name account name that needs to be searched force
1300     * @retval true account with name @p name found as subaccounts
1301     * @retval false no subaccount present with that name
1302     */
1303   bool hasAccount(const QString& id, const QString& name) const;
1304 
1305   /**
1306     * This method is used to retrieve the list of all reports
1307     * known to the engine.
1308     *
1309     * An exception will be thrown upon erroneous situations.
1310     *
1311     * @return QList of all MyMoneyReport objects.
1312     */
1313   QList<MyMoneyReport> reportList() const;
1314 
1315   /**
1316     * Adds a report to the file-global institution pool. A
1317     * respective report-ID will be generated for this object.
1318     * The ID is stored as QString in the object passed as argument.
1319     *
1320     * An exception will be thrown upon error conditions.
1321     *
1322     * @param report The complete report information in a
1323     *        MyMoneyReport object
1324     */
1325   void addReport(MyMoneyReport& report);
1326 
1327   /**
1328     * Modifies an already existing report in the file global
1329     * report pool.
1330     *
1331     * An exception will be thrown upon error conditions.
1332     *
1333     * @param report The complete new report information
1334     */
1335   void modifyReport(const MyMoneyReport& report);
1336 
1337   /**
1338     * This method returns the number of reports currently known to file
1339     * in the range 0..MAXUINT
1340     *
1341     * @return number of reports known to file
1342     */
1343   unsigned countReports() const;
1344 
1345   /**
1346     * This method is used to retrieve a single MyMoneyReport object.
1347     * The id of the object must be supplied in the parameter @p id.
1348     *
1349     * An exception will be thrown upon erroneous situations.
1350     *
1351     * @param id QString containing the id of the MyMoneyReport object
1352     * @return MyMoneyReport object
1353     */
1354   MyMoneyReport report(const QString& id) const;
1355 
1356   /**
1357     * This method is used to remove an existing MyMoneyReport object
1358     * from the engine. The id attribute of the object must be set.
1359     *
1360     * An exception will be thrown upon erroneous situations.
1361     *
1362     * @param report const reference to the MyMoneyReport object to be updated
1363     */
1364   void removeReport(const MyMoneyReport& report);
1365 
1366   /**
1367     * This method is used to retrieve the list of all budgets
1368     * known to the engine.
1369     *
1370     * An exception will be thrown upon erroneous situations.
1371     *
1372     * @return QList of all MyMoneyBudget objects.
1373     */
1374   QList<MyMoneyBudget> budgetList() const;
1375 
1376   /**
1377     * Adds a budget to the file-global institution pool. A
1378     * respective budget-ID will be generated for this object.
1379     * The ID is stored as QString in the object passed as argument.
1380     *
1381     * An exception will be thrown upon error conditions.
1382     *
1383     * @param budget The complete budget information in a
1384     *        MyMoneyBudget object
1385     */
1386   void addBudget(MyMoneyBudget &budget);
1387 
1388 
1389   /**
1390     * This method is used to retrieve the id to a corresponding
1391     * name of a budget.
1392     * An exception will be thrown upon error conditions.
1393     *
1394     * @param budget QString reference to name of budget
1395     *
1396     * @return MyMoneyBudget reference to object of budget
1397     */
1398   MyMoneyBudget budgetByName(const QString& budget) const;
1399 
1400 
1401   /**
1402     * Modifies an already existing budget in the file global
1403     * budget pool.
1404     *
1405     * An exception will be thrown upon error conditions.
1406     *
1407     * @param budget The complete new budget information
1408     */
1409   void modifyBudget(const MyMoneyBudget& budget);
1410 
1411   /**
1412     * This method returns the number of budgets currently known to file
1413     * in the range 0..MAXUINT
1414     *
1415     * @return number of budgets known to file
1416     */
1417   unsigned countBudgets() const;
1418 
1419   /**
1420     * This method is used to retrieve a single MyMoneyBudget object.
1421     * The id of the object must be supplied in the parameter @p id.
1422     *
1423     * An exception will be thrown upon erroneous situations.
1424     *
1425     * @param id QString containing the id of the MyMoneyBudget object
1426     * @return MyMoneyBudget object
1427     */
1428   MyMoneyBudget budget(const QString& id) const;
1429 
1430   /**
1431     * This method is used to remove an existing MyMoneyBudget object
1432     * from the engine. The id attribute of the object must be set.
1433     *
1434     * An exception will be thrown upon erroneous situations.
1435     *
1436     * @param budget const reference to the MyMoneyBudget object to be updated
1437     */
1438   void removeBudget(const MyMoneyBudget& budget);
1439 
1440   /**
1441     * This method is used to add a VAT split to a transaction.
1442     *
1443     * @param transaction reference to the transaction
1444     * @param account reference to the account
1445     * @param category reference to the category
1446     * @param amount reference to the amount of the VAT split
1447     *
1448     * @return true if a VAT split has been added
1449     */
1450   bool addVATSplit(MyMoneyTransaction& transaction, const MyMoneyAccount& account, const MyMoneyAccount& category, const MyMoneyMoney& amount) const;
1451 
1452   /**
1453     * This method checks if the @a transaction has two or three splits and
1454     * one references an asset or liability, one references an income or expense and one
1455     * references a tax account. All three accounts must be denominated in the same
1456     * transaction.commodity(). Also, if there is a tax split it must reference the
1457     * same account as the one that is assigned to the income/expense category.
1458     *
1459     * If that all matches, the @a transaction is updated such that the amount
1460     * of the asset/liability is split according to the tax settings.
1461     *
1462     * @param transaction reference to the transaction
1463     */
1464   void updateVAT(MyMoneyTransaction& transaction) const;
1465 
1466   /**
1467     * This method checks, if the given @p object is referenced
1468     * by another engine object.
1469     *
1470     * @param obj const reference to object to be checked
1471     * @param skipCheck QBitArray with eStorage::Reference bits set for which
1472     *                  the check should be skipped
1473     *
1474     * @retval false @p object is not referenced
1475     * @retval true @p institution is referenced
1476     */
1477   bool isReferenced(const MyMoneyObject& obj, const QBitArray& skipCheck) const;
1478   bool isReferenced(const MyMoneyObject& obj) const;
1479 
1480   /**
1481     * Returns true if any of the accounts referenced by the splits
1482     * of transaction @a t is closed.
1483     */
1484   bool referencesClosedAccount(const MyMoneyTransaction& t) const;
1485 
1486   /**
1487     * Returns true if the accounts referenced by the split @a s is closed.
1488     */
1489   bool referencesClosedAccount(const MyMoneySplit& s) const;
1490 
1491   /**
1492     * This method checks if the given check no &p no is used in
1493     * a transaction referencing account &p accId. If  @p accId is empty,
1494     * @p false is returned.
1495     *
1496     * @param accId id of account to checked
1497     * @param no check number to be verified if used or not
1498     * @retval false @p no is not in use
1499     * @retval true @p no is already assigned
1500     */
1501   bool checkNoUsed(const QString& accId, const QString& no) const;
1502 
1503   /**
1504     * This method returns the highest assigned check no for
1505     * account @p accId.
1506     *
1507     * @param accId id of account to be scanned
1508     * @return highest check no. used
1509     */
1510   QString highestCheckNo(const QString& accId) const;
1511 
1512 
1513   /**
1514     * This method checks if there is a transaction
1515     * after the date @p date for account @p accId.
1516     *
1517     * @param accId id of account to be scanned
1518     * @param date date to compare with
1519     * @retval false if there is no transaction after @p date
1520     * @retval true if there is a transaction after @p date
1521     */
1522   bool hasNewerTransaction(const QString& accId, const QDate& date) const;
1523 
1524 
1525   /**
1526     * Clear all internal caches (used internally for performance measurements)
1527     */
1528   void clearCache();
1529 
1530   void forceDataChanged();
1531 
1532   /**
1533     * This returns @p true if file and online balance of a specific
1534     * @p account are matching. Returns false if there is no online balance.
1535     *
1536     * @param account @p account to be checked
1537     * @retval false if @p account has balance mismatch or if there is no online balance.
1538     * @retval true if @p account has matching balances
1539     */
1540   bool hasMatchingOnlineBalance(const MyMoneyAccount& account) const;
1541 
1542   /**
1543     * This returns the number of transactions of a specific reconciliation state @p state of account with id @p accId.
1544     *
1545     * @param accId @p accId is the account id of account to be checked
1546     * @param state @p state reconciliation state
1547     * @return number of transactions with state @p state
1548     */
1549   int countTransactionsWithSpecificReconciliationState(const QString& accId, eMyMoney::TransactionFilter::State state) const;
1550   QMap< QString, QVector<int> > countTransactionsWithSpecificReconciliationState() const;
1551 
1552   /**
1553    * @brief Saves a new onlineJob
1554    * @param job you stay owner of the object (a copy will be created)
1555    */
1556   void addOnlineJob(onlineJob& job);
1557 
1558   /**
1559    * @brief Saves a onlineJob
1560    * @param job you stay owner of the object (a copy will be created)
1561    */
1562   void modifyOnlineJob(const onlineJob job);
1563 
1564   /**
1565    * @brief Returns onlineJob identified by jobId
1566    * @param jobId
1567    * @return
1568    */
1569   onlineJob getOnlineJob(const QString &jobId) const;
1570 
1571   /**
1572    * @brief Returns all onlineJobs
1573    * @return all online jobs, caller gains ownership
1574    */
1575   QList<onlineJob> onlineJobList() const;
1576 
1577   /**
1578    * @brief Returns the number of onlineJobs
1579    */
1580   int countOnlineJobs() const;
1581 
1582   /**
1583    * @brief Remove onlineJob
1584    *
1585    * @note Removing an onlineJob fails if it is locked
1586    */
1587   void removeOnlineJob(const onlineJob& job);
1588 
1589   /**
1590    * @brief Removes multiple onlineJobs by id
1591    *
1592    * @note Removing an onlineJob fails if it is locked
1593    */
1594   void removeOnlineJob(const QStringList onlineJobIds);
1595 
1596 protected:
1597   /**
1598     * This is the constructor for a new empty file description
1599     */
1600   MyMoneyFile();
1601 
1602 Q_SIGNALS:
1603   /**
1604    * This signal is emitted when a transaction has been committed and
1605    * the notifications are about to be sent out.
1606    */
1607   void beginChangeNotification();
1608 
1609   /**
1610    * This signal is emitted when a transaction has been committed and
1611    * all notifications have been sent out.
1612    */
1613   void endChangeNotification();
1614 
1615   /**
1616     * This signal is emitted whenever any data has been changed in the engine
1617     * via any of the methods of this object
1618     */
1619   void dataChanged();
1620 
1621   /**
1622     * This signal is emitted by the engine whenever a new object
1623     * had been added. The data for the new object is contained in
1624     * @a obj.
1625     */
1626   void objectAdded(eMyMoney::File::Object objType, const QString& id);
1627 
1628   /**
1629     * This signal is emitted by the engine whenever an object
1630     * had been removed.
1631     *
1632     * @note: The data contained in @a obj is only for reference
1633     * purposes and should not be used to call any MyMoneyFile
1634     * method anymore as the object is already deleted in the storage
1635     * when the signal is emitted.
1636     */
1637   void objectRemoved(eMyMoney::File::Object objType, const QString& id);
1638 
1639   /**
1640     * This signal is emitted by the engine whenever an object
1641     * had been changed. The new state of the object is contained
1642     * in @a obj.
1643     */
1644   void objectModified(eMyMoney::File::Object objType, const QString& id);
1645 
1646   /**
1647     * This signal is emitted by the engine whenever the balance
1648     * of an account had been changed by adding, modifying or
1649     * removing transactions from the MyMoneyFile object.
1650     */
1651   void balanceChanged(const MyMoneyAccount& acc);
1652 
1653   /**
1654     * This signal is emitted by the engine whenever the value
1655     * of an account had been changed by adding or removing
1656     * prices from the MyMoneyFile object.
1657     */
1658   void valueChanged(const MyMoneyAccount& acc);
1659 
1660 private:
1661   static MyMoneyFile file;
1662 
1663   MyMoneyFile& operator=(MyMoneyFile&); // not allowed for singleton
1664   MyMoneyFile(const MyMoneyFile&);      // not allowed for singleton
1665 
1666   QString locateSubAccount(const MyMoneyAccount& base, const QString& category) const;
1667 
1668   void ensureDefaultCurrency(MyMoneyAccount& acc) const;
1669 
1670   void warningMissingRate(const QString& fromId, const QString& toId) const;
1671 
1672   /**
1673     * This method creates an opening balances account. The name is constructed
1674     * using MyMoneyFile::openingBalancesPrefix() and appending " (xxx)" in
1675     * case the @p security is not the baseCurrency(). The account created
1676     * will be a sub-account of the standard equity account provided by equity().
1677     *
1678     * @param security Security for which the account is searched
1679     */
1680   MyMoneyAccount createOpeningBalanceAccount(const MyMoneySecurity& security);
1681 
1682   MyMoneyAccount openingBalanceAccount_internal(const MyMoneySecurity& security) const;
1683 
1684   /**
1685    * Make sure that the splits value has the precision of the corresponding account
1686    */
1687   void fixSplitPrecision(MyMoneyTransaction& t) const;
1688 
1689 private:
1690   /// \internal d-pointer class.
1691   class Private;
1692   /// \internal d-pointer instance.
1693   Private* const d;
1694 };
1695 
1696 class MyMoneyFileTransactionPrivate;
1697 class KMM_MYMONEY_EXPORT MyMoneyFileTransaction
1698 {
1699   Q_DISABLE_COPY(MyMoneyFileTransaction)
1700 
1701 public:
1702   MyMoneyFileTransaction();
1703   ~MyMoneyFileTransaction();
1704 
1705   /**
1706    * Commit the current transaction.
1707    *
1708    * @warning Make sure not to use any variable that might have been altered by
1709    *          the transaction. Please keep in mind, that changing transactions
1710    *          can also affect account objects. If you still need those variables
1711    *          just reload them from the engine.
1712    */
1713   void commit();
1714   void rollback();
1715   void restart();
1716 
1717 private:
1718   MyMoneyFileTransactionPrivate * const d_ptr;
1719   Q_DECLARE_PRIVATE(MyMoneyFileTransaction)
1720 };
1721 
1722 #endif
1723 
1724