File indexing completed on 2024-05-12 16:42:34

0001 /*
0002     SPDX-FileCopyrightText: 2006 Ace Jones <acejones@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2006 Darren Gould <darren_gould@gmx.de>
0004     SPDX-FileCopyrightText: 2017 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef MYMONEYBUDGET_H
0009 #define MYMONEYBUDGET_H
0010 
0011 // ----------------------------------------------------------------------------
0012 // QT Includes
0013 
0014 #include <QMetaType>
0015 
0016 // ----------------------------------------------------------------------------
0017 // Project Includes
0018 
0019 #include "mymoneyobject.h"
0020 #include "kmm_mymoney_export.h"
0021 #include "mymoneyunittestable.h"
0022 
0023 class QString;
0024 class QDate;
0025 class MyMoneyMoney;
0026 
0027 template <typename T> class QList;
0028 template <class Key, class T> class QMap;
0029 
0030 namespace eMyMoney {
0031 namespace Budget {
0032 enum class Level;
0033 }
0034 }
0035 
0036 /**
0037   * This class defines a Budget within the MyMoneyEngine.  The Budget class
0038   * contains all the configuration parameters needed to run a Budget, plus
0039   * XML serialization.
0040   *
0041   * As noted above, this class only provides a Budget DEFINITION.  The
0042   * generation and presentation of the Budget itself are left to higher
0043   * level classes.
0044   *
0045   * @author Darren Gould <darren_gould@gmx.de>
0046   */
0047 class MyMoneyBudgetPrivate;
0048 class KMM_MYMONEY_EXPORT MyMoneyBudget: public MyMoneyObject
0049 {
0050     Q_DECLARE_PRIVATE(MyMoneyBudget)
0051 
0052     KMM_MYMONEY_UNIT_TESTABLE
0053 
0054 public:
0055     MyMoneyBudget();
0056     explicit MyMoneyBudget(const QString &id);
0057 
0058     /**
0059       * This constructor creates an object based on the data found in the
0060       * MyMoneyBudget budget object.
0061       */
0062     MyMoneyBudget(const QString& id,
0063                   const MyMoneyBudget& other);
0064 
0065     MyMoneyBudget(const MyMoneyBudget& other);
0066     MyMoneyBudget(MyMoneyBudget && other);
0067     MyMoneyBudget & operator=(MyMoneyBudget other);
0068     friend void swap(MyMoneyBudget& first, MyMoneyBudget& second);
0069 
0070     ~MyMoneyBudget();
0071 
0072     /**
0073       * Helper class for MyMoneyBudget
0074       *
0075       * This is an abstraction of the PERIOD stored in the BUDGET/ACCOUNT tag in XML
0076       *
0077       * @author Darren Gould
0078       */
0079     class PeriodGroupPrivate;
0080     class KMM_MYMONEY_EXPORT PeriodGroup
0081     {
0082         Q_DECLARE_PRIVATE(PeriodGroup)
0083         PeriodGroupPrivate* d_ptr;
0084 
0085     public:
0086         PeriodGroup();
0087         PeriodGroup(const PeriodGroup & other);
0088         PeriodGroup(PeriodGroup && other);
0089         PeriodGroup & operator=(PeriodGroup other);
0090         friend void swap(PeriodGroup& first, PeriodGroup& second);
0091 
0092         ~PeriodGroup();
0093 
0094         QDate startDate() const;
0095         void setStartDate(const QDate& start);
0096 
0097         MyMoneyMoney amount() const;
0098         void setAmount(const MyMoneyMoney& amount);
0099 
0100         bool operator == (const PeriodGroup &right) const;
0101     };
0102 
0103     /**
0104       * Helper class for MyMoneyBudget
0105       *
0106       * This is an abstraction of the Account Data stored in the BUDGET tag in XML
0107       *
0108       * @author Darren Gould
0109       */
0110     class AccountGroupPrivate;
0111     class KMM_MYMONEY_EXPORT AccountGroup
0112     {
0113         Q_DECLARE_PRIVATE(AccountGroup)
0114         AccountGroupPrivate* d_ptr;
0115 
0116     public:
0117         AccountGroup();
0118         AccountGroup(const AccountGroup & other);
0119         AccountGroup(AccountGroup && other);
0120         AccountGroup & operator=(AccountGroup other);
0121         friend void swap(AccountGroup& first, AccountGroup& second);
0122 
0123         ~AccountGroup();
0124 
0125         QString id() const;
0126         void setId(const QString& id);
0127 
0128         bool budgetSubaccounts() const;
0129         void setBudgetSubaccounts(bool budgetsubaccounts);
0130 
0131         eMyMoney::Budget::Level budgetLevel() const;
0132         void setBudgetLevel(eMyMoney::Budget::Level level);
0133 
0134         PeriodGroup period(const QDate& date) const;
0135         void addPeriod(const QDate& date, PeriodGroup& period);
0136         const QMap<QDate, PeriodGroup> getPeriods() const;
0137         void clearPeriods();
0138 
0139         MyMoneyMoney balance() const;
0140         MyMoneyMoney totalBalance() const;
0141 
0142         // This member adds the value of another account group
0143         // m_budgetlevel is adjusted to the larger one of both
0144         // m_budgetsubaccounts remains unaffected
0145         AccountGroup operator += (const AccountGroup& right);
0146 
0147         bool operator == (const AccountGroup &right) const;
0148 
0149         bool isZero() const;
0150 
0151     protected:
0152         void convertToMonthly();
0153         void convertToYearly();
0154         void convertToMonthByMonth();
0155     };
0156 
0157     /**
0158      * This operator tests for equality of two MyMoneyBudget objects
0159      */
0160     bool operator == (const MyMoneyBudget &) const;
0161 
0162     QString name() const;
0163     void setName(const QString& name);
0164 
0165     QDate budgetStart() const;
0166     void setBudgetStart(const QDate& start);
0167 
0168     const AccountGroup & account(const QString &id) const;
0169     void setAccount(const AccountGroup& account, const QString &id);
0170 
0171     bool contains(const QString &id) const;
0172     QList<AccountGroup> getaccounts() const;
0173 
0174     QMap<QString, MyMoneyBudget::AccountGroup> accountsMap() const;
0175 
0176     /**
0177       * This method checks if a reference to the given object exists. It returns,
0178       * a @p true if the object is referencing the one requested by the
0179       * parameter @p id and the balance() returned is zero.
0180       * If it does not, this method returns @p false.
0181       *
0182       * @param id id of the object to be checked for references
0183       * @retval true This object references object with id @p id.
0184       * @retval false This object does not reference the object with id @p id.
0185       */
0186     bool hasReferenceTo(const QString& id) const override;
0187 
0188     /**
0189       * This member removes all references to object identified by @p id. Used
0190       * to remove objects which are about to be removed from the engine.
0191       */
0192     void removeReference(const QString& id);
0193 };
0194 
0195 inline void swap(MyMoneyBudget::PeriodGroup& first, MyMoneyBudget::PeriodGroup& second) // krazy:exclude=inline
0196 {
0197     using std::swap;
0198     swap(first.d_ptr, second.d_ptr);
0199 }
0200 
0201 inline MyMoneyBudget::PeriodGroup::PeriodGroup(MyMoneyBudget::PeriodGroup && other) : PeriodGroup() // krazy:exclude=inline
0202 {
0203     swap(*this, other);
0204 }
0205 
0206 inline MyMoneyBudget::PeriodGroup & MyMoneyBudget::PeriodGroup::operator=(MyMoneyBudget::PeriodGroup other) // krazy:exclude=inline
0207 {
0208     swap(*this, other);
0209     return *this;
0210 }
0211 
0212 inline void swap(MyMoneyBudget::AccountGroup& first, MyMoneyBudget::AccountGroup& second) // krazy:exclude=inline
0213 {
0214     using std::swap;
0215     swap(first.d_ptr, second.d_ptr);
0216 }
0217 
0218 inline MyMoneyBudget::AccountGroup::AccountGroup(MyMoneyBudget::AccountGroup && other) : AccountGroup() // krazy:exclude=inline
0219 {
0220     swap(*this, other);
0221 }
0222 
0223 inline MyMoneyBudget::AccountGroup & MyMoneyBudget::AccountGroup::operator=(MyMoneyBudget::AccountGroup other) // krazy:exclude=inline
0224 {
0225     swap(*this, other);
0226     return *this;
0227 }
0228 
0229 inline void swap(MyMoneyBudget& first, MyMoneyBudget& second) // krazy:exclude=inline
0230 {
0231     using std::swap;
0232     swap(first.d_ptr, second.d_ptr);
0233 }
0234 
0235 inline MyMoneyBudget::MyMoneyBudget(MyMoneyBudget && other) : MyMoneyBudget() // krazy:exclude=inline
0236 {
0237     swap(*this, other);
0238 }
0239 
0240 inline MyMoneyBudget & MyMoneyBudget::operator=(MyMoneyBudget other) // krazy:exclude=inline
0241 {
0242     swap(*this, other);
0243     return *this;
0244 }
0245 
0246 /**
0247   * Make it possible to hold @ref MyMoneyBudget objects inside @ref QVariant objects.
0248   */
0249 Q_DECLARE_METATYPE(MyMoneyBudget)
0250 
0251 #endif // MYMONEYBudget_H