summaryrefslogtreecommitdiffstats
path: root/kmymoney2/reports/pivottable.h
blob: 26ac53c6d74002d529eae7b63d59362637b64f49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
/***************************************************************************
                          pivottable.h
                             -------------------
    begin                : Sat May 22 2004
    copyright            : (C) 2004-2005 by Ace Jones
    email                : <ace.j@hotpop.com>
                           Thomas Baumgart <ipwizard@users.sourceforge.net>
                           Alvaro Soliverez <asoliverez@gmail.com>
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef PIVOTTABLE_H
#define PIVOTTABLE_H

// ----------------------------------------------------------------------------
// QT Includes
#include <tqmap.h>
#include <tqvaluelist.h>

// ----------------------------------------------------------------------------
// KDE Includes

// ----------------------------------------------------------------------------
// Project Includes
#include "kreportchartview.h"
#include "../mymoney/mymoneyfile.h"
#include "../mymoney/mymoneyreport.h"
#include "reporttable.h"
#include "pivotgrid.h"
#include "reportaccount.h"

namespace reports {

/**
  * Calculates a 'pivot table' of information about the transaction database.
  * Based on pivot tables in MS Excel, and implemented as 'Data Pilot' in
  * OpenOffice.Org Calc.
  *
  *              | Month,etc
  * -------------+------------
  * Expense Type | Sum(Value)
  *   Category   |
  *
  * This is a middle-layer class, between the UI and the engine.  The
  * MyMoneyReport class holds only the CONFIGURATION parameters.  This
  * class actually does the work of retrieving the data from the engine
  * and formatting it for the user.
  *
  * @author Ace Jones
  *
  * @short
**/
class PivotTable : public ReportTable
{
public:
  /**
    * Create a Pivot table style report
    *
    * @param _config_f The configuration parameters for this report
    */
    PivotTable( const MyMoneyReport& _config_f );

  /**
    * virtual Destructur
    */
    virtual ~PivotTable() {}

  /**
    * Render the report to an HTML stream.
    *
    * @return TQString HTML string representing the report
    */
    TQString renderHTML( void ) const;
  /**
    * Render the report to a comma-separated-values stream.
    *
    * @return TQString CSV string representing the report
    */
    TQString renderCSV( void ) const;

  /**
    * Render the report to a graphical chart
    *
    * @param view The KReportChartView into which to draw the chart.
    */
    void drawChart( KReportChartView& view ) const;

  /**
    * Dump the report's HTML to a file
    *
    * @param file The filename to dump into
    * @param context unused, but provided for interface compatibility
    */
    void dump( const TQString& file, const TQString& context=TQString()) const;

  /**
    * Returns the grid generated by the report
    *
    */
    PivotGrid grid(void) {return m_grid;}

protected:
  void init(void);    // used for debugging the constructor

private:

    PivotGrid m_grid;

    TQStringList m_columnHeadings;
    unsigned m_numColumns;
    TQDate m_beginDate;
    TQDate m_endDate;
    bool m_runningSumsCalculated;

    /**
      * For budget-vs-actual reports only, maps each account to the account which holds
      * the budget for it.  If an account is not contained in this map, it is not included
      * in the budget.
      */
    TQMap<TQString, TQString> m_budgetMap;

    /**
      * This list contains the types of PivotGridRows that are going to be shown in the report
      */
    TQValueList<ERowType> m_rowTypeList;

    /**
     * This list contains the i18n headers for the column types
     */
    TQValueList<TQString> m_columnTypeHeaderList;

    MyMoneyReport m_config_f;

    /**
      * This method returns the formatted value of @a amount with
      * a possible @a currencySymbol added and @a prec fractional digits.
      * @a currencySymbol defaults to be empty and @a prec defaults to 2.
      *
      * If @a amount is negative the formatted value is enclosed in an
      * HTML font tag to modify the color to reflect the user settings for
      * negtive numbers.
      *
      * Example: 1.23 is returned as '1.23' whereas -1.23 is returned as
      *          @verbatim <font color="rgb($red,$green,$blue)">-1.23</font>@endverbatim
      *          with $red, $green and $blue being the actual value for the
      *          chosen color.
      */
    TQString coloredAmount(const MyMoneyMoney& amount, const TQString& currencySymbol = TQString(), int prec = 2 ) const;

protected:
  /**
    * Creates a row in the grid if it doesn't already exist
    *
    * Downsteam assignment functions will assume that this row already
    * exists, so this function creates a row of the needed length populated
    * with zeros.
    *
    * @param outergroup The outer row group
    * @param row The row itself
    * @param recursive Whether to also recursively create rows for our tqparent accounts
    */
    void createRow( const TQString& outergroup, const ReportAccount& row, bool recursive );

  /**
    * Assigns a value into the grid
    *
    * Adds the given value to the value which already exists at the specified grid position
    *
    * @param outergroup The outer row group
    * @param row The row itself
    * @param column The column
    * @param value The value to be added in
    * @param budget Whether this is a budget value (@p true) or an actual
    *               value (@p false). Defaults to @p false.
    * @param stockSplit Wheter this is a stock split (@p true) or an actual
    *                   value (@p false). Defaults to @p false.
    */
    inline void assignCell( const TQString& outergroup, const ReportAccount& row, unsigned column, MyMoneyMoney value, bool budget = false, bool stockSplit = false );

  /**
    * Create a row for each included account. This is used when
    * the config parameter isIncludingUnusedAccount() is true
    */
    void createAccountRows(void);

  /**
    * Record the opening balances of all qualifying accounts into the grid.
    *
    * For accounts opened before the report period, places the balance into the '0' column.
    * For those opened during the report period, places the balance into the appropriate column
    * for the month when it was opened.
    */
    void calculateOpeningBalances( void );

  /**
    * Calculate budget mapping
    *
    * For budget-vs-actual reports, this creates a mapping between each account
    * in the user's hierarchy and the account where the budget is held for it.
    * This is needed because the user can budget on a given account for that
    * account and all its descendants.  Also if NO budget is placed on the
    * account or any of its tqparents, the account is not included in the map.
    */
    void calculateBudgetMapping( void );

  /**
    * Calculate the running sums.
    *
    * After calling this method, each cell of the report will contain the running sum of all
    * the cells in its row in this and earlier columns.
    *
    * For example, consider a row with these values:
    *   01 02 03 04 05 06 07 08 09 10
    *
    * After calling this function, the row will look like this:
    *   01 03 06 10 15 21 28 36 45 55
    */
    void calculateRunningSums( void );
    void calculateRunningSums( PivotInnerGroup::iterator& it_row);

   /**
     * This method calculates the difference between a @a budgeted and an @a
     * actual amount. The calculation is based on the type of the
      * @a repAccount. The difference value is calculated as follows:
     *
     * If @a repAccount is of type MyMoneyAccount::Income
     *
     * @code
     *      diff = actual - budgeted
     * @endcode
     *
     * If @a repAccount is of type MyMoneyAccount::Expense
     *
     * @code
     *      diff = budgeted - actual
     * @endcode
     *
     * In all other cases, 0 is returned.
     */
    void calculateBudgetDiff(void);

  /**
    * This method calculates forecast for a report
    */
    void calculateForecast(void);

    /**
     * This method inserts units to be used to display prices
     */
    void fillBasePriceUnit(ERowType rowType);

  /**
    * This method calculates moving average for a report
    */
    void calculateMovingAverage(void);

  /**
    * Calculate the row and column totals
    *
    * This function will set the m_total members of all the TGrid objects.  Be sure the values are
    * all converted to the base currency first!!
    *
    */
    void calculateTotals( void );

  /**
    * Convert each value in the grid to the base currency
    *
    */
    void convertToBaseCurrency( void );

  /**
    * Convert each value in the grid to the account/category's deep currency
    *
    * See AccountDescriptor::deepCurrencyPrice() for a description of 'deep' currency
    *
    */
    void convertToDeepCurrency( void );

  /**
    * Turn month-long columns into larger time periods if needed
    *
    * For example, consider a row with these values:
    *   01 02 03 04 05 06 07 08 09 10
    *
    * If the column pitch is 3 (i.e. quarterly), after calling this function,
    * the row will look like this:
    *   06 15 26 10
    */
    void collapseColumns(void);

  /**
    * Determine the proper column headings based on the time periods covered by each column
    *
    */
    void calculateColumnHeadings(void);

  /**
    * Helper methods for collapseColumns
    *
    */
    void accumulateColumn(unsigned destcolumn, unsigned sourcecolumn);
    void clearColumn(unsigned column);

  /**
    * Calculate the column of a given date.  This is the absolute column in a
    * hypothetical report that covers all of known time.  In reality an actual
    * report will be a subset of that.
    *
    * @param _date The date
    */
    unsigned columnValue(const TQDate& _date) const;

  /**
    * Calculate the date of the last day covered by a given column.
    *
    * @param column The column
    */
    TQDate columnDate(int column) const;

  /**
    * Returns the balance of a given cell. Throws an exception once calculateRunningSums() has been run.
    */
    MyMoneyMoney cellBalance(const TQString& outergroup, const ReportAccount& _row, unsigned column, bool budget);

   /**
     * Draws a PivotGridRowSet in a chart for the given ERowType
     */
    unsigned drawChartRowSet(unsigned rowNum, const bool seriesTotals, const bool accountSeries, KDChartTableData& data, const PivotGridRowSet& rowSet, const ERowType rowType ) const;

   /**
     * Loads m_rowTypeList with the list of PivotGridRow types that the reporttable
     * should show
     */
    void loadRowTypeList(void);

   /**
     * If not in expert mode, include all subaccounts for each selected
     * investment account
     */
    void includeInvestmentSubAccounts(void);
};


}
#endif
// PIVOTTABLE_H
// vim:cin:si:ai:et:ts=2:sw=2: