1 /*
2 * Copyright 2004-2006 Ace Jones <acejones@users.sourceforge.net>
3 * Copyright 2006 Darren Gould <darren_gould@gmx.de>
4 * Copyright 2007-2010 Alvaro Soliverez <asoliverez@gmail.com>
5 * Copyright 2017-2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
6 * Copyright 2018 Michael Kiefer <Michael-Kiefer@web.de>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #ifndef MYMONEYREPORT_H
23 #define MYMONEYREPORT_H
24
25 // ----------------------------------------------------------------------------
26 // QT Includes
27
28 // ----------------------------------------------------------------------------
29 // Project Includes
30 #include "mymoneyobject.h"
31 #include "mymoneytransactionfilter.h"
32 #include "kmm_mymoney_export.h"
33 #include "mymoneyunittestable.h"
34
35 class QString;
36 class MyMoneyAccount;
37
38 template <typename T> class QList;
39
40 namespace eMyMoney { namespace Account { enum class Type; }
41 namespace TransactionFilter { enum class Date; } }
42
43 namespace eMyMoney { namespace Report { enum class RowType; } }
44 namespace eMyMoney { namespace Report { enum class ReportType; } }
45 namespace eMyMoney { namespace Report { enum class ColumnType; } }
46 namespace eMyMoney { namespace Report { enum QueryColumn : int; } }
47 namespace eMyMoney { namespace Report { enum class DetailLevel; } }
48 namespace eMyMoney { namespace Report { enum class InvestmentSum; } }
49 namespace eMyMoney { namespace Report { enum class ChartType; } }
50 namespace eMyMoney { namespace Report { enum class DataLock; } }
51 namespace eMyMoney { namespace Report { enum class ChartPalette; } }
52
53 /**
54 * This class defines a report within the MyMoneyEngine. The report class
55 * contains all the configuration parameters needed to run a report, plus
56 * XML serialization.
57 *
58 * A report is a transactionfilter, so any report can specify which
59 * transactions it's interested down to the most minute level of detail.
60 * It extends the transactionfilter by providing identification (name,
61 * comments, group type, etc) as well as layout information (what kind
62 * of layout should be used, how the rows & columns should be presented,
63 * currency converted, etc.)
64 *
65 * As noted above, this class only provides a report DEFINITION. The
66 * generation and presentation of the report itself are left to higher
67 * level classes.
68 *
69 * @author Ace Jones <acejones@users.sourceforge.net>
70 */
71
72 class MyMoneyReportPrivate;
73 class KMM_MYMONEY_EXPORT MyMoneyReport: public MyMoneyObject, public MyMoneyTransactionFilter
74 {
75 Q_DECLARE_PRIVATE_D(MyMoneyObject::d_ptr, MyMoneyReport)
76
77 KMM_MYMONEY_UNIT_TESTABLE
78
79 public:
80 MyMoneyReport();
81 explicit MyMoneyReport(const QString &id);
82
83 explicit MyMoneyReport(eMyMoney::Report::RowType rt,
84 unsigned ct,
85 eMyMoney::TransactionFilter::Date dl,
86 eMyMoney::Report::DetailLevel ss,
87 const QString& name,
88 const QString& comment);
89
90 MyMoneyReport(const QString& id,
91 const MyMoneyReport& other);
92
93 MyMoneyReport(const MyMoneyReport & other);
94 MyMoneyReport(MyMoneyReport && other);
95 MyMoneyReport & operator=(MyMoneyReport other);
96 friend void swap(MyMoneyReport& first, MyMoneyReport& second);
97
98 ~MyMoneyReport();
99
100 eMyMoney::Report::ReportType reportType() const;
101 void setReportType(eMyMoney::Report::ReportType rt);
102
103 QString name() const;
104 void setName(const QString& s);
105
106 bool isShowingRowTotals() const;
107 void setShowingRowTotals(bool f);
108
109 bool isShowingColumnTotals() const;
110 void setShowingColumnTotals(bool f);
111
112 eMyMoney::Report::RowType rowType() const;
113 void setRowType(eMyMoney::Report::RowType rt);
114 bool isRunningSum() const;
115
116 eMyMoney::Report::ColumnType columnType() const;
117 void setColumnType(eMyMoney::Report::ColumnType ct);
118
119 bool isConvertCurrency() const;
120 void setConvertCurrency(bool f);
121 uint columnPitch() const;
122
123 QString comment() const;
124 void setComment(const QString& comment);
125
126 eMyMoney::Report::QueryColumn queryColumns() const;
127 void setQueryColumns(eMyMoney::Report::QueryColumn qc);
128
129 QString group() const;
130 void setGroup(const QString& group);
131
132 bool isFavorite() const;
133 void setFavorite(bool f);
134
135 bool isTax() const;
136 void setTax(bool f);
137
138 bool isInvestmentsOnly() const;
139 void setInvestmentsOnly(bool f);
140
141 bool isLoansOnly() const;
142 void setLoansOnly(bool f);
143
144 eMyMoney::Report::DetailLevel detailLevel() const;
145 void setDetailLevel(eMyMoney::Report::DetailLevel detail);
146
147 eMyMoney::Report::InvestmentSum investmentSum() const;
148 void setInvestmentSum(eMyMoney::Report::InvestmentSum sum);
149
150 bool isHideTransactions() const;
151 void setHideTransactions(bool f);
152
153 eMyMoney::Report::ChartType chartType() const;
154 void setChartType(eMyMoney::Report::ChartType type);
155
156 eMyMoney::Report::ChartPalette chartPalette() const;
157 void setChartPalette(eMyMoney::Report::ChartPalette type);
158
159 bool isChartDataLabels() const;
160 void setChartDataLabels(bool f);
161
162 bool isChartCHGridLines() const;
163 void setChartCHGridLines(bool f);
164
165 bool isChartSVGridLines() const;
166 void setChartSVGridLines(bool f);
167
168 bool isChartByDefault() const;
169 void setChartByDefault(bool f);
170
171 uint chartLineWidth() const;
172 void setChartLineWidth(uint f);
173
174 bool isLogYAxis() const;
175 void setLogYAxis(bool f);
176
177 bool isNegExpenses() const;
178 void setNegExpenses(bool f);
179
180 QString dataRangeStart() const;
181 void setDataRangeStart(const QString& f);
182
183 QString dataRangeEnd() const;
184 void setDataRangeEnd(const QString& f);
185
186 QString dataMajorTick() const;
187 void setDataMajorTick(const QString& f);
188
189 QString dataMinorTick() const;
190 void setDataMinorTick(const QString& f);
191
192 uint yLabelsPrecision() const;
193 void setYLabelsPrecision(int f);
194
195 bool isIncludingSchedules() const;
196 void setIncludingSchedules(bool f);
197
198 bool isColumnsAreDays() const;
199 void setColumnsAreDays(bool f);
200
201 bool isIncludingTransfers() const;
202 void setIncludingTransfers(bool f);
203
204 bool isIncludingUnusedAccounts() const;
205 void setIncludingUnusedAccounts(bool f);
206
207 bool hasBudget() const;
208 QString budget() const;
209
210 /**
211 * Sets the budget used for this report
212 *
213 * @param budget The ID of the budget to use, or an empty string
214 * to indicate a budget is NOT included
215 * @param fa Whether to display actual data alongside the budget.
216 * Setting to false means the report displays ONLY the budget itself.
217 * @warning For now, the budget ID is ignored. The budget id is
218 * simply checked for any non-empty string, and if so, hasBudget()
219 * will return true.
220 */
221 void setBudget(const QString& budget, bool fa = true);
222
223 bool isIncludingBudgetActuals() const;
224 void setIncludingBudgetActuals(bool f);
225
226 bool isIncludingForecast() const;
227 void setIncludingForecast(bool f);
228
229 bool isIncludingMovingAverage() const;
230 void setIncludingMovingAverage(bool f);
231
232 int movingAverageDays() const;
233 void setMovingAverageDays(int days);
234
235 bool isIncludingPrice() const;
236 void setIncludingPrice(bool f);
237
238 bool isIncludingAveragePrice() const;
239 void setIncludingAveragePrice(bool f);
240
241 eMyMoney::Report::DataLock dataFilter() const;
242 bool isDataUserDefined() const;
243 void setDataFilter(eMyMoney::Report::DataLock u);
244
245 eMyMoney::TransactionFilter::Date dateRange() const;
246 bool isDateUserDefined() const;
247
248 /**
249 * Set the underlying date filter and LOCK that filter to the specified
250 * range. For example, if @p _u is "CurrentMonth", this report should always
251 * be updated to the current month no matter when the report is run.
252 *
253 * This updating is not entirely automatic, you should update it yourself by
254 * calling updateDateFilter.
255 *
256 * @param _u The date range constant (MyMoneyTransactionFilter::dateRangeE)
257 * which this report should be locked to.
258 */
259
260 void setDateFilter(eMyMoney::TransactionFilter::Date u);
261
262 /**
263 * Set the underlying date filter using the start and end dates provided.
264 * Note that this does not LOCK to any range like setDateFilter(unsigned)
265 * above. It is just a reimplementation of the MyMoneyTransactionFilter
266 * version.
267 *
268 * @param _db The inclusive begin date of the date range
269 * @param _de The inclusive end date of the date range
270 */
271
272 void setDateFilter(const QDate& db, const QDate& de);
273
274 /**
275 * Set the underlying date filter using the 'date lock' property.
276 *
277 * Always call this function before executing the report to be sure that
278 * the date filters properly match the plain-language 'date lock'.
279 *
280 * For example, if the report is date-locked to "Current Month", and the
281 * last time you loaded or ran the report was in August, but it's now
282 * September, this function will update the date range to be September,
283 * as is proper.
284 */
285 void updateDateFilter();
286
287 bool isMixedTime() const;
288 void setMixedTime(bool f);
289
290 int currentDateColumn() const;
291 void setCurrentDateColumn(int f);
292
293 uint settlementPeriod() const;
294 void setSettlementPeriod(uint days);
295
296 bool isShowingSTLTCapitalGains() const;
297 void setShowSTLTCapitalGains(bool f);
298
299 QDate termSeparator() const;
300 void setTermSeparator(const QDate& date);
301
302 bool isSkippingZero() const;
303 void setSkipZero(int f);
304
305 /**
306 * This method allows you to clear the underlying transaction filter
307 */
308 void clearTransactionFilter();
309
310 /**
311 * This method allows you to set the underlying transaction filter
312 *
313 * @param _filter The filter which should replace the existing transaction
314 * filter.
315 */
316 void assignFilter(const MyMoneyTransactionFilter& filter);
317
318 /**
319 * Retrieves a VALID beginning & ending date for this report.
320 *
321 * The underlying date filter can return en empty QDate() for either the
322 * begin or end date or both. This is typically unacceptable for reports,
323 * which need the REAL begin and end date.
324 *
325 * This function gets the underlying date filter range, and if either is
326 * an empty QDate(), it determines the missing date from looking at all
327 * the transactions which match the underlying filter, and returning the
328 * date of the first or last transaction (as appropriate).
329 *
330 * @param _db The inclusive begin date of the date range
331 * @param _de The inclusive end date of the date range
332 */
333 void validDateRange(QDate &db, QDate &de);
334
335 /**
336 * This method turns on the account group filter and adds the
337 * @p type to the list of allowed groups.
338 *
339 * Note that account group filtering is handled differently
340 * than all the filters of the underlying class. This filter
341 * is meant to be applied to individual splits of matched
342 * transactions AFTER the underlying filter is used to find
343 * the matching transactions.
344 *
345 * @param type the account group to add to the allowed groups list
346 */
347 void addAccountGroup(eMyMoney::Account::Type type);
348
349 /**
350 * This method returns whether an account group filter has been set,
351 * and if so, it returns all the account groups set in the filter.
352 *
353 * @param list list to append account groups into
354 * @return return true if an account group filter has been set
355 */
356 bool accountGroups(QList<eMyMoney::Account::Type>& list) const;
357
358 /**
359 * This method returns whether the specified account group
360 * is allowed by the account groups filter.
361 *
362 * @param type group to append account groups into
363 * @return return true if an account group filter has been set
364 */
365 bool includesAccountGroup(eMyMoney::Account::Type type) const;
366
367 /**
368 * This method is used to test whether a specific account
369 * passes the accountGroup test and either the Account or
370 * Category test, depending on which sort of Account it is.
371 *
372 * The m_tax and m_investments properties are also considered.
373 *
374 * @param acc the account in question
375 * @return true if account is in filter set, false otherwise
376 */
377 bool includes(const MyMoneyAccount& acc) const;
378
379 /**
380 * This method checks if a reference to the given object exists. It returns,
381 * a @p true if the object is referencing the one requested by the
382 * parameter @p id. If it does not, this method returns @p false.
383 *
384 * @param id id of the object to be checked for references
385 * @retval true This object references object with id @p id.
386 * @retval false This object does not reference the object with id @p id.
387 */
388 bool hasReferenceTo(const QString& id) const override;
389
390 /**
391 * Return row type as string.
392 *
393 * @param type type to get string for
394 * @return row type converted to string
395 */
396 static QString toString(eMyMoney::Report::RowType type);
397
398 /**
399 * Return report type as string.
400 *
401 * @param type report type to get string for
402 * @return report type converted to string
403 */
404 static QString toString(eMyMoney::Report::ReportType type);
405
406 /**
407 * This method allows to modify and retrieve the default lineWidth for graphs.
408 * The default is 2.
409 */
410 static void setLineWidth(int width);
411 static int lineWidth();
412
413 // set the expert mode which shows equity accounts for some reports
414 static void setExpertMode(bool expertMode);
415
416 private:
417 void addAccountGroupsByRowType(eMyMoney::Report::RowType rt);
418
419 private:
420 /**
421 * This member keeps the current setting for line graphs lineWidth.
422 * @sa setLineWidth()
423 */
424 static int m_lineWidth;
425
426 static bool m_expertMode;
427 };
428
swap(MyMoneyReport & first,MyMoneyReport & second)429 inline void swap(MyMoneyReport& first, MyMoneyReport& second) // krazy:exclude=inline
430 {
431 using std::swap;
432 swap(first.MyMoneyObject::d_ptr, second.MyMoneyObject::d_ptr);
433 swap(first.MyMoneyTransactionFilter::d_ptr, second.MyMoneyTransactionFilter::d_ptr);
434 }
435
MyMoneyReport(MyMoneyReport && other)436 inline MyMoneyReport::MyMoneyReport(MyMoneyReport && other) : MyMoneyReport() // krazy:exclude=inline
437 {
438 swap(*this, other);
439 }
440
441 inline MyMoneyReport & MyMoneyReport::operator=(MyMoneyReport other) // krazy:exclude=inline
442 {
443 swap(*this, other);
444 return *this;
445 }
446
447 /**
448 * Make it possible to hold @ref MyMoneyReport objects inside @ref QVariant objects.
449 */
450 Q_DECLARE_METATYPE(MyMoneyReport)
451
452 #endif // MYMONEYREPORT_H
453