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 #include "mymoneyreport_p.h"
23
24 // ----------------------------------------------------------------------------
25 // QT Includes
26
27 // ----------------------------------------------------------------------------
28 // KDE Includes
29
30 // ----------------------------------------------------------------------------
31 // Project Includes
32
33 #include "mymoneymoney.h"
34 #include "mymoneyfile.h"
35 #include "mymoneyaccount.h"
36 #include "mymoneytransaction.h"
37 #include "mymoneytransactionfilter.h"
38 #include "mymoneyexception.h"
39
MyMoneyReport()40 MyMoneyReport::MyMoneyReport() :
41 MyMoneyObject(*new MyMoneyReportPrivate)
42 {
43 }
44
MyMoneyReport(const QString & id)45 MyMoneyReport::MyMoneyReport(const QString &id) :
46 MyMoneyObject(*new MyMoneyReportPrivate, id)
47 {
48 }
49
MyMoneyReport(eMyMoney::Report::RowType rt,unsigned ct,eMyMoney::TransactionFilter::Date dl,eMyMoney::Report::DetailLevel ss,const QString & name,const QString & comment)50 MyMoneyReport::MyMoneyReport(eMyMoney::Report::RowType rt,
51 unsigned ct,
52 eMyMoney::TransactionFilter::Date dl,
53 eMyMoney::Report::DetailLevel ss,
54 const QString& name,
55 const QString& comment) :
56 MyMoneyObject(*new MyMoneyReportPrivate)
57 {
58 Q_D(MyMoneyReport);
59 d->m_name = name;
60 d->m_comment = comment;
61 d->m_detailLevel = ss;
62 d->m_investmentSum = ct & eMyMoney::Report::QueryColumn::CapitalGain ? eMyMoney::Report::InvestmentSum::Sold : eMyMoney::Report::InvestmentSum::Period;
63 d->m_reportType = d->rowTypeToReportType(rt);
64 d->m_rowType = rt;
65 d->m_dateLock = dl;
66
67 //set report type
68 if (d->m_reportType == eMyMoney::Report::ReportType::PivotTable)
69 d->m_columnType = static_cast<eMyMoney::Report::ColumnType>(ct);
70 if (d->m_reportType == eMyMoney::Report::ReportType::QueryTable)
71 d->m_queryColumns = static_cast<eMyMoney::Report::QueryColumn>(ct);
72 setDateFilter(dl);
73
74 //throw exception if the type is inconsistent
75 if (d->rowTypeToReportType(rt) == eMyMoney::Report::ReportType::Invalid ||
76 d->m_reportType == eMyMoney::Report::ReportType::NoReport)
77 throw MYMONEYEXCEPTION_CSTRING("Invalid report type");
78
79 //add the corresponding account groups
80 addAccountGroupsByRowType(rt);
81 switch(rt) {
82 case eMyMoney::Report::RowType::AssetLiability:
83 case eMyMoney::Report::RowType::Account:
84 case eMyMoney::Report::RowType::ExpenseIncome:
85 d->m_showRowTotals = true;
86 break;
87 default:
88 break;
89 }
90
91 #ifdef DEBUG_REPORTS
92 QDebug out = qDebug();
93 out << _name << toString(_rt) << toString(m_reportType);
94 foreach(const eMyMoney::Account::Type accountType, m_accountGroups)
95 out << MyMoneyeMyMoney::Account::accountTypeToString(accountType);
96 if (m_accounts.size() > 0)
97 out << m_accounts;
98 #endif
99 }
100
MyMoneyReport(const MyMoneyReport & other)101 MyMoneyReport::MyMoneyReport(const MyMoneyReport& other) :
102 MyMoneyObject(*new MyMoneyReportPrivate(*other.d_func()), other.id()),
103 MyMoneyTransactionFilter(other)
104 {
105 }
106
MyMoneyReport(const QString & id,const MyMoneyReport & other)107 MyMoneyReport::MyMoneyReport(const QString& id, const MyMoneyReport& other) :
108 MyMoneyObject(*new MyMoneyReportPrivate(*other.d_func()), id),
109 MyMoneyTransactionFilter(other)
110 {
111 Q_D(MyMoneyReport);
112 d->m_movingAverageDays = 0;
113 d->m_currentDateColumn = 0;
114 }
115
~MyMoneyReport()116 MyMoneyReport::~MyMoneyReport()
117 {
118 }
119
addAccountGroupsByRowType(eMyMoney::Report::RowType rt)120 void MyMoneyReport::addAccountGroupsByRowType(eMyMoney::Report::RowType rt)
121 {
122 //add the corresponding account groups
123 switch(rt) {
124 case eMyMoney::Report::RowType::AccountInfo:
125 case eMyMoney::Report::RowType::AssetLiability:
126 addAccountGroup(eMyMoney::Account::Type::Asset);
127 addAccountGroup(eMyMoney::Account::Type::Liability);
128 break;
129
130 case eMyMoney::Report::RowType::Account:
131 addAccountGroup(eMyMoney::Account::Type::Asset);
132 addAccountGroup(eMyMoney::Account::Type::AssetLoan);
133 addAccountGroup(eMyMoney::Account::Type::Cash);
134 addAccountGroup(eMyMoney::Account::Type::Checkings);
135 addAccountGroup(eMyMoney::Account::Type::CreditCard);
136 if (m_expertMode)
137 addAccountGroup(eMyMoney::Account::Type::Equity);
138 addAccountGroup(eMyMoney::Account::Type::Expense);
139 addAccountGroup(eMyMoney::Account::Type::Income);
140 addAccountGroup(eMyMoney::Account::Type::Liability);
141 addAccountGroup(eMyMoney::Account::Type::Loan);
142 addAccountGroup(eMyMoney::Account::Type::Savings);
143 addAccountGroup(eMyMoney::Account::Type::Stock);
144 break;
145
146 case eMyMoney::Report::RowType::ExpenseIncome:
147 addAccountGroup(eMyMoney::Account::Type::Expense);
148 addAccountGroup(eMyMoney::Account::Type::Income);
149 break;
150
151 //FIXME take this out once we have sorted out all issues regarding budget of assets and liabilities -- asoliverez@gmail.com
152 case eMyMoney::Report::RowType::Budget:
153 case eMyMoney::Report::RowType::BudgetActual:
154 addAccountGroup(eMyMoney::Account::Type::Expense);
155 addAccountGroup(eMyMoney::Account::Type::Income);
156 break;
157
158 //cash flow reports show splits for all account groups
159 case eMyMoney::Report::RowType::CashFlow:
160 addAccountGroup(eMyMoney::Account::Type::Expense);
161 addAccountGroup(eMyMoney::Account::Type::Income);
162 addAccountGroup(eMyMoney::Account::Type::Asset);
163 addAccountGroup(eMyMoney::Account::Type::Liability);
164 break;
165 default:
166 break;
167 }
168 }
169
reportType() const170 eMyMoney::Report::ReportType MyMoneyReport::reportType() const
171 {
172 Q_D(const MyMoneyReport);
173 return d->m_reportType;
174 }
175
setReportType(eMyMoney::Report::ReportType rt)176 void MyMoneyReport::setReportType(eMyMoney::Report::ReportType rt)
177 {
178 Q_D(MyMoneyReport);
179 d->m_reportType = rt;
180 }
181
name() const182 QString MyMoneyReport::name() const
183 {
184 Q_D(const MyMoneyReport);
185 return d->m_name;
186 }
187
setName(const QString & s)188 void MyMoneyReport::setName(const QString& s)
189 {
190 Q_D(MyMoneyReport);
191 d->m_name = s;
192 }
193
isShowingRowTotals() const194 bool MyMoneyReport::isShowingRowTotals() const
195 {
196 Q_D(const MyMoneyReport);
197 return (d->m_showRowTotals);
198 }
199
setShowingRowTotals(bool f)200 void MyMoneyReport::setShowingRowTotals(bool f)
201 {
202 Q_D(MyMoneyReport);
203 d->m_showRowTotals = f;
204 }
205
isShowingColumnTotals() const206 bool MyMoneyReport::isShowingColumnTotals() const
207 {
208 Q_D(const MyMoneyReport);
209 return d->m_showColumnTotals;
210 }
211
setShowingColumnTotals(bool f)212 void MyMoneyReport::setShowingColumnTotals(bool f)
213 {
214 Q_D(MyMoneyReport);
215 d->m_showColumnTotals = f;
216 }
217
rowType() const218 eMyMoney::Report::RowType MyMoneyReport::rowType() const
219 {
220 Q_D(const MyMoneyReport);
221 return d->m_rowType;
222 }
223
setRowType(eMyMoney::Report::RowType rt)224 void MyMoneyReport::setRowType(eMyMoney::Report::RowType rt)
225 {
226 Q_D(MyMoneyReport);
227 d->m_rowType = rt;
228 d->m_reportType = d->rowTypeToReportType(rt);
229
230 d->m_accountGroupFilter = false;
231 d->m_accountGroups.clear();
232
233 addAccountGroupsByRowType(rt);
234 }
235
isRunningSum() const236 bool MyMoneyReport::isRunningSum() const
237 {
238 Q_D(const MyMoneyReport);
239 return (d->m_rowType == eMyMoney::Report::RowType::AssetLiability);
240 }
241
columnType() const242 eMyMoney::Report::ColumnType MyMoneyReport::columnType() const
243 {
244 Q_D(const MyMoneyReport);
245 return d->m_columnType;
246 }
247
setColumnType(eMyMoney::Report::ColumnType ct)248 void MyMoneyReport::setColumnType(eMyMoney::Report::ColumnType ct)
249 {
250 Q_D(MyMoneyReport);
251 d->m_columnType = ct;
252 }
253
isConvertCurrency() const254 bool MyMoneyReport::isConvertCurrency() const
255 {
256 Q_D(const MyMoneyReport);
257 return d->m_convertCurrency;
258 }
259
setConvertCurrency(bool f)260 void MyMoneyReport::setConvertCurrency(bool f)
261 {
262 Q_D(MyMoneyReport);
263 d->m_convertCurrency = f;
264 }
265
columnPitch() const266 uint MyMoneyReport::columnPitch() const
267 {
268 Q_D(const MyMoneyReport);
269 return static_cast<uint>(d->m_columnType);
270 }
271
comment() const272 QString MyMoneyReport::comment() const
273 {
274 Q_D(const MyMoneyReport);
275 return d->m_comment;
276 }
277
setComment(const QString & comment)278 void MyMoneyReport::setComment(const QString& comment)
279 {
280 Q_D(MyMoneyReport);
281 d->m_comment = comment;
282 }
283
queryColumns() const284 eMyMoney::Report::QueryColumn MyMoneyReport::queryColumns() const
285 {
286 Q_D(const MyMoneyReport);
287 return d->m_queryColumns;
288 }
289
setQueryColumns(eMyMoney::Report::QueryColumn qc)290 void MyMoneyReport::setQueryColumns(eMyMoney::Report::QueryColumn qc)
291 {
292 Q_D(MyMoneyReport);
293 d->m_queryColumns = qc;
294 }
295
group() const296 QString MyMoneyReport::group() const
297 {
298 Q_D(const MyMoneyReport);
299 return d->m_group;
300 }
301
setGroup(const QString & group)302 void MyMoneyReport::setGroup(const QString& group)
303 {
304 Q_D(MyMoneyReport);
305 d->m_group = group;
306 }
307
isFavorite() const308 bool MyMoneyReport::isFavorite() const
309 {
310 Q_D(const MyMoneyReport);
311 return d->m_favorite;
312 }
313
setFavorite(bool f)314 void MyMoneyReport::setFavorite(bool f)
315 {
316 Q_D(MyMoneyReport);
317 d->m_favorite = f;
318 }
319
isTax() const320 bool MyMoneyReport::isTax() const
321 {
322 Q_D(const MyMoneyReport);
323 return d->m_tax;
324 }
325
setTax(bool f)326 void MyMoneyReport::setTax(bool f)
327 {
328 Q_D(MyMoneyReport);
329 d->m_tax = f;
330 }
331
isInvestmentsOnly() const332 bool MyMoneyReport::isInvestmentsOnly() const
333 {
334 Q_D(const MyMoneyReport);
335 return d->m_investments;
336 }
337
setInvestmentsOnly(bool f)338 void MyMoneyReport::setInvestmentsOnly(bool f)
339 {
340 Q_D(MyMoneyReport);
341 d->m_investments = f; if (f) d->m_loans = false;
342 }
343
isLoansOnly() const344 bool MyMoneyReport::isLoansOnly() const
345 {
346 Q_D(const MyMoneyReport);
347 return d->m_loans;
348 }
349
setLoansOnly(bool f)350 void MyMoneyReport::setLoansOnly(bool f)
351 {
352 Q_D(MyMoneyReport);
353 d->m_loans = f; if (f) d->m_investments = false;
354 }
355
detailLevel() const356 eMyMoney::Report::DetailLevel MyMoneyReport::detailLevel() const
357 {
358 Q_D(const MyMoneyReport);
359 return d->m_detailLevel;
360 }
361
setDetailLevel(eMyMoney::Report::DetailLevel detail)362 void MyMoneyReport::setDetailLevel(eMyMoney::Report::DetailLevel detail)
363 {
364 Q_D(MyMoneyReport);
365 d->m_detailLevel = detail;
366 }
367
investmentSum() const368 eMyMoney::Report::InvestmentSum MyMoneyReport::investmentSum() const
369 {
370 Q_D(const MyMoneyReport);
371 return d->m_investmentSum;
372 }
373
setInvestmentSum(eMyMoney::Report::InvestmentSum sum)374 void MyMoneyReport::setInvestmentSum(eMyMoney::Report::InvestmentSum sum)
375 {
376 Q_D(MyMoneyReport);
377 d->m_investmentSum = sum;
378 }
379
isHideTransactions() const380 bool MyMoneyReport::isHideTransactions() const
381 {
382 Q_D(const MyMoneyReport);
383 return d->m_hideTransactions;
384 }
385
setHideTransactions(bool f)386 void MyMoneyReport::setHideTransactions(bool f)
387 {
388 Q_D(MyMoneyReport);
389 d->m_hideTransactions = f;
390 }
391
chartType() const392 eMyMoney::Report::ChartType MyMoneyReport::chartType() const
393 {
394 Q_D(const MyMoneyReport);
395 return d->m_chartType;
396 }
397
setChartType(eMyMoney::Report::ChartType type)398 void MyMoneyReport::setChartType(eMyMoney::Report::ChartType type)
399 {
400 Q_D(MyMoneyReport);
401 d->m_chartType = type;
402 }
403
chartPalette() const404 eMyMoney::Report::ChartPalette MyMoneyReport::chartPalette() const
405 {
406 Q_D(const MyMoneyReport);
407 return d->m_chartPalette;
408 }
409
setChartPalette(eMyMoney::Report::ChartPalette type)410 void MyMoneyReport::setChartPalette(eMyMoney::Report::ChartPalette type)
411 {
412 Q_D(MyMoneyReport);
413 d->m_chartPalette = type;
414 }
415
isChartDataLabels() const416 bool MyMoneyReport::isChartDataLabels() const
417 {
418 Q_D(const MyMoneyReport);
419 return d->m_chartDataLabels;
420 }
421
setChartDataLabels(bool f)422 void MyMoneyReport::setChartDataLabels(bool f)
423 {
424 Q_D(MyMoneyReport);
425 d->m_chartDataLabels = f;
426 }
427
isChartCHGridLines() const428 bool MyMoneyReport::isChartCHGridLines() const
429 {
430 Q_D(const MyMoneyReport);
431 return d->m_chartCHGridLines;
432 }
433
setChartCHGridLines(bool f)434 void MyMoneyReport::setChartCHGridLines(bool f)
435 {
436 Q_D(MyMoneyReport);
437 d->m_chartCHGridLines = f;
438 }
439
isChartSVGridLines() const440 bool MyMoneyReport::isChartSVGridLines() const
441 {
442 Q_D(const MyMoneyReport);
443 return d->m_chartSVGridLines;
444 }
445
setChartSVGridLines(bool f)446 void MyMoneyReport::setChartSVGridLines(bool f)
447 {
448 Q_D(MyMoneyReport);
449 d->m_chartSVGridLines = f;
450 }
451
isChartByDefault() const452 bool MyMoneyReport::isChartByDefault() const
453 {
454 Q_D(const MyMoneyReport);
455 return d->m_chartByDefault;
456 }
457
setChartByDefault(bool f)458 void MyMoneyReport::setChartByDefault(bool f)
459 {
460 Q_D(MyMoneyReport);
461 d->m_chartByDefault = f;
462 }
463
chartLineWidth() const464 uint MyMoneyReport::chartLineWidth() const
465 {
466 Q_D(const MyMoneyReport);
467 return d->m_chartLineWidth;
468 }
469
setChartLineWidth(uint f)470 void MyMoneyReport::setChartLineWidth(uint f)
471 {
472 Q_D(MyMoneyReport);
473 d->m_chartLineWidth = f;
474 }
475
isLogYAxis() const476 bool MyMoneyReport::isLogYAxis() const
477 {
478 Q_D(const MyMoneyReport);
479 return d->m_logYaxis;
480 }
481
setLogYAxis(bool f)482 void MyMoneyReport::setLogYAxis(bool f)
483 {
484 Q_D(MyMoneyReport);
485 d->m_logYaxis = f;
486 }
487
isNegExpenses() const488 bool MyMoneyReport::isNegExpenses() const
489 {
490 Q_D(const MyMoneyReport);
491 return d->m_negExpenses;
492 }
493
setNegExpenses(bool f)494 void MyMoneyReport::setNegExpenses(bool f)
495 {
496 Q_D(MyMoneyReport);
497 d->m_negExpenses = f;
498 }
499
dataRangeStart() const500 QString MyMoneyReport::dataRangeStart() const
501 {
502 Q_D(const MyMoneyReport);
503 return d->m_dataRangeStart;
504 }
505
setDataRangeStart(const QString & f)506 void MyMoneyReport::setDataRangeStart(const QString& f)
507 {
508 Q_D(MyMoneyReport);
509 d->m_dataRangeStart = f;
510 }
511
dataRangeEnd() const512 QString MyMoneyReport::dataRangeEnd() const
513 {
514 Q_D(const MyMoneyReport);
515 return d->m_dataRangeEnd;
516 }
517
setDataRangeEnd(const QString & f)518 void MyMoneyReport::setDataRangeEnd(const QString& f)
519 {
520 Q_D(MyMoneyReport);
521 d->m_dataRangeEnd = f;
522 }
523
dataMajorTick() const524 QString MyMoneyReport::dataMajorTick() const
525 {
526 Q_D(const MyMoneyReport);
527 return d->m_dataMajorTick;
528 }
529
setDataMajorTick(const QString & f)530 void MyMoneyReport::setDataMajorTick(const QString& f)
531 {
532 Q_D(MyMoneyReport);
533 d->m_dataMajorTick = f;
534 }
535
dataMinorTick() const536 QString MyMoneyReport::dataMinorTick() const
537 {
538 Q_D(const MyMoneyReport);
539 return d->m_dataMinorTick;
540 }
541
setDataMinorTick(const QString & f)542 void MyMoneyReport::setDataMinorTick(const QString& f)
543 {
544 Q_D(MyMoneyReport);
545 d->m_dataMinorTick = f;
546 }
547
yLabelsPrecision() const548 uint MyMoneyReport::yLabelsPrecision() const
549 {
550 Q_D(const MyMoneyReport);
551 return d->m_yLabelsPrecision;
552 }
553
setYLabelsPrecision(int f)554 void MyMoneyReport::setYLabelsPrecision(int f)
555 {
556 Q_D(MyMoneyReport);
557 d->m_yLabelsPrecision = f;
558 }
559
isIncludingSchedules() const560 bool MyMoneyReport::isIncludingSchedules() const
561 {
562 Q_D(const MyMoneyReport);
563 return d->m_includeSchedules;
564 }
565
setIncludingSchedules(bool f)566 void MyMoneyReport::setIncludingSchedules(bool f)
567 {
568 Q_D(MyMoneyReport);
569 d->m_includeSchedules = f;
570 }
571
isColumnsAreDays() const572 bool MyMoneyReport::isColumnsAreDays() const
573 {
574 Q_D(const MyMoneyReport);
575 return d->m_columnsAreDays;
576 }
577
setColumnsAreDays(bool f)578 void MyMoneyReport::setColumnsAreDays(bool f)
579 {
580 Q_D(MyMoneyReport);
581 d->m_columnsAreDays = f;
582 }
583
isIncludingTransfers() const584 bool MyMoneyReport::isIncludingTransfers() const
585 {
586 Q_D(const MyMoneyReport);
587 return d->m_includeTransfers;
588 }
589
setIncludingTransfers(bool f)590 void MyMoneyReport::setIncludingTransfers(bool f)
591 {
592 Q_D(MyMoneyReport);
593 d->m_includeTransfers = f;
594 }
595
isIncludingUnusedAccounts() const596 bool MyMoneyReport::isIncludingUnusedAccounts() const
597 {
598 Q_D(const MyMoneyReport);
599 return d->m_includeUnusedAccounts;
600 }
601
setIncludingUnusedAccounts(bool f)602 void MyMoneyReport::setIncludingUnusedAccounts(bool f)
603 {
604 Q_D(MyMoneyReport);
605 d->m_includeUnusedAccounts = f;
606 }
607
hasBudget() const608 bool MyMoneyReport::hasBudget() const
609 {
610 Q_D(const MyMoneyReport);
611 return !d->m_budgetId.isEmpty();
612 }
613
budget() const614 QString MyMoneyReport::budget() const
615 {
616 Q_D(const MyMoneyReport);
617 return d->m_budgetId;
618 }
619
620 /**
621 * Sets the budget used for this report
622 *
623 * @param budget The ID of the budget to use, or an empty string
624 * to indicate a budget is NOT included
625 * @param fa Whether to display actual data alongside the budget.
626 * Setting to false means the report displays ONLY the budget itself.
627 * @warning For now, the budget ID is ignored. The budget id is
628 * simply checked for any non-empty string, and if so, hasBudget()
629 * will return true.
630 */
setBudget(const QString & budget,bool fa)631 void MyMoneyReport::setBudget(const QString& budget, bool fa)
632 {
633 Q_D(MyMoneyReport);
634 d->m_budgetId = budget; d->m_includeBudgetActuals = fa;
635 }
636
isIncludingBudgetActuals() const637 bool MyMoneyReport::isIncludingBudgetActuals() const
638 {
639 Q_D(const MyMoneyReport);
640 return d->m_includeBudgetActuals;
641 }
642
setIncludingBudgetActuals(bool f)643 void MyMoneyReport::setIncludingBudgetActuals(bool f)
644 {
645 Q_D(MyMoneyReport);
646 d->m_includeBudgetActuals = f;
647 }
648
isIncludingForecast() const649 bool MyMoneyReport::isIncludingForecast() const
650 {
651 Q_D(const MyMoneyReport);
652 return d->m_includeForecast;
653 }
654
setIncludingForecast(bool f)655 void MyMoneyReport::setIncludingForecast(bool f)
656 {
657 Q_D(MyMoneyReport);
658 d->m_includeForecast = f;
659 }
660
isIncludingMovingAverage() const661 bool MyMoneyReport::isIncludingMovingAverage() const
662 {
663 Q_D(const MyMoneyReport);
664 return d->m_includeMovingAverage;
665 }
666
setIncludingMovingAverage(bool f)667 void MyMoneyReport::setIncludingMovingAverage(bool f)
668 {
669 Q_D(MyMoneyReport);
670 d->m_includeMovingAverage = f;
671 }
672
movingAverageDays() const673 int MyMoneyReport::movingAverageDays() const
674 {
675 Q_D(const MyMoneyReport);
676 return d->m_movingAverageDays;
677 }
678
setMovingAverageDays(int days)679 void MyMoneyReport::setMovingAverageDays(int days)
680 {
681 Q_D(MyMoneyReport);
682 d->m_movingAverageDays = days;
683 }
684
isIncludingPrice() const685 bool MyMoneyReport::isIncludingPrice() const
686 {
687 Q_D(const MyMoneyReport);
688 return d->m_includePrice;
689 }
690
setIncludingPrice(bool f)691 void MyMoneyReport::setIncludingPrice(bool f)
692 {
693 Q_D(MyMoneyReport);
694 d->m_includePrice = f;
695 }
696
isIncludingAveragePrice() const697 bool MyMoneyReport::isIncludingAveragePrice() const
698 {
699 Q_D(const MyMoneyReport);
700 return d->m_includeAveragePrice;
701 }
702
setIncludingAveragePrice(bool f)703 void MyMoneyReport::setIncludingAveragePrice(bool f)
704 {
705 Q_D(MyMoneyReport);
706 d->m_includeAveragePrice = f;
707 }
708
dataFilter() const709 eMyMoney::Report::DataLock MyMoneyReport::dataFilter() const
710 {
711 Q_D(const MyMoneyReport);
712 return d->m_dataLock;
713 }
714
isDataUserDefined() const715 bool MyMoneyReport::isDataUserDefined() const
716 {
717 Q_D(const MyMoneyReport);
718 return d->m_dataLock == eMyMoney::Report::DataLock::UserDefined;
719 }
720
setDataFilter(eMyMoney::Report::DataLock u)721 void MyMoneyReport::setDataFilter(eMyMoney::Report::DataLock u)
722 {
723 Q_D(MyMoneyReport);
724 d->m_dataLock = u;
725 }
726
dateRange() const727 eMyMoney::TransactionFilter::Date MyMoneyReport::dateRange() const
728 {
729 Q_D(const MyMoneyReport);
730 return d->m_dateLock;
731 }
732
isDateUserDefined() const733 bool MyMoneyReport::isDateUserDefined() const
734 {
735 Q_D(const MyMoneyReport);
736 return d->m_dateLock == eMyMoney::TransactionFilter::Date::UserDefined;
737 }
738
739 /**
740 * Set the underlying date filter and LOCK that filter to the specified
741 * range. For example, if @p _u is "CurrentMonth", this report should always
742 * be updated to the current month no matter when the report is run.
743 *
744 * This updating is not entirely automatic, you should update it yourself by
745 * calling updateDateFilter.
746 *
747 * @param _u The date range constant (MyMoneyTransactionFilter::dateRangeE)
748 * which this report should be locked to.
749 */
750
setDateFilter(eMyMoney::TransactionFilter::Date u)751 void MyMoneyReport::setDateFilter(eMyMoney::TransactionFilter::Date u)
752 {
753 Q_D(MyMoneyReport);
754 d->m_dateLock = u;
755 if (u != eMyMoney::TransactionFilter::Date::UserDefined)
756 MyMoneyTransactionFilter::setDateFilter(u);
757 }
758
setDateFilter(const QDate & db,const QDate & de)759 void MyMoneyReport::setDateFilter(const QDate& db, const QDate& de)
760 {
761 MyMoneyTransactionFilter::setDateFilter(db, de);
762 }
763
updateDateFilter()764 void MyMoneyReport::updateDateFilter()
765 {
766 Q_D(MyMoneyReport);
767 if (d->m_dateLock != eMyMoney::TransactionFilter::Date::UserDefined) MyMoneyTransactionFilter::setDateFilter(d->m_dateLock);
768 }
769
770
isMixedTime() const771 bool MyMoneyReport::isMixedTime() const
772 {
773 Q_D(const MyMoneyReport);
774 return d->m_mixedTime;
775 }
776
setMixedTime(bool f)777 void MyMoneyReport::setMixedTime(bool f)
778 {
779 Q_D(MyMoneyReport);
780 d->m_mixedTime = f;
781 }
782
currentDateColumn() const783 int MyMoneyReport::currentDateColumn() const
784 {
785 Q_D(const MyMoneyReport);
786 return d->m_currentDateColumn;
787 }
788
setCurrentDateColumn(int f)789 void MyMoneyReport::setCurrentDateColumn(int f)
790 {
791 Q_D(MyMoneyReport);
792 d->m_currentDateColumn = f;
793 }
794
settlementPeriod() const795 uint MyMoneyReport::settlementPeriod() const
796 {
797 Q_D(const MyMoneyReport);
798 return d->m_settlementPeriod;
799 }
800
setSettlementPeriod(uint days)801 void MyMoneyReport::setSettlementPeriod(uint days)
802 {
803 Q_D(MyMoneyReport);
804 d->m_settlementPeriod = days;
805 }
806
isShowingSTLTCapitalGains() const807 bool MyMoneyReport::isShowingSTLTCapitalGains() const
808 {
809 Q_D(const MyMoneyReport);
810 return d->m_showSTLTCapitalGains;
811 }
812
setShowSTLTCapitalGains(bool f)813 void MyMoneyReport::setShowSTLTCapitalGains(bool f)
814 {
815 Q_D(MyMoneyReport);
816 d->m_showSTLTCapitalGains = f;
817 }
818
termSeparator() const819 QDate MyMoneyReport::termSeparator() const
820 {
821 Q_D(const MyMoneyReport);
822 return d->m_tseparator;
823 }
824
setTermSeparator(const QDate & date)825 void MyMoneyReport::setTermSeparator(const QDate& date)
826 {
827 Q_D(MyMoneyReport);
828 d->m_tseparator = date;
829 }
830
isSkippingZero() const831 bool MyMoneyReport::isSkippingZero() const
832 {
833 Q_D(const MyMoneyReport);
834 return d->m_skipZero;
835 }
836
setSkipZero(int f)837 void MyMoneyReport::setSkipZero(int f)
838 {
839 Q_D(MyMoneyReport);
840 d->m_skipZero = f;
841 }
842
clearTransactionFilter()843 void MyMoneyReport::clearTransactionFilter()
844 {
845 Q_D(MyMoneyReport);
846 d->m_accountGroupFilter = false;
847 d->m_accountGroups.clear();
848
849 MyMoneyTransactionFilter::clear();
850 }
851
assignFilter(const MyMoneyTransactionFilter & filter)852 void MyMoneyReport::assignFilter(const MyMoneyTransactionFilter& filter)
853 {
854 MyMoneyTransactionFilter::operator=(filter);
855 }
856
validDateRange(QDate & db,QDate & de)857 void MyMoneyReport::validDateRange(QDate& db, QDate& de)
858 {
859 db = fromDate();
860 de = toDate();
861
862 // if either begin or end date are invalid we have one of the following
863 // possible date filters:
864 //
865 // a) begin date not set - first transaction until given end date
866 // b) end date not set - from given date until last transaction
867 // c) both not set - first transaction until last transaction
868 //
869 // If there is no transaction in the engine at all, we use the current
870 // year as the filter criteria.
871
872 if (!db.isValid() || !de.isValid()) {
873 QList<MyMoneyTransaction> list = MyMoneyFile::instance()->transactionList(*this);
874 QDate tmpBegin, tmpEnd;
875
876 if (!list.isEmpty()) {
877 qSort(list);
878 // try to use the post dates
879 tmpBegin = list.front().postDate();
880 tmpEnd = list.back().postDate();
881 // if the post dates are not valid try the entry dates
882 if (!tmpBegin.isValid())
883 tmpBegin = list.front().entryDate();
884 if (!tmpEnd.isValid())
885 tmpEnd = list.back().entryDate();
886 }
887 // make sure that we leave this function with valid dates no mather what
888 if (!tmpBegin.isValid() || !tmpEnd.isValid() || tmpBegin > tmpEnd) {
889 tmpBegin = QDate(QDate::currentDate().year(), 1, 1); // the first date in the file
890 tmpEnd = QDate(QDate::currentDate().year(), 12, 31); // the last date in the file
891 }
892 if (!db.isValid())
893 db = tmpBegin;
894 if (!de.isValid())
895 de = tmpEnd;
896 }
897 if (db > de)
898 db = de;
899 }
900
accountGroups(QList<eMyMoney::Account::Type> & list) const901 bool MyMoneyReport::accountGroups(QList<eMyMoney::Account::Type>& list) const
902 {
903 Q_D(const MyMoneyReport);
904 bool result = d->m_accountGroupFilter;
905
906 if (result) {
907 QList<eMyMoney::Account::Type>::const_iterator it_group = d->m_accountGroups.begin();
908 while (it_group != d->m_accountGroups.end()) {
909 list += (*it_group);
910 ++it_group;
911 }
912 }
913 return result;
914 }
915
addAccountGroup(eMyMoney::Account::Type type)916 void MyMoneyReport::addAccountGroup(eMyMoney::Account::Type type)
917 {
918 Q_D(MyMoneyReport);
919 if (!d->m_accountGroups.isEmpty() && type != eMyMoney::Account::Type::Unknown) {
920 if (d->m_accountGroups.contains(type))
921 return;
922 }
923 d->m_accountGroupFilter = true;
924 if (type != eMyMoney::Account::Type::Unknown)
925 d->m_accountGroups.push_back(type);
926 }
927
includesAccountGroup(eMyMoney::Account::Type type) const928 bool MyMoneyReport::includesAccountGroup(eMyMoney::Account::Type type) const
929 {
930 Q_D(const MyMoneyReport);
931 bool result = (! d->m_accountGroupFilter)
932 || (isIncludingTransfers() && d->m_rowType == eMyMoney::Report::RowType::ExpenseIncome)
933 || d->m_accountGroups.contains(type);
934
935 return result;
936 }
937
includes(const MyMoneyAccount & acc) const938 bool MyMoneyReport::includes(const MyMoneyAccount& acc) const
939 {
940 Q_D(const MyMoneyReport);
941 auto result = false;
942
943 if (includesAccountGroup(acc.accountGroup())) {
944 switch (acc.accountGroup()) {
945 case eMyMoney::Account::Type::Income:
946 case eMyMoney::Account::Type::Expense:
947 if (isTax())
948 result = (acc.value("Tax") == "Yes") && includesCategory(acc.id());
949 else
950 result = includesCategory(acc.id());
951 break;
952 case eMyMoney::Account::Type::Asset:
953 case eMyMoney::Account::Type::Liability:
954 if (isLoansOnly())
955 result = acc.isLoan() && includesAccount(acc.id());
956 else if (isInvestmentsOnly())
957 result = acc.isInvest() && includesAccount(acc.id());
958 else if (isIncludingTransfers() && d->m_rowType == eMyMoney::Report::RowType::ExpenseIncome)
959 // If transfers are included, ONLY include this account if it is NOT
960 // included in the report itself!!
961 result = ! includesAccount(acc.id());
962 else
963 result = includesAccount(acc.id());
964 break;
965 case eMyMoney::Account::Type::Equity:
966 if (isInvestmentsOnly())
967 result = (isIncludingPrice() || isIncludingAveragePrice()) && acc.isInvest() && includesAccount(acc.id());
968 break;
969 default:
970 result = includesAccount(acc.id());
971 }
972 }
973 return result;
974 }
975
hasReferenceTo(const QString & id) const976 bool MyMoneyReport::hasReferenceTo(const QString& id) const
977 {
978 QStringList list;
979
980 // collect all ids
981 accounts(list);
982 categories(list);
983 payees(list);
984 tags(list);
985
986 return list.contains(id);
987 }
988
989 int MyMoneyReport::m_lineWidth = 2;
990 bool MyMoneyReport::m_expertMode = false;
991
setLineWidth(int width)992 void MyMoneyReport::setLineWidth(int width)
993 {
994 m_lineWidth = width;
995 }
996
lineWidth()997 int MyMoneyReport::lineWidth()
998 {
999 return m_lineWidth;
1000 }
1001
setExpertMode(bool expertMode)1002 void MyMoneyReport::setExpertMode(bool expertMode)
1003 {
1004 m_expertMode = expertMode;
1005 }
1006
toString(eMyMoney::Report::RowType type)1007 QString MyMoneyReport::toString(eMyMoney::Report::RowType type)
1008 {
1009 switch(type) {
1010 case eMyMoney::Report::RowType::NoRows : return "eMyMoney::Report::RowType::NoRows";
1011 case eMyMoney::Report::RowType::AssetLiability : return "eMyMoney::Report::RowType::AssetLiability";
1012 case eMyMoney::Report::RowType::ExpenseIncome : return "eMyMoney::Report::RowType::ExpenseIncome";
1013 case eMyMoney::Report::RowType::Category : return "eMyMoney::Report::RowType::Category";
1014 case eMyMoney::Report::RowType::TopCategory : return "eTopCategory";
1015 case eMyMoney::Report::RowType::Account : return "eAccount";
1016 case eMyMoney::Report::RowType::Tag : return "eTag";
1017 case eMyMoney::Report::RowType::Payee : return "ePayee";
1018 case eMyMoney::Report::RowType::Month : return "eMonth";
1019 case eMyMoney::Report::RowType::Week : return "eWeek";
1020 case eMyMoney::Report::RowType::TopAccount : return "eTopAccount";
1021 case eMyMoney::Report::RowType::AccountByTopAccount: return "eAccountByTopAccount";
1022 case eMyMoney::Report::RowType::EquityType : return "eEquityType";
1023 case eMyMoney::Report::RowType::AccountType : return "eAccountType";
1024 case eMyMoney::Report::RowType::Institution : return "eInstitution";
1025 case eMyMoney::Report::RowType::Budget : return "eBudget";
1026 case eMyMoney::Report::RowType::BudgetActual : return "eBudgetActual";
1027 case eMyMoney::Report::RowType::Schedule : return "eSchedule";
1028 case eMyMoney::Report::RowType::AccountInfo : return "eAccountInfo";
1029 case eMyMoney::Report::RowType::AccountLoanInfo : return "eAccountLoanInfo";
1030 case eMyMoney::Report::RowType::AccountReconcile : return "eAccountReconcile";
1031 case eMyMoney::Report::RowType::CashFlow : return "eCashFlow";
1032 default : return "undefined";
1033 }
1034 }
1035
toString(eMyMoney::Report::ReportType type)1036 QString MyMoneyReport::toString(eMyMoney::Report::ReportType type)
1037 {
1038 switch(type) {
1039 case eMyMoney::Report::ReportType::NoReport: return "eNoReport";
1040 case eMyMoney::Report::ReportType::PivotTable: return "ePivotTable";
1041 case eMyMoney::Report::ReportType::QueryTable: return "eQueryTable";
1042 case eMyMoney::Report::ReportType::InfoTable: return "eInfoTable";
1043 default: return "undefined";
1044 }
1045 }
1046