File indexing completed on 2024-06-23 05:02:17
0001 /* 0002 SPDX-FileCopyrightText: 2005-2006 Ace Jones <acejones@users.sourceforge.net> 0003 SPDX-FileCopyrightText: 2005-2018 Thomas Baumgart <tbaumgart@kde.org> 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef PIVOTGRID_H 0008 #define PIVOTGRID_H 0009 0010 // ---------------------------------------------------------------------------- 0011 // QT Includes 0012 0013 #include <QMap> 0014 #include <QList> 0015 0016 // ---------------------------------------------------------------------------- 0017 // KDE Includes 0018 0019 // ---------------------------------------------------------------------------- 0020 // Project Includes 0021 0022 #include "reportaccount.h" 0023 #include "mymoneymoney.h" 0024 0025 namespace reports 0026 { 0027 0028 enum ERowType {eActual, eBudget, eBudgetDiff, eForecast, eAverage, ePrice }; 0029 0030 /** 0031 * The fundamental data construct of this class is a 'grid'. It is organized as follows: 0032 * 0033 * A 'Row' is a row of money values, each column is a month. The first month corresponds to 0034 * m_beginDate. 0035 * 0036 * A 'Row Pair' is two rows of money values. Each column is the SAME month. One row is the 0037 * 'actual' values for the period, the other row is the 'budgetted' values for the same 0038 * period. For ease of implementation, a Row Pair is implemented as a Row which contains 0039 * another Row. The inherited Row is the 'actual', the contained row is the 'Budget'. 0040 * 0041 * An 'Inner Group' contains a rows for each subordinate account within a single top-level 0042 * account. It also contains a mapping from the account descriptor for the subordinate account 0043 * to its row data. So if we have an Expense account called "Computers", with sub-accounts called 0044 * "Hardware", "Software", and "Peripherals", there will be one Inner Group for "Computers" 0045 * which contains three Rows. 0046 * 0047 * An 'Outer Group' contains Inner Row Groups for all the top-level accounts in a given 0048 * account class. Account classes are Expense, Income, Asset, Liability. In the case above, 0049 * the "Computers" Inner Group is contained within the "Expense" Outer Group. 0050 * 0051 * A 'Grid' is the set of all Outer Groups contained in this report. 0052 * 0053 */ 0054 class PivotCell: public MyMoneyMoney 0055 { 0056 KMM_MYMONEY_UNIT_TESTABLE 0057 0058 public: 0059 PivotCell() : m_stockSplit(MyMoneyMoney::ONE), m_cellUsed(false) {} 0060 explicit PivotCell(const MyMoneyMoney& value); 0061 virtual ~PivotCell(); 0062 static PivotCell stockSplit(const MyMoneyMoney& factor); 0063 PivotCell operator += (const PivotCell& right); 0064 PivotCell operator += (const MyMoneyMoney& value); 0065 const QString formatMoney(int fraction, bool showThousandSeparator = true) const; 0066 const QString formatMoney(const QString& currency, const int prec, bool showThousandSeparator = true) const; 0067 MyMoneyMoney calculateRunningSum(const MyMoneyMoney& runningSum); 0068 MyMoneyMoney cellBalance(const MyMoneyMoney& _balance); 0069 bool isUsed() const { 0070 return m_cellUsed; 0071 } 0072 private: 0073 MyMoneyMoney m_stockSplit; 0074 MyMoneyMoney m_postSplit; 0075 bool m_cellUsed; 0076 }; 0077 class PivotGridRow: public QList<PivotCell> 0078 { 0079 public: 0080 0081 explicit PivotGridRow(unsigned _numcolumns = 0) { 0082 for (uint i = 0; i < _numcolumns; i++) 0083 append(PivotCell()); 0084 } 0085 MyMoneyMoney m_total; 0086 }; 0087 0088 class PivotGridRowSet: public QMap<ERowType, PivotGridRow> 0089 { 0090 public: 0091 explicit PivotGridRowSet(unsigned _numcolumns = 0); 0092 }; 0093 0094 class PivotInnerGroup: public QMap<ReportAccount, PivotGridRowSet> 0095 { 0096 public: 0097 explicit PivotInnerGroup(unsigned _numcolumns = 0): m_total(_numcolumns) {} 0098 0099 PivotGridRowSet m_total; 0100 }; 0101 0102 class PivotOuterGroup: public QMap<QString, PivotInnerGroup> 0103 { 0104 public: 0105 explicit PivotOuterGroup(unsigned _numcolumns = 0, unsigned _sort = m_kDefaultSortOrder, bool _inverted = false): m_total(_numcolumns), m_inverted(_inverted), m_sortOrder(_sort) {} 0106 bool operator<(const PivotOuterGroup& _right) const { 0107 if (m_sortOrder != _right.m_sortOrder) 0108 return m_sortOrder < _right.m_sortOrder; 0109 else 0110 return m_displayName < _right.m_displayName; 0111 } 0112 PivotGridRowSet m_total; 0113 0114 // An inverted outergroup means that all values placed in subordinate rows 0115 // should have their sign inverted from typical cash-flow notation. Also it 0116 // means that when the report is summed, the values should be inverted again 0117 // so that the grand total is really "non-inverted outergroup MINUS inverted outergroup". 0118 bool m_inverted; 0119 0120 // The localized name of the group for display in the report. Outergoups need this 0121 // independently, because they will lose their association with the TGrid when the 0122 // report is rendered. 0123 QString m_displayName; 0124 0125 // lower numbers sort toward the top of the report. defaults to 100, which is a nice 0126 // middle-of-the-road value 0127 unsigned m_sortOrder; 0128 0129 // default sort order 0130 static const unsigned m_kDefaultSortOrder; 0131 }; 0132 class PivotGrid: public QMap<QString, PivotOuterGroup> 0133 { 0134 public: 0135 PivotGridRowSet rowSet(QString id); 0136 0137 PivotGridRowSet m_total; 0138 }; 0139 0140 } 0141 0142 #endif 0143 // PIVOTGRID_H